Date: Mon, 6 Jul 1998 11:42:19 +1000 From: Bruce Evans <bde@zeta.org.au> To: julian@whistle.com, wollman@khavrinen.lcs.mit.edu Cc: current@FreeBSD.ORG Subject: Re: small locking patch for discussion Message-ID: <199807060142.LAA00552@godzilla.zeta.org.au>
next in thread | raw e-mail | index | archive | help
>here's the patch
>Index: ufs/ufs/ufs_quota.c
This seems to be more or less correct, but incomplete.
>===================================================================
>RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_quota.c,v
>retrieving revision 1.23
>diff -c -r1.23 ufs_quota.c
>*** ufs_quota.c 1998/06/21 14:53:40 1.23
>--- ufs_quota.c 1998/07/04 20:39:16
>***************
>*** 465,478 ****
> /*
> * Search vnodes associated with this mount point,
> * deleting any references to quota file being closed.
> */
> again:
> for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nextvp) {
> nextvp = vp->v_mntvnodes.le_next;
> if (vp->v_type == VNON)
> continue;
>! if (vget(vp, LK_EXCLUSIVE, p))
> goto again;
> ip = VTOI(vp);
> dq = ip->i_dquot[type];
> ip->i_dquot[type] = NODQUOT;
>--- 465,489 ----
> /*
> * Search vnodes associated with this mount point,
> * deleting any references to quota file being closed.
>+ *
>+ * This is nearly identical to code in VFSOP_RELOAD, and
>+ * *must* be maintained in parallel!
> */
This comment is an obfuscation. All mnt_vnodelist traversals should
look much like this. Apart from the traversal, the code doesn't look
much like ffs_reload(). VFSOP_RELOAD doesn't exist. Every traversal
shouldn't be commented on.
> again:
>+ simple_lock(&mntvnode_slock);
> for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nextvp) {
>+ if (vp->v_mount != mp) {
>+ simple_unlock(&mntvnode_slock);
>+ goto again;
>+ }
> nextvp = vp->v_mntvnodes.le_next;
> if (vp->v_type == VNON)
> continue;
>! simple_lock(&vp->v_interlock);
>! simple_unlock(&mntvnode_slock);
>! if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p)) {
> goto again;
>+ }
Style bugs: excess braces.
> ip = VTOI(vp);
> dq = ip->i_dquot[type];
> ip->i_dquot[type] = NODQUOT;
>***************
>*** 480,485 ****
>--- 491,497 ----
> vput(vp);
> if (vp->v_mntvnodes.le_next != nextvp || vp->v_mount != mp)
> goto again;
>+ simple_lock(&mntvnode_slock);
The check before locking is now bogus. It isn't valid to check
(vp->v_mntvnodes.le_next != nextvp) before locking. This is harmless
because the only effect of a wrong check is to "goto again" unnecessarily.
The new consistency check on vp (= the newvp here) at the start of the
loop handles all problems. Most other mnt_vnodelist traversals (but
not the one in qsync()) don't bother checking vp here.
> }
> dqflush(qvp); qvp->v_flag &= ~VSYSTEM;
>#########-------
The above is for quotaoff(). quotaon() is also missing locking.
Bruce
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199807060142.LAA00552>
