aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRick Macklem <rmacklem@FreeBSD.org>2021-04-28 00:30:16 +0000
committerRick Macklem <rmacklem@FreeBSD.org>2021-04-28 00:30:16 +0000
commitf6fec55fe30088bbefd3efe70b62565399a7b9b8 (patch)
tree948f5feaa06f80e6218b0a682677efea9bb6ab29
parentdb8c27f499105dcc9872dcc46e88bdd570c24fee (diff)
downloadsrc-f6fec55fe30088bbefd3efe70b62565399a7b9b8.tar.gz
src-f6fec55fe30088bbefd3efe70b62565399a7b9b8.zip
nfscl: add check for NULL clp and forced dismounts to nfscl_delegreturnvp()
Commit aad780464fad added a function called nfscl_delegreturnvp() to return delegations during the NFS VOP_RECLAIM(). The function erroneously assumed that nm_clp would be non-NULL. It will be NULL for NFSV4.0 mounts until a regular file is opened. It will also be NULL during vflush() in nfs_unmount() for a forced dismount. This patch adds a check for clp == NULL to fix this. Also, since it makes no sense to call nfscl_delegreturnvp() during a forced dismount, the patch adds a check for that case and does not do the call during forced dismounts. PR: 255436 Reported by: ish@amail.plala.or.jp MFC after: 2 weeks
-rw-r--r--sys/fs/nfsclient/nfs_clnode.c9
-rw-r--r--sys/fs/nfsclient/nfs_clstate.c6
2 files changed, 12 insertions, 3 deletions
diff --git a/sys/fs/nfsclient/nfs_clnode.c b/sys/fs/nfsclient/nfs_clnode.c
index 43c2286726f7..1c0e855ff5a9 100644
--- a/sys/fs/nfsclient/nfs_clnode.c
+++ b/sys/fs/nfsclient/nfs_clnode.c
@@ -289,8 +289,10 @@ ncl_reclaim(struct vop_reclaim_args *ap)
struct nfsnode *np = VTONFS(vp);
struct nfsdmap *dp, *dp2;
struct thread *td;
+ struct mount *mp;
td = curthread;
+ mp = vp->v_mount;
/*
* If the NLM is running, give it a chance to abort pending
@@ -317,7 +319,12 @@ ncl_reclaim(struct vop_reclaim_args *ap)
* vfs_hash_remove(), since it cannot be recalled once the
* nfs node is no longer available.
*/
- nfscl_delegreturnvp(vp, td);
+ MNT_ILOCK(mp);
+ if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) == 0) {
+ MNT_IUNLOCK(mp);
+ nfscl_delegreturnvp(vp, td);
+ } else
+ MNT_IUNLOCK(mp);
}
vfs_hash_remove(vp);
diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
index bbc1c6ccbc2f..8b5f07b5aa2a 100644
--- a/sys/fs/nfsclient/nfs_clstate.c
+++ b/sys/fs/nfsclient/nfs_clstate.c
@@ -3300,10 +3300,12 @@ nfscl_delegreturnvp(vnode_t vp, NFSPROC_T *p)
np = VTONFS(vp);
cred = newnfs_getcred();
+ dp = NULL;
NFSLOCKCLSTATE();
clp = VFSTONFS(vp->v_mount)->nm_clp;
- dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh,
- np->n_fhp->nfh_len);
+ if (clp != NULL)
+ dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh,
+ np->n_fhp->nfh_len);
if (dp != NULL) {
nfscl_cleandeleg(dp);
nfscl_freedeleg(&clp->nfsc_deleg, dp, false);