From owner-svn-src-all@FreeBSD.ORG Fri Feb 1 18:06:07 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 2ECC5FEB; Fri, 1 Feb 2013 18:06:07 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 02C8D6F4; Fri, 1 Feb 2013 18:06:07 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r11I660k010437; Fri, 1 Feb 2013 18:06:06 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r11I66aP010436; Fri, 1 Feb 2013 18:06:06 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201302011806.r11I66aP010436@svn.freebsd.org> From: Konstantin Belousov Date: Fri, 1 Feb 2013 18:06:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r246217 - head/sys/fs/msdosfs X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 01 Feb 2013 18:06:07 -0000 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))