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.
|
* Copyright 2000 Marshall Kirk McKusick. All Rights Reserved.
|
||||||
@ -38,7 +38,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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)
|
#if defined(_KERNEL_OPT)
|
||||||
#include "opt_ffs.h"
|
#include "opt_ffs.h"
|
||||||
@ -516,7 +516,6 @@ loop:
|
|||||||
}
|
}
|
||||||
mutex_exit(&si->si_lock);
|
mutex_exit(&si->si_lock);
|
||||||
vn_lock(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY);
|
vn_lock(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY);
|
||||||
transferlockers(&vp->v_lock, vp->v_vnlock);
|
|
||||||
lockmgr(&vp->v_lock, LK_RELEASE, NULL);
|
lockmgr(&vp->v_lock, LK_RELEASE, NULL);
|
||||||
/*
|
/*
|
||||||
* If this is the first snapshot on this filesystem, then we need
|
* 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;
|
vp->v_vnlock = &si->si_vnlock;
|
||||||
}
|
}
|
||||||
vn_lock(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY);
|
vn_lock(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY);
|
||||||
transferlockers(&vp->v_lock, vp->v_vnlock);
|
|
||||||
lockmgr(&vp->v_lock, LK_RELEASE, NULL);
|
lockmgr(&vp->v_lock, LK_RELEASE, NULL);
|
||||||
/*
|
/*
|
||||||
* Link it onto the active snapshot list.
|
* 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
|
* Copyright (c) 1982, 1986, 1989, 1993
|
||||||
@ -32,7 +32,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
@ -740,6 +740,9 @@ ffs_lock(void *v)
|
|||||||
} */ *ap = v;
|
} */ *ap = v;
|
||||||
struct vnode *vp = ap->a_vp;
|
struct vnode *vp = ap->a_vp;
|
||||||
struct mount *mp = vp->v_mount;
|
struct mount *mp = vp->v_mount;
|
||||||
|
struct lock *lkp;
|
||||||
|
int flags = ap->a_flags;
|
||||||
|
int result;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fake lock during file system suspension.
|
* Fake lock during file system suspension.
|
||||||
@ -747,11 +750,34 @@ ffs_lock(void *v)
|
|||||||
if ((vp->v_type == VREG || vp->v_type == VDIR) &&
|
if ((vp->v_type == VREG || vp->v_type == VDIR) &&
|
||||||
fstrans_is_owner(mp) &&
|
fstrans_is_owner(mp) &&
|
||||||
fstrans_getstate(mp) == FSTRANS_SUSPENDING) {
|
fstrans_getstate(mp) == FSTRANS_SUSPENDING) {
|
||||||
if ((ap->a_flags & LK_INTERLOCK) != 0)
|
if ((flags & LK_INTERLOCK) != 0)
|
||||||
simple_unlock(&vp->v_interlock);
|
simple_unlock(&vp->v_interlock);
|
||||||
return 0;
|
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