For snapshots we need all VOP_LOCKs to be exclusive.
The "business class upgrade" was implemented in UFS's VOP_LOCK implementation ufs_lock() which is the wrong layer, so move it to ffs_lock(). Also, as long as we have not abandonned advanced vfs-stacking we should not preclude it from happening: instead of implementing a copy locally, use the VOP_LOCK_APV(&ufs) to correctly arrive at vop_stdlock() at the bottom.
This commit is contained in:
parent
32a870da8a
commit
d6f622cc2f
@ -97,11 +97,13 @@ __FBSDID("$FreeBSD$");
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <ufs/ffs/ffs_extern.h>
|
||||
#include "opt_directio.h"
|
||||
#include "opt_ffs.h"
|
||||
|
||||
#ifdef DIRECTIO
|
||||
extern int ffs_rawread(struct vnode *vp, struct uio *uio, int *workdone);
|
||||
#endif
|
||||
static vop_fsync_t ffs_fsync;
|
||||
static vop_lock_t ffs_lock;
|
||||
static vop_getpages_t ffs_getpages;
|
||||
static vop_read_t ffs_read;
|
||||
static vop_write_t ffs_write;
|
||||
@ -122,6 +124,7 @@ struct vop_vector ffs_vnodeops = {
|
||||
.vop_default = &ufs_vnodeops,
|
||||
.vop_fsync = ffs_fsync,
|
||||
.vop_getpages = ffs_getpages,
|
||||
.vop_lock = ffs_lock,
|
||||
.vop_read = ffs_read,
|
||||
.vop_reallocblks = ffs_reallocblks,
|
||||
.vop_write = ffs_write,
|
||||
@ -136,6 +139,7 @@ struct vop_vector ffs_vnodeops = {
|
||||
struct vop_vector ffs_fifoops = {
|
||||
.vop_default = &ufs_fifoops,
|
||||
.vop_fsync = ffs_fsync,
|
||||
.vop_lock = ffs_lock,
|
||||
.vop_reallocblks = ffs_reallocblks,
|
||||
.vop_strategy = ffsext_strategy,
|
||||
.vop_closeextattr = ffs_closeextattr,
|
||||
@ -302,6 +306,26 @@ loop:
|
||||
return (UFS_UPDATE(vp, wait));
|
||||
}
|
||||
|
||||
/*
|
||||
* Snapshots require all lock requests to be exclusive.
|
||||
*/
|
||||
static int
|
||||
ffs_lock(ap)
|
||||
struct vop_lock_args /* {
|
||||
struct vnode *a_vp;
|
||||
int a_flags;
|
||||
struct thread *a_td;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
|
||||
if ((VTOI(vp)->i_flags & SF_SNAPSHOT) &&
|
||||
((ap->a_flags & LK_TYPE_MASK) == LK_SHARED)) {
|
||||
ap->a_flags &= ~LK_TYPE_MASK;
|
||||
ap->a_flags |= LK_EXCLUSIVE;
|
||||
}
|
||||
return (VOP_LOCK_APV(&ufs_vnodeops, ap));
|
||||
}
|
||||
|
||||
/*
|
||||
* Vnode op for reading.
|
||||
|
@ -97,7 +97,6 @@ static vop_mkdir_t ufs_mkdir;
|
||||
static vop_mknod_t ufs_mknod;
|
||||
static vop_open_t ufs_open;
|
||||
static vop_pathconf_t ufs_pathconf;
|
||||
static vop_lock_t ufs_lock;
|
||||
static vop_print_t ufs_print;
|
||||
static vop_readlink_t ufs_readlink;
|
||||
static vop_remove_t ufs_remove;
|
||||
@ -1949,33 +1948,6 @@ ufs_strategy(ap)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Snapshots require all lock requests to be exclusive.
|
||||
*/
|
||||
static int
|
||||
ufs_lock(ap)
|
||||
struct vop_lock_args /* {
|
||||
struct vnode *a_vp;
|
||||
int a_flags;
|
||||
struct thread *a_td;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
int flags = ap->a_flags;
|
||||
|
||||
if ((VTOI(vp)->i_flags & SF_SNAPSHOT) &&
|
||||
((flags & LK_TYPE_MASK) == LK_SHARED)) {
|
||||
flags &= ~LK_TYPE_MASK;
|
||||
flags |= LK_EXCLUSIVE;
|
||||
}
|
||||
#ifndef DEBUG_LOCKS
|
||||
return (lockmgr(vp->v_vnlock, flags, VI_MTX(vp), ap->a_td));
|
||||
#else
|
||||
return (debuglockmgr(vp->v_vnlock, flags, VI_MTX(vp),
|
||||
ap->a_td, "vop_stdlock", vp->filename, vp->line));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out the contents of an inode.
|
||||
*/
|
||||
@ -2525,7 +2497,6 @@ struct vop_vector ufs_vnodeops = {
|
||||
.vop_write = VOP_PANIC,
|
||||
.vop_access = ufs_access,
|
||||
.vop_advlock = ufs_advlock,
|
||||
.vop_lock = ufs_lock,
|
||||
.vop_bmap = ufs_bmap,
|
||||
.vop_cachedlookup = ufs_lookup,
|
||||
.vop_close = ufs_close,
|
||||
|
Loading…
x
Reference in New Issue
Block a user