FreeBSD QandA 817
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 まで
お知らせください。