Author: kib
Date: Fri Feb  8 11:15:57 2013
New Revision: 246548
URL: http://svnweb.freebsd.org/changeset/base/246548

Log:
  MFC r246217:
  Fix the corruption of the ".." entry for the directory moved to a
  subdirectory of the root on FAT32.

Modified:
  stable/8/sys/fs/msdosfs/msdosfs_vnops.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/fs/   (props changed)

Modified: stable/8/sys/fs/msdosfs/msdosfs_vnops.c
==============================================================================
--- stable/8/sys/fs/msdosfs/msdosfs_vnops.c     Fri Feb  8 11:14:23 2013        
(r246547)
+++ stable/8/sys/fs/msdosfs/msdosfs_vnops.c     Fri Feb  8 11:15:57 2013        
(r246548)
@@ -974,7 +974,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;
@@ -1247,9 +1247,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 (fvp->v_mount->mnt_flag & MNT_ASYNC)
                        bdwrite(bp);
                else if ((error = bwrite(bp)) != 0) {
@@ -1370,8 +1373,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);
@@ -1381,7 +1389,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 (ap->a_dvp->v_mount->mnt_flag & MNT_ASYNC)
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to