Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 15 Oct 2016 17:43:56 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-bugs@FreeBSD.org
Subject:   [Bug 213507] [msdosfs] [patch]: Prevent occasional directory corruption while extending it to another cluster
Message-ID:  <bug-213507-8@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D213507

            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.movchan@gmail.com
          Keywords: patch

Created attachment 175786
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=3D175786&action=
=3Dedit
This patch fixes the problem for me

When amount of directory entries grows directory could reach size when it
require one more cluster.=20

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 consi=
sts
of garbage-like data which after completion of "grow to one more cluster" m=
ight
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 noticeabl=
e 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=3D512 SecPerClust=3D64 ResSectors=3D32 FATs=3D2 Media=3D0xf0 Se=
cPerTrack=3D63
Heads=3D16 HiddenSecs=3D0 HugeSectors=3D315649016 FATsecs=3D38522 RootClust=
er=3D2
FSInfo=3D1 Backup=3D2
# 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: .=D0=B3J(: No such file or directory
ls: .=D0=B3M(: No such file or directory
ls: .=D0=B3P(: No such file or directory
ls: .=D0=B3S(: No such file or directory
ls: .=D0=B3V(: No such file or directory
ls: .=D0=B3Y(: No such file or directory
ls: .=D0=90?.: Invalid argument
ls: .=D0=90B(: No such file or directory
ls: 0?.?????: Invalid argument
ls: 0t,?????.=D0=9F=D0=9C+: 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 f=
or
directory case) I'm no longer able to reproduce this problem. Patch attache=
d.


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=
=20
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
=3D>        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)

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-213507-8>