- Move pubflag and lockflag handling from nfsrv_fhtovp() to nfs_namei() -
this is the only place that is different from all the other nfsrv_fhtovp() consumers. This simplifies nfsrv_fhtovp() a bit and also eliminates one vn_lock/VOP_UNLOCK() cycle in case of NFSv3. - Implement NFSRV_FLAG_BUSY flag for nfsrv_fhtovp() that tells it to leave mount point busy. Reviewed by: kib MFC after: 5 days
This commit is contained in:
parent
f2f1ef00be
commit
7ef95239a9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=216632
@ -239,6 +239,12 @@ extern int nfs_debug;
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following flags can be passed to nfsrv_fhtovp() function.
|
||||
*/
|
||||
/* Leave file system busy on success. */
|
||||
#define NFSRV_FLAG_BUSY 0x01
|
||||
|
||||
struct mbuf *nfs_rephead(int, struct nfsrv_descript *, int, struct mbuf **,
|
||||
caddr_t *);
|
||||
void nfsm_srvfattr(struct nfsrv_descript *, struct vattr *,
|
||||
@ -264,7 +270,7 @@ int nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf **mrq);
|
||||
int nfsrv_fhtovp(fhandle_t *, int, struct vnode **, int *,
|
||||
struct nfsrv_descript *, struct nfssvc_sock *, struct sockaddr *,
|
||||
int *, int);
|
||||
int *);
|
||||
int nfsrv_setpublicfs(struct mount *, struct netexport *,
|
||||
struct export_args *);
|
||||
int nfs_ispublicfh(fhandle_t *);
|
||||
|
@ -213,8 +213,7 @@ nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
fhp = &nfh.fh_generic;
|
||||
nfsm_srvmtofh(fhp);
|
||||
tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
|
||||
error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
|
||||
nam, &rdonly, TRUE);
|
||||
error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
|
||||
if (error) {
|
||||
nfsm_reply(NFSX_UNSIGNED);
|
||||
nfsm_srvpostop_attr(1, NULL);
|
||||
@ -280,8 +279,7 @@ nfsrv_getattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
vfslocked = 0;
|
||||
fhp = &nfh.fh_generic;
|
||||
nfsm_srvmtofh(fhp);
|
||||
error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp, nam,
|
||||
&rdonly, TRUE);
|
||||
error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
|
||||
if (error) {
|
||||
nfsm_reply(0);
|
||||
error = 0;
|
||||
@ -389,8 +387,7 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
/*
|
||||
* Now that we have all the fields, lets do it.
|
||||
*/
|
||||
error = nfsrv_fhtovp(fhp, 1, &vp, &tvfslocked, nfsd, slp,
|
||||
nam, &rdonly, TRUE);
|
||||
error = nfsrv_fhtovp(fhp, 0, &vp, &tvfslocked, nfsd, slp, nam, &rdonly);
|
||||
vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
|
||||
if (error) {
|
||||
nfsm_reply(2 * NFSX_UNSIGNED);
|
||||
@ -712,8 +709,7 @@ nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
uiop->uio_rw = UIO_READ;
|
||||
uiop->uio_segflg = UIO_SYSSPACE;
|
||||
uiop->uio_td = NULL;
|
||||
error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
|
||||
nam, &rdonly, TRUE);
|
||||
error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
|
||||
if (error) {
|
||||
nfsm_reply(2 * NFSX_UNSIGNED);
|
||||
if (v3)
|
||||
@ -808,8 +804,7 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
* as well.
|
||||
*/
|
||||
|
||||
error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
|
||||
nam, &rdonly, TRUE);
|
||||
error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
|
||||
if (error) {
|
||||
vp = NULL;
|
||||
nfsm_reply(2 * NFSX_UNSIGNED);
|
||||
@ -1109,8 +1104,7 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
error = 0;
|
||||
goto nfsmout;
|
||||
}
|
||||
error = nfsrv_fhtovp(fhp, 1, &vp, &tvfslocked, nfsd, slp,
|
||||
nam, &rdonly, TRUE);
|
||||
error = nfsrv_fhtovp(fhp, 0, &vp, &tvfslocked, nfsd, slp, nam, &rdonly);
|
||||
vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
|
||||
if (error) {
|
||||
vp = NULL;
|
||||
@ -2102,8 +2096,7 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
nfsm_srvmtofh(dfhp);
|
||||
nfsm_srvnamesiz(len);
|
||||
|
||||
error = nfsrv_fhtovp(fhp, TRUE, &vp, &tvfslocked, nfsd, slp,
|
||||
nam, &rdonly, TRUE);
|
||||
error = nfsrv_fhtovp(fhp, 0, &vp, &tvfslocked, nfsd, slp, nam, &rdonly);
|
||||
vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
|
||||
if (error) {
|
||||
nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
|
||||
@ -2770,8 +2763,7 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
if (siz > xfer)
|
||||
siz = xfer;
|
||||
fullsiz = siz;
|
||||
error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
|
||||
nam, &rdonly, TRUE);
|
||||
error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
|
||||
if (!error && vp->v_type != VDIR) {
|
||||
error = ENOTDIR;
|
||||
vput(vp);
|
||||
@ -3066,7 +3058,7 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
if (siz > xfer)
|
||||
siz = xfer;
|
||||
fullsiz = siz;
|
||||
error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
|
||||
error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp,
|
||||
nam, &rdonly, TRUE);
|
||||
vp_locked = 1;
|
||||
if (!error && vp->v_type != VDIR) {
|
||||
@ -3375,6 +3367,8 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
nfsmout:
|
||||
if (vp)
|
||||
vrele(vp);
|
||||
if (mntp)
|
||||
vfs_unbusy(mntp);
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
return(error);
|
||||
}
|
||||
@ -3426,8 +3420,7 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
off = fxdr_hyper(tl);
|
||||
tl += 2;
|
||||
cnt = fxdr_unsigned(int, *tl);
|
||||
error = nfsrv_fhtovp(fhp, 1, &vp, &tvfslocked, nfsd, slp,
|
||||
nam, &rdonly, TRUE);
|
||||
error = nfsrv_fhtovp(fhp, 0, &vp, &tvfslocked, nfsd, slp, nam, &rdonly);
|
||||
vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
|
||||
if (error) {
|
||||
nfsm_reply(2 * NFSX_UNSIGNED);
|
||||
@ -3571,8 +3564,7 @@ nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
vfslocked = 0;
|
||||
fhp = &nfh.fh_generic;
|
||||
nfsm_srvmtofh(fhp);
|
||||
error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
|
||||
nam, &rdonly, TRUE);
|
||||
error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
|
||||
if (error) {
|
||||
nfsm_reply(NFSX_UNSIGNED);
|
||||
if (v3)
|
||||
@ -3666,8 +3658,7 @@ nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
fhp = &nfh.fh_generic;
|
||||
vfslocked = 0;
|
||||
nfsm_srvmtofh(fhp);
|
||||
error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
|
||||
nam, &rdonly, TRUE);
|
||||
error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
|
||||
if (error) {
|
||||
nfsm_reply(NFSX_UNSIGNED);
|
||||
nfsm_srvpostop_attr(getret, &at);
|
||||
@ -3741,8 +3732,7 @@ nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
vfslocked = 0;
|
||||
fhp = &nfh.fh_generic;
|
||||
nfsm_srvmtofh(fhp);
|
||||
error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
|
||||
nam, &rdonly, TRUE);
|
||||
error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
|
||||
if (error) {
|
||||
nfsm_reply(NFSX_UNSIGNED);
|
||||
nfsm_srvpostop_attr(getret, &at);
|
||||
|
@ -639,16 +639,18 @@ nfs_namei(struct nameidata *ndp, struct nfsrv_descript *nfsd,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!pubflag && nfs_ispublicfh(fhp))
|
||||
return (ESTALE);
|
||||
|
||||
/*
|
||||
* Extract and set starting directory.
|
||||
*/
|
||||
error = nfsrv_fhtovp(fhp, FALSE, &dp, &dvfslocked,
|
||||
nfsd, slp, nam, &rdonly, pubflag);
|
||||
error = nfsrv_fhtovp(fhp, 0, &dp, &dvfslocked, nfsd, slp, nam, &rdonly);
|
||||
if (error)
|
||||
goto out;
|
||||
vfslocked = VFS_LOCK_GIANT(dp->v_mount);
|
||||
if (dp->v_type != VDIR) {
|
||||
vrele(dp);
|
||||
vput(dp);
|
||||
error = ENOTDIR;
|
||||
goto out;
|
||||
}
|
||||
@ -662,12 +664,12 @@ nfs_namei(struct nameidata *ndp, struct nfsrv_descript *nfsd,
|
||||
*/
|
||||
*retdirp = dp;
|
||||
if (v3) {
|
||||
vn_lock(dp, LK_EXCLUSIVE | LK_RETRY);
|
||||
*retdirattr_retp = VOP_GETATTR(dp, retdirattrp,
|
||||
ndp->ni_cnd.cn_cred);
|
||||
VOP_UNLOCK(dp, 0);
|
||||
}
|
||||
|
||||
VOP_UNLOCK(dp, 0);
|
||||
|
||||
if (pubflag) {
|
||||
/*
|
||||
* Oh joy. For WebNFS, handle those pesky '%' escapes,
|
||||
@ -1051,12 +1053,11 @@ nfsm_srvfattr(struct nfsrv_descript *nfsd, struct vattr *vap,
|
||||
* - look up fsid in mount list (if not found ret error)
|
||||
* - get vp and export rights by calling VFS_FHTOVP()
|
||||
* - if cred->cr_uid == 0 or MNT_EXPORTANON set it to credanon
|
||||
* - if not lockflag unlock it with VOP_UNLOCK()
|
||||
*/
|
||||
int
|
||||
nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, int *vfslockedp,
|
||||
nfsrv_fhtovp(fhandle_t *fhp, int flags, struct vnode **vpp, int *vfslockedp,
|
||||
struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct sockaddr *nam, int *rdonlyp, int pubflag)
|
||||
struct sockaddr *nam, int *rdonlyp)
|
||||
{
|
||||
struct mount *mp;
|
||||
int i;
|
||||
@ -1076,7 +1077,7 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, int *vfslockedp,
|
||||
*vpp = NULL;
|
||||
|
||||
if (nfs_ispublicfh(fhp)) {
|
||||
if (!pubflag || !nfs_pub.np_valid)
|
||||
if (!nfs_pub.np_valid)
|
||||
return (ESTALE);
|
||||
fhp = &nfs_pub.np_handle;
|
||||
}
|
||||
@ -1128,12 +1129,12 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, int *vfslockedp,
|
||||
}
|
||||
}
|
||||
error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp);
|
||||
if (error != 0)
|
||||
if (error) {
|
||||
/* Make sure the server replies ESTALE to the client. */
|
||||
error = ESTALE;
|
||||
vfs_unbusy(mp);
|
||||
if (error)
|
||||
goto out;
|
||||
}
|
||||
#ifdef MNT_EXNORESPORT
|
||||
if (!(exflags & (MNT_EXNORESPORT|MNT_EXPUBLIC))) {
|
||||
saddr = (struct sockaddr_in *)nam;
|
||||
@ -1162,8 +1163,8 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, int *vfslockedp,
|
||||
else
|
||||
*rdonlyp = 0;
|
||||
|
||||
if (!lockflag)
|
||||
VOP_UNLOCK(*vpp, 0);
|
||||
if (!(flags & NFSRV_FLAG_BUSY))
|
||||
vfs_unbusy(mp);
|
||||
out:
|
||||
if (credanon != NULL)
|
||||
crfree(credanon);
|
||||
|
Loading…
Reference in New Issue
Block a user