FreeBSD QandA 817

FreeBSD QandA

Q. msdosfs としてマウントしてある FAT, VFAT, FAT32 パーティションのマ
   ウント状態をアンマウントせずに変更する (ex: mount -u -r /msdos) と、
   `panic: msdosfs_sync: rofs mod' または `panic: vflush: not busy' と言っ
   て reboot してしまいます。

A. その FreeBSD が FreeBSD 2.2.7-RELEASE または FreeBSD(98) 2.2.7R-Rev01
   であれば msdosfs の不具合です。

   以下のパッチをあてて、カーネルを再構築してください。

   ---------------- BEGIN ----------------
   Index: msdosfs_denode.c
   ===================================================================
   RCS file: /usr/tmp/cvsup/cvs/PAO/sys/msdosfs/msdosfs_denode.c,v
   retrieving revision 1.1.1.2
   diff -u -r1.1.1.2 msdosfs_denode.c
   --- msdosfs_denode.c	1998/07/24 10:22:22	1.1.1.2
   +++ msdosfs_denode.c	1998/10/17 06:07:00
   @@ -55,7 +55,10 @@
    #include <sys/proc.h>
    #include <sys/buf.h>
    #include <sys/vnode.h>
   +
   +#ifndef __FreeBSD_version
    #include <sys/kernel.h>		/* defines "time" */
   +#endif
 
    #include <vm/vm.h>
    #include <vm/vm_extern.h>
   Index: msdosfs_lookup.c
   ===================================================================
   RCS file: /usr/tmp/cvsup/cvs/PAO/sys/msdosfs/msdosfs_lookup.c,v
   retrieving revision 1.1.1.2
   diff -u -r1.1.1.2 msdosfs_lookup.c
   --- msdosfs_lookup.c	1998/07/24 10:22:25	1.1.1.2
   +++ msdosfs_lookup.c	1998/10/17 05:25:25
   @@ -942,9 +942,7 @@
    	int error;
    	daddr_t bn;
    	int blsize;
   -	u_long boff;
 
   -	boff = diroffset & ~pmp->pm_crbomask;
    	blsize = pmp->pm_bpcluster;
    	if (dirclust == MSDOSFSROOT
    	    && de_blk(pmp, diroffset + blsize) > pmp->pm_rootdirsize)
   Index: msdosfs_vfsops.c
   ===================================================================
   RCS file: /usr/tmp/cvsup/cvs/PAO/sys/msdosfs/msdosfs_vfsops.c,v
   retrieving revision 1.1.1.3
   diff -u -r1.1.1.3 msdosfs_vfsops.c
   --- msdosfs_vfsops.c	1998/07/24 10:22:29	1.1.1.3
   +++ msdosfs_vfsops.c	1998/10/17 05:44:47
   @@ -259,7 +259,14 @@
    			flags = WRITECLOSE;
    			if (mp->mnt_flag & MNT_FORCE)
    				flags |= FORCECLOSE;
   +#ifndef __FreeBSD_version
   +			if (vfs_busy(mp))
   +				return EBUSY;
   +#endif
    			error = vflush(mp, NULLVP, flags);
   +#ifndef __FreeBSD_version
   +			vfs_unbusy(mp);
   +#endif
    		}
    		if (!error && (mp->mnt_flag & MNT_RELOAD))
    			/* not yet implemented */
   @@ -269,7 +276,7 @@
    #ifdef __FreeBSD_version
    		if ((pmp->pm_flags & MSDOSFSMNT_RONLY) && (mp->mnt_kern_flag & MNTK_WANTRDWR)) {
    #else
   -		if ((pmp->pm_flags & MSDOSFSMNT_RONLY) && (mp->mnt_flag & MNT_RDONLY) == 0) {
   +		if ((pmp->pm_flags & MSDOSFSMNT_RONLY) && (mp->mnt_flag & MNT_WANTRDWR)) {
    #endif
    			/*
    			 * If upgrade to read-write by non-root, then verify
   @@ -1134,4 +1141,8 @@
    	msdosfs_init
    };
 
   +#ifdef __FreeBSD_version
   +VFS_SET(msdosfs_vfsops, msdos, 0);
   +#else
    VFS_SET(msdosfs_vfsops, msdos, MOUNT_MSDOS, 0);
   +#endif
   Index: msdosfs_vnops.c
   ===================================================================
   RCS file: /usr/tmp/cvsup/cvs/PAO/sys/msdosfs/msdosfs_vnops.c,v
   retrieving revision 1.1.1.2
   diff -u -r1.1.1.2 msdosfs_vnops.c
   --- msdosfs_vnops.c	1998/07/24 10:22:31	1.1.1.2
   +++ msdosfs_vnops.c	1998/10/17 05:50:11
   @@ -1521,7 +1523,9 @@
    #endif
    				goto bad;
    			}
   -			if (ip->de_dirclust != MSDOSFSROOT)
   +			if (ip->de_dirclust == MSDOSFSROOT)
   +				ip->de_diroffset = to_diroffset;
   +			else
    				ip->de_diroffset = to_diroffset & pmp->pm_crbomask;
    		}
    		reinsert(ip);
   @@ -2150,6 +2154,9 @@
    static int
    msdosfs_strategy(ap)
    	struct vop_strategy_args /* {
   +#ifdef __FreeBSD_version
   +		struct vnode *a_vp;
   +#endif
    		struct buf *a_bp;
    	} */ *ap;
    {
   @@ -2187,7 +2194,11 @@
    	 */
    	vp = dep->de_devvp;
    	bp->b_dev = vp->v_rdev;
   +#ifdef __FreeBSD_version
   +	VOP_STRATEGY(vp, bp);
   +#else
    	VOCALL(vp->v_op, VOFFSET(vop_strategy), ap);
   +#endif
    	return (0);
    }
 
   @@ -2200,7 +2211,7 @@
    	struct denode *dep = VTODE(ap->a_vp);
 
    	printf(
   -	    "tag VT_MSDOSFS, startcluster %d, dircluster %ld, diroffset %ld ",
   +	    "tag VT_MSDOSFS, startcluster %lu, dircluster %lu, diroffset %lu ",
    	       dep->de_StartCluster, dep->de_dirclust, dep->de_diroffset);
    	printf(" dev %d, %d", major(dep->de_dev), minor(dep->de_dev));
    #ifdef __FreeBSD_version
   ----------------  END  ----------------

間違い・追加情報を見付けた場合は、 修正案の投稿のしかた を読んだ上で、
QandA@jp.FreeBSD.org まで お知らせください。