svn commit: r246217 - head/sys/fs/msdosfs
Konstantin Belousov
kib at FreeBSD.org
Fri Feb 1 18:06:07 UTC 2013
Author: kib
Date: Fri Feb 1 18:06:06 2013
New Revision: 246217
URL: http://svnweb.freebsd.org/changeset/base/246217
Log:
The directory entry for dotdot was corrupted in the FAT32 case when moving
a directory to a subdir of the root directory from somewhere else.
For all directory moves that change the parent directory, the dotdot
entry must be fixed up. For msdosfs, the root directory is magic for
non-FAT32. It is less magic for FAT32, but needs the same magic for
the dotdot fixup. It didn't have it.
Both chkdsk and fsck_msdosfs fix the corrupt directory entries with no
problems.
The fix is to use the same magic for dotdot in msdosfs_rename() as in
msdosfs_mkdir().
For msdosfs_mkdir(), document the magic. When writing the dotdot entry
in mkdir, use explicitly set pcl variable instead on relying on the
start cluster of the root directory typically has a value < 65536.
Submitted by: bde
MFC after: 1 week
Modified:
head/sys/fs/msdosfs/msdosfs_vnops.c
Modified: head/sys/fs/msdosfs/msdosfs_vnops.c
==============================================================================
--- head/sys/fs/msdosfs/msdosfs_vnops.c Fri Feb 1 18:01:03 2013 (r246216)
+++ head/sys/fs/msdosfs/msdosfs_vnops.c Fri Feb 1 18:06:06 2013 (r246217)
@@ -973,7 +973,7 @@ msdosfs_rename(ap)
u_char to_count;
int doingdirectory = 0, newparent = 0;
int error;
- u_long cn;
+ u_long cn, pcl;
daddr_t bn;
struct denode *fddep; /* from file's parent directory */
struct msdosfsmount *pmp;
@@ -1246,9 +1246,12 @@ abortit:
goto bad;
}
dotdotp = (struct direntry *)bp->b_data + 1;
- putushort(dotdotp->deStartCluster, dp->de_StartCluster);
+ pcl = dp->de_StartCluster;
+ if (FAT32(pmp) && pcl == pmp->pm_rootdirblk)
+ pcl = MSDOSFSROOT;
+ putushort(dotdotp->deStartCluster, pcl);
if (FAT32(pmp))
- putushort(dotdotp->deHighClust, dp->de_StartCluster >> 16);
+ putushort(dotdotp->deHighClust, pcl >> 16);
if (DOINGASYNC(fvp))
bdwrite(bp);
else if ((error = bwrite(bp)) != 0) {
@@ -1369,8 +1372,13 @@ msdosfs_mkdir(ap)
putushort(denp[0].deMDate, ndirent.de_MDate);
putushort(denp[0].deMTime, ndirent.de_MTime);
pcl = pdep->de_StartCluster;
+ /*
+ * Although the root directory has a non-magic starting cluster
+ * number for FAT32, chkdsk and fsck_msdosfs still require
+ * references to it in dotdot entries to be magic.
+ */
if (FAT32(pmp) && pcl == pmp->pm_rootdirblk)
- pcl = 0;
+ pcl = MSDOSFSROOT;
putushort(denp[1].deStartCluster, pcl);
putushort(denp[1].deCDate, ndirent.de_CDate);
putushort(denp[1].deCTime, ndirent.de_CTime);
@@ -1380,7 +1388,7 @@ msdosfs_mkdir(ap)
putushort(denp[1].deMTime, ndirent.de_MTime);
if (FAT32(pmp)) {
putushort(denp[0].deHighClust, newcluster >> 16);
- putushort(denp[1].deHighClust, pdep->de_StartCluster >> 16);
+ putushort(denp[1].deHighClust, pcl >> 16);
}
if (DOINGASYNC(ap->a_dvp))
More information about the svn-src-all
mailing list