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:
Poul-Henning Kamp 2005-02-08 15:54:30 +00:00
parent 32a870da8a
commit d6f622cc2f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=141521
2 changed files with 24 additions and 29 deletions

View File

@ -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 @@ ffs_fsync(ap)
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.

View File

@ -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,