git: ab17854f974b - main - nfsclient: access v_mount only after the vnode is locked
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 27 Sep 2022 20:01:15 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=ab17854f974b5671b09139079d98e2068802064b
commit ab17854f974b5671b09139079d98e2068802064b
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2022-09-26 18:10:47 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-09-27 20:00:51 +0000
nfsclient: access v_mount only after the vnode is locked
and we checked that it is not reclaimed.
Reviewed by: markj, rmacklem
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D36722
---
sys/fs/nfsclient/nfs_clvnops.c | 34 +++++++++++++++++++++++-----------
1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index 4c6a3b527049..f013b13b0cbe 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -3894,19 +3894,13 @@ nfs_copy_file_range(struct vop_copy_file_range_args *ap)
off_t inoff, outoff;
bool consecutive, must_commit, tryoutcred;
- ret = ret2 = 0;
- nmp = VFSTONFS(invp->v_mount);
- mtx_lock(&nmp->nm_mtx);
/* NFSv4.2 Copy is not permitted for infile == outfile. */
- if (!NFSHASNFSV4(nmp) || nmp->nm_minorvers < NFSV42_MINORVERSION ||
- (nmp->nm_privflag & NFSMNTP_NOCOPY) != 0 || invp == outvp) {
- mtx_unlock(&nmp->nm_mtx);
- error = vn_generic_copy_file_range(ap->a_invp, ap->a_inoffp,
- ap->a_outvp, ap->a_outoffp, ap->a_lenp, ap->a_flags,
- ap->a_incred, ap->a_outcred, ap->a_fsizetd);
- return (error);
+ if (invp == outvp) {
+generic_copy:
+ return (vn_generic_copy_file_range(invp, ap->a_inoffp,
+ outvp, ap->a_outoffp, ap->a_lenp, ap->a_flags,
+ ap->a_incred, ap->a_outcred, ap->a_fsizetd));
}
- mtx_unlock(&nmp->nm_mtx);
/* Lock both vnodes, avoiding risk of deadlock. */
do {
@@ -3933,6 +3927,23 @@ nfs_copy_file_range(struct vop_copy_file_range_args *ap)
if (error != 0)
return (error);
+ /*
+ * More reasons to avoid nfs copy: not NFSv4.2, or explicitly
+ * disabled.
+ */
+ nmp = VFSTONFS(invp->v_mount);
+ mtx_lock(&nmp->nm_mtx);
+ if (!NFSHASNFSV4(nmp) || nmp->nm_minorvers < NFSV42_MINORVERSION ||
+ (nmp->nm_privflag & NFSMNTP_NOCOPY) != 0) {
+ mtx_unlock(&nmp->nm_mtx);
+ VOP_UNLOCK(invp);
+ VOP_UNLOCK(outvp);
+ if (mp != NULL)
+ vn_finished_write(mp);
+ goto generic_copy;
+ }
+ mtx_unlock(&nmp->nm_mtx);
+
/*
* Do the vn_rlimit_fsize() check. Should this be above the VOP layer?
*/
@@ -3959,6 +3970,7 @@ nfs_copy_file_range(struct vop_copy_file_range_args *ap)
error = ncl_flush(outvp, MNT_WAIT, curthread, 1, 0);
/* Do the actual NFSv4.2 RPC. */
+ ret = ret2 = 0;
len = *ap->a_lenp;
mtx_lock(&nmp->nm_mtx);
if ((nmp->nm_privflag & NFSMNTP_NOCONSECUTIVE) == 0)