Skip site navigation (1)Skip section navigation (2)
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>