https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=213507
Bug ID: 213507 Summary: [msdosfs] [patch]: Prevent occasional directory corruption while extending it to another cluster Product: Base System Version: CURRENT Hardware: Any OS: Any Status: New Keywords: patch Severity: Affects Some People Priority: --- Component: kern Assignee: freebsd-bugs@FreeBSD.org Reporter: vladislav.movc...@gmail.com Keywords: patch Created attachment 175786 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=175786&action=edit This patch fixes the problem for me When amount of directory entries grows directory could reach size when it require one more cluster. This condition checked at the beginning of createde() inside of msdosfs_lookup.c Actual directory extension occurs by extendfile() inside of msdosfs_fat.c I found that after completion of extendfile() newly allocated cluster consists of garbage-like data which after completion of "grow to one more cluster" might be interpreted as phantom/random directory entries. This bug is sometimes hard to reproduce intentionally as data in newly allocated cluster often looks the same no matter how many times you retry. And if this data consists of mostly zeros it won't produce effect noticeable on the filesystem. Here is an output when I got lucky to trigger this problem (shell is bash): # newfs_msdos -F 32 /dev/gpt/sg1-disk-f /dev/gpt/sg1-disk-f: 315571904 sectors in 4930811 FAT32 clusters (32768 bytes/cluster) BytesPerSec=512 SecPerClust=64 ResSectors=32 FATs=2 Media=0xf0 SecPerTrack=63 Heads=16 HiddenSecs=0 HugeSectors=315649016 FATsecs=38522 RootCluster=2 FSInfo=1 Backup=2 # mount_msdosfs -o large /dev/gpt/sg1-disk-f /mnt/f # mkdir /mnt/f/test # cd /mnt/f/test # for i in `seq 1 150`; do; head -c $((20000*1000+1)) /dev/random > `echo {0..9}{a..k} | tr -d ' '`$i; done # ls -laR /mnt/f/test > /dev/null ls: .гJ(: No such file or directory ls: .гM(: No such file or directory ls: .гP(: No such file or directory ls: .гS(: No such file or directory ls: .гV(: No such file or directory ls: .гY(: No such file or directory ls: .А?.: Invalid argument ls: .АB(: No such file or directory ls: 0?.?????: Invalid argument ls: 0t,?????.ПМ+: Invalid argument ls: 0w,?????.?t,: Invalid argument ls: 0|#?????.0|#: Invalid argument ls: 0|#?????.0|#: Invalid argument ls: 0|#?????.0|#: Invalid argument ... In most cases there is no other way than newfs_msdos to get rid of such "random" directory entries. So don't run this on filesystem you care about. After I tried to intentionally bzero() newly allocated cluster data (only for directory case) I'm no longer able to reproduce this problem. Patch attached. System details: $ uname -a FreeBSD morgenstern 12.0-CURRENT FreeBSD 12.0-CURRENT #0 r306964: Mon Oct 10 18:17:21 EEST 2016 root@morgenstern:/usr/obj/usr/src/sys/Mephistopheles amd64 $ diskinfo -v /dev/gpt/sg1-disk-f /dev/gpt/sg1-disk-f 512 # sectorsize 161612296192 # mediasize in bytes (151G) 315649016 # mediasize in sectors 0 # stripesize 539533312 # stripeoffset 313143 # Cylinders according to firmware. 16 # Heads according to firmware. 63 # Sectors according to firmware. 9WM0NGVRs0 # Disk ident. $ gpart show -l /dev/ada3 => 40 3907026976 ada3 GPT (1.8T) 40 23 - free - (12K) 63 105910497 1 sg1-disk-e (51G) 105910560 14680080 - free - (7.0G) 120590640 1572864000 2 sg1-tank-disk3 (750G) 1693454640 39 - free - (20K) 1693454679 1897923321 4 sg1-disk-i (905G) 3591378000 315649016 5 sg1-disk-f (151G) -- You are receiving this mail because: You are the assignee for the bug. _______________________________________________ freebsd-bugs@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"