From 694a586a43ad15e65a6fe278af031e4ec18a3524 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Sun, 22 May 2011 01:07:54 +0000 Subject: [PATCH] Add a lock flags argument to the VFS_FHTOVP() file system method, so that callers can indicate the minimum vnode locking requirement. This will allow some file systems to choose to return a LK_SHARED locked vnode when LK_SHARED is specified for the flags argument. This patch only adds the flag. It does not change any file system to use it and all callers specify LK_EXCLUSIVE, so file system semantics are not changed. Reviewed by: kib --- .../contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c | 4 ++-- sys/fs/cd9660/cd9660_vfsops.c | 3 ++- sys/fs/ext2fs/ext2_vfsops.c | 2 +- sys/fs/hpfs/hpfs_vfsops.c | 1 + sys/fs/msdosfs/msdosfs_vfsops.c | 2 +- sys/fs/nfsserver/nfs_nfsdport.c | 4 ++-- sys/fs/ntfs/ntfs_vfsops.c | 1 + sys/fs/nullfs/null_vfsops.c | 6 ++++-- sys/fs/tmpfs/tmpfs_vfsops.c | 6 ++++-- sys/fs/udf/udf_vfsops.c | 2 +- sys/fs/unionfs/union_vfsops.c | 3 ++- sys/gnu/fs/reiserfs/reiserfs_vfsops.c | 3 ++- sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c | 3 ++- sys/kern/vfs_default.c | 3 ++- sys/kern/vfs_syscalls.c | 6 +++--- sys/nfsserver/nfs_srvsubs.c | 2 +- sys/nlm/nlm_prot_impl.c | 2 +- sys/sys/mount.h | 7 ++++--- sys/sys/param.h | 2 +- sys/ufs/ffs/ffs_vfsops.c | 5 +++-- sys/ufs/ufs/ufs_extern.h | 2 +- sys/ufs/ufs/ufs_vfsops.c | 3 ++- 22 files changed, 43 insertions(+), 29 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c index e9a956ce4bb4..85e3d44d39a6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c @@ -93,7 +93,7 @@ static int zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp); static int zfs_sync(vfs_t *vfsp, int waitfor); static int zfs_checkexp(vfs_t *vfsp, struct sockaddr *nam, int *extflagsp, struct ucred **credanonp, int *numsecflavors, int **secflavors); -static int zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp); +static int zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, int flags, vnode_t **vpp); static void zfs_objset_close(zfsvfs_t *zfsvfs); static void zfs_freevfs(vfs_t *vfsp); @@ -2007,7 +2007,7 @@ CTASSERT(SHORT_FID_LEN <= sizeof(struct fid)); CTASSERT(LONG_FID_LEN <= sizeof(struct fid)); static int -zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp) +zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, int flags, vnode_t **vpp) { zfsvfs_t *zfsvfs = vfsp->vfs_data; znode_t *zp; diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c index 77757f2c64fc..0ad57ecb785f 100644 --- a/sys/fs/cd9660/cd9660_vfsops.c +++ b/sys/fs/cd9660/cd9660_vfsops.c @@ -586,9 +586,10 @@ cd9660_statfs(mp, sbp) /* ARGSUSED */ static int -cd9660_fhtovp(mp, fhp, vpp) +cd9660_fhtovp(mp, fhp, flags, vpp) struct mount *mp; struct fid *fhp; + int flags; struct vnode **vpp; { struct ifid ifh; diff --git a/sys/fs/ext2fs/ext2_vfsops.c b/sys/fs/ext2fs/ext2_vfsops.c index 5c807dc327d3..1b47e912fec2 100644 --- a/sys/fs/ext2fs/ext2_vfsops.c +++ b/sys/fs/ext2fs/ext2_vfsops.c @@ -973,7 +973,7 @@ ext2_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) * those rights via. exflagsp and credanonp */ static int -ext2_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) +ext2_fhtovp(struct mount *mp, struct fid *fhp, int flags, struct vnode **vpp) { struct inode *ip; struct ufid *ufhp; diff --git a/sys/fs/hpfs/hpfs_vfsops.c b/sys/fs/hpfs/hpfs_vfsops.c index 676b5c711edc..866004eeb549 100644 --- a/sys/fs/hpfs/hpfs_vfsops.c +++ b/sys/fs/hpfs/hpfs_vfsops.c @@ -417,6 +417,7 @@ static int hpfs_fhtovp( struct mount *mp, struct fid *fhp, + int flags, struct vnode **vpp) { struct vnode *nvp; diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c index e04ef9c14e82..e347640bb5dc 100644 --- a/sys/fs/msdosfs/msdosfs_vfsops.c +++ b/sys/fs/msdosfs/msdosfs_vfsops.c @@ -963,7 +963,7 @@ msdosfs_sync(struct mount *mp, int waitfor) } static int -msdosfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) +msdosfs_fhtovp(struct mount *mp, struct fid *fhp, int flags, struct vnode **vpp) { struct msdosfsmount *pmp = VFSTOMSDOSFS(mp); struct defid *defhp = (struct defid *) fhp; diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 11c287f52529..d62be99a1768 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -2551,7 +2551,7 @@ nfsvno_fhtovp(struct mount *mp, fhandle_t *fhp, struct sockaddr *nam, if (VFS_NEEDSGIANT(mp)) error = ESTALE; else - error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp); + error = VFS_FHTOVP(mp, &fhp->fh_fid, LK_EXCLUSIVE, vpp); if (error != 0) /* Make sure the server replies ESTALE to the client. */ error = ESTALE; @@ -2834,7 +2834,7 @@ nfsvno_getvp(fhandle_t *fhp) mp = vfs_busyfs(&fhp->fh_fsid); if (mp == NULL) return (NULL); - error = VFS_FHTOVP(mp, &fhp->fh_fid, &vp); + error = VFS_FHTOVP(mp, &fhp->fh_fid, LK_EXCLUSIVE, &vp); vfs_unbusy(mp); if (error) return (NULL); diff --git a/sys/fs/ntfs/ntfs_vfsops.c b/sys/fs/ntfs/ntfs_vfsops.c index b5e024be9932..d3468af2f022 100644 --- a/sys/fs/ntfs/ntfs_vfsops.c +++ b/sys/fs/ntfs/ntfs_vfsops.c @@ -616,6 +616,7 @@ static int ntfs_fhtovp( struct mount *mp, struct fid *fhp, + int flags, struct vnode **vpp) { struct vnode *nvp; diff --git a/sys/fs/nullfs/null_vfsops.c b/sys/fs/nullfs/null_vfsops.c index 7bd4ab7d2794..e39dd8f892c4 100644 --- a/sys/fs/nullfs/null_vfsops.c +++ b/sys/fs/nullfs/null_vfsops.c @@ -321,13 +321,15 @@ nullfs_vget(mp, ino, flags, vpp) } static int -nullfs_fhtovp(mp, fidp, vpp) +nullfs_fhtovp(mp, fidp, flags, vpp) struct mount *mp; struct fid *fidp; + int flags; struct vnode **vpp; { int error; - error = VFS_FHTOVP(MOUNTTONULLMOUNT(mp)->nullm_vfs, fidp, vpp); + error = VFS_FHTOVP(MOUNTTONULLMOUNT(mp)->nullm_vfs, fidp, LK_EXCLUSIVE, + vpp); if (error) return (error); diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c index 356be5e30815..9d23bd212ffb 100644 --- a/sys/fs/tmpfs/tmpfs_vfsops.c +++ b/sys/fs/tmpfs/tmpfs_vfsops.c @@ -71,7 +71,8 @@ MALLOC_DEFINE(M_TMPFSNAME, "tmpfs name", "tmpfs file names"); static int tmpfs_mount(struct mount *); static int tmpfs_unmount(struct mount *, int); static int tmpfs_root(struct mount *, int flags, struct vnode **); -static int tmpfs_fhtovp(struct mount *, struct fid *, struct vnode **); +static int tmpfs_fhtovp(struct mount *, struct fid *, int, + struct vnode **); static int tmpfs_statfs(struct mount *, struct statfs *); /* --------------------------------------------------------------------- */ @@ -341,7 +342,8 @@ tmpfs_root(struct mount *mp, int flags, struct vnode **vpp) /* --------------------------------------------------------------------- */ static int -tmpfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) +tmpfs_fhtovp(struct mount *mp, struct fid *fhp, int flags, + struct vnode **vpp) { boolean_t found; struct tmpfs_fid *tfhp; diff --git a/sys/fs/udf/udf_vfsops.c b/sys/fs/udf/udf_vfsops.c index 7be538436ce5..bb2c09d31c5b 100644 --- a/sys/fs/udf/udf_vfsops.c +++ b/sys/fs/udf/udf_vfsops.c @@ -722,7 +722,7 @@ udf_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) } static int -udf_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) +udf_fhtovp(struct mount *mp, struct fid *fhp, int flags, struct vnode **vpp) { struct ifid *ifhp; struct vnode *nvp; diff --git a/sys/fs/unionfs/union_vfsops.c b/sys/fs/unionfs/union_vfsops.c index e11219c1d026..96258fb88649 100644 --- a/sys/fs/unionfs/union_vfsops.c +++ b/sys/fs/unionfs/union_vfsops.c @@ -454,7 +454,8 @@ unionfs_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) } static int -unionfs_fhtovp(struct mount *mp, struct fid *fidp, struct vnode **vpp) +unionfs_fhtovp(struct mount *mp, struct fid *fidp, int flags, + struct vnode **vpp) { return (EOPNOTSUPP); } diff --git a/sys/gnu/fs/reiserfs/reiserfs_vfsops.c b/sys/gnu/fs/reiserfs/reiserfs_vfsops.c index 1b5ce88eef9c..9b7ccd94aa7b 100644 --- a/sys/gnu/fs/reiserfs/reiserfs_vfsops.c +++ b/sys/gnu/fs/reiserfs/reiserfs_vfsops.c @@ -335,7 +335,8 @@ reiserfs_statfs(struct mount *mp, struct statfs *sbp) * those rights via. exflagsp and credanonp */ static int -reiserfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) +reiserfs_fhtovp(struct mount *mp, struct fid *fhp, int flags, + struct vnode **vpp) { int error; struct rfid *rfhp; diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c b/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c index f89618e93d02..e9ccfc902761 100644 --- a/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c +++ b/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c @@ -370,9 +370,10 @@ _xfs_vget(mp, ino, flags, vpp) } static int -_xfs_fhtovp(mp, fidp, vpp) +_xfs_fhtovp(mp, fidp, flags, vpp) struct mount *mp; struct fid *fidp; + int flags; struct vnode **vpp; { printf("xfs_fhtovp\n"); diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index e5f1254fd6f2..b89d990ffe7c 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -1081,9 +1081,10 @@ vfs_stdvget (mp, ino, flags, vpp) } int -vfs_stdfhtovp (mp, fhp, vpp) +vfs_stdfhtovp (mp, fhp, flags, vpp) struct mount *mp; struct fid *fhp; + int flags; struct vnode **vpp; { diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 33f7c5b63752..b48c6e796958 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -4405,7 +4405,7 @@ fhopen(td, uap) return (ESTALE); vfslocked = VFS_LOCK_GIANT(mp); /* now give me my vnode, it gets returned to me locked */ - error = VFS_FHTOVP(mp, &fhp.fh_fid, &vp); + error = VFS_FHTOVP(mp, &fhp.fh_fid, LK_EXCLUSIVE, &vp); vfs_unbusy(mp); if (error) goto out; @@ -4581,7 +4581,7 @@ fhstat(td, uap) if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) return (ESTALE); vfslocked = VFS_LOCK_GIANT(mp); - error = VFS_FHTOVP(mp, &fh.fh_fid, &vp); + error = VFS_FHTOVP(mp, &fh.fh_fid, LK_EXCLUSIVE, &vp); vfs_unbusy(mp); if (error) { VFS_UNLOCK_GIANT(vfslocked); @@ -4641,7 +4641,7 @@ kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf) if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) return (ESTALE); vfslocked = VFS_LOCK_GIANT(mp); - error = VFS_FHTOVP(mp, &fh.fh_fid, &vp); + error = VFS_FHTOVP(mp, &fh.fh_fid, LK_EXCLUSIVE, &vp); if (error) { vfs_unbusy(mp); VFS_UNLOCK_GIANT(vfslocked); diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c index 5a923762380f..66a85c4bb8e3 100644 --- a/sys/nfsserver/nfs_srvsubs.c +++ b/sys/nfsserver/nfs_srvsubs.c @@ -1128,7 +1128,7 @@ nfsrv_fhtovp(fhandle_t *fhp, int flags, struct vnode **vpp, int *vfslockedp, goto out; } } - error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp); + error = VFS_FHTOVP(mp, &fhp->fh_fid, LK_EXCLUSIVE, vpp); if (error) { /* Make sure the server replies ESTALE to the client. */ error = ESTALE; diff --git a/sys/nlm/nlm_prot_impl.c b/sys/nlm/nlm_prot_impl.c index 070fdf9ad78a..afbb9ddd809c 100644 --- a/sys/nlm/nlm_prot_impl.c +++ b/sys/nlm/nlm_prot_impl.c @@ -1797,7 +1797,7 @@ nlm_get_vfs_state(struct nlm_host *host, struct svc_req *rqstp, goto out; } - error = VFS_FHTOVP(vs->vs_mp, &fhp->fh_fid, &vs->vs_vp); + error = VFS_FHTOVP(vs->vs_mp, &fhp->fh_fid, LK_EXCLUSIVE, &vs->vs_vp); if (error) goto out; vs->vs_vnlocked = TRUE; diff --git a/sys/sys/mount.h b/sys/sys/mount.h index 231e3d69f0f4..d6366071b91a 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -566,7 +566,8 @@ typedef int vfs_statfs_t(struct mount *mp, struct statfs *sbp); typedef int vfs_sync_t(struct mount *mp, int waitfor); typedef int vfs_vget_t(struct mount *mp, ino_t ino, int flags, struct vnode **vpp); -typedef int vfs_fhtovp_t(struct mount *mp, struct fid *fhp, struct vnode **vpp); +typedef int vfs_fhtovp_t(struct mount *mp, struct fid *fhp, + int flags, struct vnode **vpp); typedef int vfs_checkexp_t(struct mount *mp, struct sockaddr *nam, int *extflagsp, struct ucred **credanonp, int *numsecflavors, int **secflavors); @@ -610,8 +611,8 @@ vfs_statfs_t __vfs_statfs; #define VFS_SYNC(MP, WAIT) (*(MP)->mnt_op->vfs_sync)(MP, WAIT) #define VFS_VGET(MP, INO, FLAGS, VPP) \ (*(MP)->mnt_op->vfs_vget)(MP, INO, FLAGS, VPP) -#define VFS_FHTOVP(MP, FIDP, VPP) \ - (*(MP)->mnt_op->vfs_fhtovp)(MP, FIDP, VPP) +#define VFS_FHTOVP(MP, FIDP, FLAGS, VPP) \ + (*(MP)->mnt_op->vfs_fhtovp)(MP, FIDP, FLAGS, VPP) #define VFS_CHECKEXP(MP, NAM, EXFLG, CRED, NUMSEC, SEC) \ (*(MP)->mnt_op->vfs_checkexp)(MP, NAM, EXFLG, CRED, NUMSEC, SEC) #define VFS_EXTATTRCTL(MP, C, FN, NS, N) \ diff --git a/sys/sys/param.h b/sys/sys/param.h index 7fbcde54fb43..838769fcaba1 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 900037 /* Master, propagated to newvers */ +#define __FreeBSD_version 900038 /* Master, propagated to newvers */ #ifdef _KERNEL #define P_OSREL_SIGSEGV 700004 diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 573c364cc33d..68b961910bdc 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -1640,9 +1640,10 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags) * those rights via. exflagsp and credanonp */ static int -ffs_fhtovp(mp, fhp, vpp) +ffs_fhtovp(mp, fhp, flags, vpp) struct mount *mp; struct fid *fhp; + int flags; struct vnode **vpp; { struct ufid *ufhp; @@ -1653,7 +1654,7 @@ ffs_fhtovp(mp, fhp, vpp) if (ufhp->ufid_ino < ROOTINO || ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg) return (ESTALE); - return (ufs_fhtovp(mp, ufhp, vpp)); + return (ufs_fhtovp(mp, ufhp, flags, vpp)); } /* diff --git a/sys/ufs/ufs/ufs_extern.h b/sys/ufs/ufs/ufs_extern.h index 528b03bc5f28..c590748f7ff0 100644 --- a/sys/ufs/ufs/ufs_extern.h +++ b/sys/ufs/ufs/ufs_extern.h @@ -56,7 +56,7 @@ extern struct vop_vector ufs_vnodeops; int ufs_bmap(struct vop_bmap_args *); int ufs_bmaparray(struct vnode *, ufs2_daddr_t, ufs2_daddr_t *, struct buf *, int *, int *); -int ufs_fhtovp(struct mount *, struct ufid *, struct vnode **); +int ufs_fhtovp(struct mount *, struct ufid *, int, struct vnode **); int ufs_checkpath(ino_t, ino_t, struct inode *, struct ucred *, ino_t *); void ufs_dirbad(struct inode *, doff_t, char *); int ufs_dirbadentry(struct vnode *, struct direct *, int); diff --git a/sys/ufs/ufs/ufs_vfsops.c b/sys/ufs/ufs/ufs_vfsops.c index 0eeb14fc54e8..b71fc169a366 100644 --- a/sys/ufs/ufs/ufs_vfsops.c +++ b/sys/ufs/ufs/ufs_vfsops.c @@ -208,9 +208,10 @@ ufs_uninit(vfsp) * Call the VFS_CHECKEXP beforehand to verify access. */ int -ufs_fhtovp(mp, ufhp, vpp) +ufs_fhtovp(mp, ufhp, flags, vpp) struct mount *mp; struct ufid *ufhp; + int flags; struct vnode **vpp; { struct inode *ip;