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:
parent
473d5fc042
commit
5657bcacb9
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user