aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2021-01-01 15:35:44 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2021-01-09 01:33:55 +0000
commitf6be8e5155195f5eeac763fa24d6afa2d5417fa0 (patch)
treea4c8f86bcd8598318bb3b7879cc4a0f158f5a56e
parent91006937a3b9535476a9291dbc816ccb2883ccde (diff)
nfs server: improve use of the VFS KPI
(cherry picked from commit 51a9b978e75021415fdced616b4e4bc373a20a8a)
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c33
-rw-r--r--sys/fs/nfsserver/nfs_nfsdsocket.c6
2 files changed, 22 insertions, 17 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index f159e9c89a87..0bb3edbddec9 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -3086,28 +3086,35 @@ nfsd_fhtovp(struct nfsrv_descript *nd, struct nfsrvfh *nfp, int lktype,
struct vnode **vpp, struct nfsexstuff *exp,
struct mount **mpp, int startwrite, struct thread *p)
{
- struct mount *mp;
+ struct mount *mp, *mpw;
struct ucred *credanon;
fhandle_t *fhp;
+ int error;
+ if (mpp != NULL)
+ *mpp = NULL;
+ *vpp = NULL;
fhp = (fhandle_t *)nfp->nfsrvfh_data;
- /*
- * Check for the special case of the nfsv4root_fh.
- */
mp = vfs_busyfs(&fhp->fh_fsid);
- if (mpp != NULL)
- *mpp = mp;
if (mp == NULL) {
- *vpp = NULL;
nd->nd_repstat = ESTALE;
goto out;
}
if (startwrite) {
- vn_start_write(NULL, mpp, V_WAIT);
+ mpw = mp;
+ error = vn_start_write(NULL, &mpw, V_WAIT);
+ if (error != 0) {
+ mpw = NULL;
+ vfs_unbusy(mp);
+ nd->nd_repstat = ESTALE;
+ goto out;
+ }
if (lktype == LK_SHARED && !(MNT_SHARED_WRITES(mp)))
lktype = LK_EXCLUSIVE;
- }
+ } else
+ mpw = NULL;
+
nd->nd_repstat = nfsvno_fhtovp(mp, fhp, nd->nd_nam, lktype, vpp, exp,
&credanon);
vfs_unbusy(mp);
@@ -3119,6 +3126,7 @@ nfsd_fhtovp(struct nfsrv_descript *nd, struct nfsrvfh *nfp, int lktype,
if (!nd->nd_repstat && exp->nes_exflag == 0 &&
!(nd->nd_flag & ND_NFSV4)) {
vput(*vpp);
+ *vpp = NULL;
nd->nd_repstat = EACCES;
}
@@ -3166,11 +3174,10 @@ nfsd_fhtovp(struct nfsrv_descript *nd, struct nfsrvfh *nfp, int lktype,
if (credanon != NULL)
crfree(credanon);
if (nd->nd_repstat) {
- if (startwrite)
- vn_finished_write(mp);
+ vn_finished_write(mpw);
*vpp = NULL;
- if (mpp != NULL)
- *mpp = NULL;
+ } else if (mpp != NULL) {
+ *mpp = mpw;
}
out:
diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c
index 718737ec184c..a678e3acfeab 100644
--- a/sys/fs/nfsserver/nfs_nfsdsocket.c
+++ b/sys/fs/nfsserver/nfs_nfsdsocket.c
@@ -543,8 +543,7 @@ nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram, u_char *tag, int taglen,
nfsrvd_statstart(nfsv3to4op[nd->nd_procnum], /*now*/ NULL);
nfsrvd_statend(nfsv3to4op[nd->nd_procnum], /*bytes*/ 0,
/*now*/ NULL, /*then*/ NULL);
- if (mp != NULL && nfsrv_writerpc[nd->nd_procnum] != 0)
- vn_finished_write(mp);
+ vn_finished_write(mp);
goto out;
}
@@ -574,8 +573,7 @@ nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram, u_char *tag, int taglen,
error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram,
vp, p, &nes);
}
- if (mp != NULL && nfsrv_writerpc[nd->nd_procnum] != 0)
- vn_finished_write(mp);
+ vn_finished_write(mp);
nfsrvd_statend(nfsv3to4op[nd->nd_procnum], /*bytes*/ 0,
/*now*/ NULL, /*then*/ &start_time);