summaryrefslogtreecommitdiffstats
path: root/sys/fs/msdosfs
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2003-06-29 03:05:59 +0000
committertjr <tjr@FreeBSD.org>2003-06-29 03:05:59 +0000
commit8b83d54b5e54fa52b8122a47131e51e275108dff (patch)
treedd1d22a892107f08a185dbf12c0366c002004910 /sys/fs/msdosfs
parentebb4fc782dbaeff91ed4302033b54580f50f3474 (diff)
downloadFreeBSD-src-8b83d54b5e54fa52b8122a47131e51e275108dff.zip
FreeBSD-src-8b83d54b5e54fa52b8122a47131e51e275108dff.tar.gz
XXX Copy workaround from UFS: open device for write access even if
the user requests a read-only mount. This is necessary because we don't do the VOP_OPEN again if they upgrade a read-only mount to read-write. Fixes lockup when creating files on msdosfs mounts that have been mounted read-only then upgraded to read-write. The exact cause of the lockup is not known, but it is likely to be the kernel getting stuck in an infinite loop trying to write dirty buffers to a device without write permission. Reported/tested by andreas, discussed with phk.
Diffstat (limited to 'sys/fs/msdosfs')
-rw-r--r--sys/fs/msdosfs/msdosfs_vfsops.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
index ac092b8..5e5713d 100644
--- a/sys/fs/msdosfs/msdosfs_vfsops.c
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c
@@ -318,7 +318,16 @@ mountmsdosfs(devvp, mp, td, argp)
ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
+ /*
+ * XXX Open the device with write access even if the filesystem
+ * is read-only: someone may remount it read-write later, and
+ * we don't VOP_OPEN the device again in that case.
+ */
+#ifdef notyet
error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, td);
+#else
+ error = VOP_OPEN(devvp, FREAD|FWRITE, FSCRED, td);
+#endif
VOP_UNLOCK(devvp, 0, td);
if (error)
return (error);
@@ -607,7 +616,12 @@ mountmsdosfs(devvp, mp, td, argp)
error_exit:
if (bp)
brelse(bp);
+ /* XXX See comment at VOP_OPEN call */
+#ifdef notyet
(void) VOP_CLOSE(devvp, ronly ? FREAD : FREAD | FWRITE, NOCRED, td);
+#else
+ (void) VOP_CLOSE(devvp, FREAD | FWRITE, NOCRED, td);
+#endif
if (pmp) {
if (pmp->pm_inusemap)
free(pmp->pm_inusemap, M_MSDOSFSFAT);
@@ -662,9 +676,14 @@ msdosfs_unmount(mp, mntflags, td)
VI_UNLOCK(vp);
}
#endif
+ /* XXX See comment at VOP_OPEN call */
+#ifdef notyet
error = VOP_CLOSE(pmp->pm_devvp,
(pmp->pm_flags&MSDOSFSMNT_RONLY) ? FREAD : FREAD | FWRITE,
NOCRED, td);
+#else
+ error = VOP_CLOSE(pmp->pm_devvp, FREAD | FWRITE, NOCRED, td);
+#endif
vrele(pmp->pm_devvp);
free(pmp->pm_inusemap, M_MSDOSFSFAT);
free(pmp, M_MSDOSFSMNT);
OpenPOWER on IntegriCloud