Modify ffs_lock() to take care for changed v_vnlock. Snapshots do not need

transferlockers() anymore.

From FreeBSD ffs_vnops.c Rev. 1.159

Reviewed by: YAMAMOTO Takashi <yamt@netbsd.org>
This commit is contained in:
hannken 2007-08-21 09:27:33 +00:00
parent 473d5fc042
commit 5657bcacb9
2 changed files with 32 additions and 8 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_snapshot.c,v 1.49 2007/08/18 10:11:01 hannken Exp $ */
/* $NetBSD: ffs_snapshot.c,v 1.50 2007/08/21 09:27:33 hannken Exp $ */
/*
* Copyright 2000 Marshall Kirk McKusick. All Rights Reserved.
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.49 2007/08/18 10:11:01 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.50 2007/08/21 09:27:33 hannken Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@ -516,7 +516,6 @@ loop:
}
mutex_exit(&si->si_lock);
vn_lock(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY);
transferlockers(&vp->v_lock, vp->v_vnlock);
lockmgr(&vp->v_lock, LK_RELEASE, NULL);
/*
* If this is the first snapshot on this filesystem, then we need
@ -1815,7 +1814,6 @@ ffs_snapshot_mount(struct mount *mp)
vp->v_vnlock = &si->si_vnlock;
}
vn_lock(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY);
transferlockers(&vp->v_lock, vp->v_vnlock);
lockmgr(&vp->v_lock, LK_RELEASE, NULL);
/*
* Link it onto the active snapshot list.

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_vnops.c,v 1.90 2007/08/09 09:22:34 hannken Exp $ */
/* $NetBSD: ffs_vnops.c,v 1.91 2007/08/21 09:27:33 hannken Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,v 1.90 2007/08/09 09:22:34 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,v 1.91 2007/08/21 09:27:33 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -740,6 +740,9 @@ ffs_lock(void *v)
} */ *ap = v;
struct vnode *vp = ap->a_vp;
struct mount *mp = vp->v_mount;
struct lock *lkp;
int flags = ap->a_flags;
int result;
/*
* Fake lock during file system suspension.
@ -747,11 +750,34 @@ ffs_lock(void *v)
if ((vp->v_type == VREG || vp->v_type == VDIR) &&
fstrans_is_owner(mp) &&
fstrans_getstate(mp) == FSTRANS_SUSPENDING) {
if ((ap->a_flags & LK_INTERLOCK) != 0)
if ((flags & LK_INTERLOCK) != 0)
simple_unlock(&vp->v_interlock);
return 0;
}
return (lockmgr(vp->v_vnlock, ap->a_flags, &vp->v_interlock));
if ((flags & LK_TYPE_MASK) == LK_DRAIN)
return (lockmgr(vp->v_vnlock, flags, &vp->v_interlock));
KASSERT((flags & ~(LK_SHARED | LK_EXCLUSIVE | LK_SLEEPFAIL |
LK_INTERLOCK | LK_NOWAIT | LK_SETRECURSE | LK_CANRECURSE)) == 0);
for (;;) {
if ((flags & LK_INTERLOCK) == 0) {
simple_lock(&vp->v_interlock);
flags |= LK_INTERLOCK;
}
lkp = vp->v_vnlock;
result = lockmgr(lkp, flags, &vp->v_interlock);
if (lkp == vp->v_vnlock || result != 0)
return result;
/*
* Apparent success, except that the vnode mutated between
* snapshot file vnode and regular file vnode while this
* thread slept. The lock currently held is not the right
* lock. Release it, and try to get the new lock.
*/
(void) lockmgr(lkp, LK_RELEASE, NULL);
flags &= ~LK_INTERLOCK;
}
}
/*