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)