PERFORCE change 125824 for review
Xin LI
delphij at FreeBSD.org
Wed Aug 29 10:08:04 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=125824
Change 125824 by delphij at charlie on 2007/08/29 17:07:39
We can only alter dirty flag while the device is read-write, so
move it before g_access which would set the device as read-only,
causing the write to fail.
Restructure the flow in order to make it more obvious.
Don't use vfs_flagopt() to obfuscate simple flag setting.
Set pmp->pm_fmod appropriately to avoid panics.
Submitted by: bde
Affected files ...
.. //depot/projects/delphij_fork/sys/fs/msdosfs/msdosfs_vfsops.c#8 edit
Differences ...
==== //depot/projects/delphij_fork/sys/fs/msdosfs/msdosfs_vfsops.c#8 (text+ko) ====
@@ -250,8 +250,6 @@
* read/write; if there is no device name, that's all we do.
*/
if (mp->mnt_flag & MNT_UPDATE) {
- int ro_to_rw = 0;
-
pmp = VFSTOMSDOSFS(mp);
if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0)) {
/*
@@ -275,18 +273,38 @@
error = vflush(mp, 0, flags, td);
if (error)
return (error);
+
+ /*
+ * Now the volume is clean. We have to mark it so
+ * when the device is still r/w.
+ */
+ error = markvoldirty(pmp, 0);
+ if (error) {
+ (void)markvoldirty(pmp, 1);
+ return (error);
+ }
+
+ /* Downgrade the device from rw to ro. */
DROP_GIANT();
g_topology_lock();
error = g_access(pmp->pm_cp, 0, -1, 0);
g_topology_unlock();
PICKUP_GIANT();
- if (error)
+ if (error) {
+ (void)markvoldirty(pmp, 1);
return (error);
+ }
+
+ /*
+ * Backing out after an error was painful in the
+ * above. Now we are committed to succeeding.
+ */
+ pmp->pm_fmod = 0;
+ pmp->pm_flags |= MSDOSFSMNT_RONLY;
- /* Now the volume is clean. Mark it. */
- error = markvoldirty(pmp, 0);
- if (error && (flags & FORCECLOSE) == 0)
- return (error);
+ MNT_ILOCK(mp);
+ mp->mnt_flag |= MNT_RDONLY;
+ MNT_IUNLOCK(mp);
} else if ((pmp->pm_flags & MSDOSFSMNT_RONLY) &&
!vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0)) {
/*
@@ -311,20 +329,22 @@
PICKUP_GIANT();
if (error)
return (error);
+ }
+ /*
+ * XXX: pm_fmod is only used to implement a panic
+ * if we forget to set it here.
+ */
+ pmp->pm_fmod = 1;
- ro_to_rw = 1;
- }
- vfs_flagopt(mp->mnt_optnew, "ro",
- &pmp->pm_flags, MSDOSFSMNT_RONLY);
- vfs_flagopt(mp->mnt_optnew, "ro",
- &mp->mnt_flag, MNT_RDONLY);
+ pmp->pm_flags &= ~MSDOSFSMNT_RONLY;
+ MNT_ILOCK(mp);
+ mp->mnt_flag &= ~MNT_RDONLY;
+ MNT_IUNLOCK(mp);
- if (ro_to_rw) {
- /* Now that the volume is modifiable, mark it dirty. */
- error = markvoldirty(pmp, 1);
- if (error)
- return (error);
- }
+ /* Now that the volume is modifiable, mark it dirty. */
+ error = markvoldirty(pmp, 1);
+ if (error)
+ return (error);
}
/*
* Not an update, or updating the name: look up the name
@@ -714,9 +734,10 @@
if (ronly)
pmp->pm_flags |= MSDOSFSMNT_RONLY;
else {
- /* Mark the volume dirty while it is mounted read/write. */
- if ((error = markvoldirty(pmp, 1)) != 0)
+ if ((error = markvoldirty(pmp, 1)) != 0) {
+ (void)markvoldirty(pmp, 0);
goto error_exit;
+ }
pmp->pm_fmod = 1;
}
mp->mnt_data = (qaddr_t) pmp;
More information about the p4-projects
mailing list