From owner-p4-projects@FreeBSD.ORG Wed Aug 29 17:08:04 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id CDC3F16A46B; Wed, 29 Aug 2007 17:08:03 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5CAD016A418 for ; Wed, 29 Aug 2007 17:08:03 +0000 (UTC) (envelope-from delphij@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 4C29713C45A for ; Wed, 29 Aug 2007 17:08:03 +0000 (UTC) (envelope-from delphij@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id l7TH83bp092468 for ; Wed, 29 Aug 2007 17:08:03 GMT (envelope-from delphij@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l7TH83W3092465 for perforce@freebsd.org; Wed, 29 Aug 2007 17:08:03 GMT (envelope-from delphij@freebsd.org) Date: Wed, 29 Aug 2007 17:08:03 GMT Message-Id: <200708291708.l7TH83W3092465@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to delphij@freebsd.org using -f From: Xin LI To: Perforce Change Reviews Cc: Subject: PERFORCE change 125824 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Aug 2007 17:08:04 -0000 http://perforce.freebsd.org/chv.cgi?CH=125824 Change 125824 by delphij@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;