From nobody Fri Apr 7 15:50:34 2023 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4PtNB338bjz43Y58; Fri, 7 Apr 2023 15:50:35 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4PtNB25QrPz4K67; Fri, 7 Apr 2023 15:50:34 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1680882634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=PFXXapNeAmLLCJJ7qxyjtfglAmVxpVpzHI1nYkjWevU=; b=KRNl9lC6jwzsnzgb0V4CiDWX5KjWd3A1Ch5RIhvdwk+9bNwZsUpk4dhjabOwxcDOab5vxi XG0fDjvgr7OoQqas4ltJ9rwwuiAVIerRd5lC7KbGu2R62gTavUtmL+7EXnd2FZW44JeIvl zDj2v1kJkrQxH89zsXu5T07CfbLPUZ7B5sfUcFf3Aw1lJwhpeXMiL4CQ91pSS2JhZju4vU RtBSa+O4GBcG3knSUDpYwEq8l32a4TLudxXSBW3ucN/NRrqSrxX2lIn1kuM7UKpCCNklru RCVXbA3RtEy28pgBGv8i660RitTFaIWkHUoJjXLQQY80YZfIutqCdy8sFGTWQA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1680882634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=PFXXapNeAmLLCJJ7qxyjtfglAmVxpVpzHI1nYkjWevU=; b=KfuylyvUpvEsHxuAHT0+iSW03N5ievoBFnlUvNkQJpa1zVjsNI8lc0bePBUL4BAHJzrvmP CqDnaxbzTIHfwyfODu+qtEmrISMfLo1kps94nb/jiB9PhK1wmGMGFkLwwvRGexMjuOmqx4 66QDSYr73HjsFmJzZS6RJqQEFAMiu9XGZXoO4myU2s8zYRJBnHMqPKf+H+hg2mQ/2i7SZL tbW02McDMwxQ9BV6nWFnVPJpfAOv+de2aH+0eNvDjXWT2RNXyUA8hsUltXlOOvE6rxhkgc 67A1yZPPSoPy15SlxBP6xhi0NRikkkixvMbzN3G3QiRQYgjPJHcgE5dutieYkw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1680882634; a=rsa-sha256; cv=none; b=ctrB22KBedrawpk1XSXUy39aUuHrFMBXUdKMOTdO8tKOoNrJiovmY6BZIFHj3w1r9/EEKx XynveKPWZismmeIB8EWv509+qCYUklyCwFxBJdoro8u8AtXVga8ZkwitUsJTLmZkQ/sYMg NuXh2q7bU32rMoHWlc+Q7AJhvjafJdrg53iVUwMB0S9h0A0EzSDqKmVcBj0i0xbDu0+hl+ 8xsRqfexY2lalEL51e5pEc+ndiNFFLSQ6S0E5YxMuf5OeAG2CU3HQub/FzCRfncWd2f63K eKUqkIUgd0rLkDe0buD5PYqPxtdkKE6aQvFgd3GaspiqfvQVoLNlfA4x7/qWxg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4PtNB24XmYzr9L; Fri, 7 Apr 2023 15:50:34 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 337FoYZ7060771; Fri, 7 Apr 2023 15:50:34 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 337FoYj8060770; Fri, 7 Apr 2023 15:50:34 GMT (envelope-from git) Date: Fri, 7 Apr 2023 15:50:34 GMT Message-Id: <202304071550.337FoYj8060770@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mateusz Guzik Subject: git: d012836fb616 - main - zfs: fix up EXDEV handling for clone_range List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mjg X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: d012836fb61654942c9d573c8e0f9def598d4ae2 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by mjg: URL: https://cgit.FreeBSD.org/src/commit/?id=d012836fb61654942c9d573c8e0f9def598d4ae2 commit d012836fb61654942c9d573c8e0f9def598d4ae2 Author: Mateusz Guzik AuthorDate: 2023-04-05 20:27:12 +0000 Commit: Mateusz Guzik CommitDate: 2023-04-07 15:46:20 +0000 zfs: fix up EXDEV handling for clone_range API contract requires VOPs to handle EXDEV internally, worst case by falling back to the generic copy routine. This broke with the recent changes. While here whack custom loop to lock 2 vnodes with vn_lock_pair, which provides the same functionality internally. write start/finish around it plays no role so got eliminated. One difference is that vn_lock_pair always takes an exclusive lock on both vnodes. I did not patch around it because current code takes an exclusive lock on the target vnode. zfs supports shared-locking for writes, so this serializes different calls to the routine as is, despite range locking inside. At the same time you may notice the source vnode can get some traffic if only shared-locked, thus once more this goes the safer route of exclusive-locking. Note this should be patched to use shared-locking for both once the feature is considered stable. Technically the switch to vn_lock_pair should be a separate change, but it would only introduce churn immediately whacked by the rest of the patch. [note: technically the review is still in progress, but so is the active breakage] Sponsored by: Rubicon Communications, LLC ("Netgate") --- .../openzfs/module/os/freebsd/zfs/zfs_vnops_os.c | 56 +++++++++++----------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c index baa2ee5b3824..67c1a6e3344b 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c @@ -6250,56 +6250,54 @@ zfs_freebsd_copy_file_range(struct vop_copy_file_range_args *ap) * need something else than vn_generic_copy_file_range(). */ - /* Lock both vnodes, avoiding risk of deadlock. */ - do { - mp = NULL; - error = vn_start_write(outvp, &mp, V_WAIT); - if (error == 0) { - error = vn_lock(outvp, LK_EXCLUSIVE); - if (error == 0) { - if (invp == outvp) - break; - error = vn_lock(invp, LK_SHARED | LK_NOWAIT); - if (error == 0) - break; - VOP_UNLOCK(outvp); - if (mp != NULL) - vn_finished_write(mp); - mp = NULL; - error = vn_lock(invp, LK_SHARED); - if (error == 0) - VOP_UNLOCK(invp); - } + vn_start_write(outvp, &mp, V_WAIT); + if (invp == outvp) { + if (vn_lock(outvp, LK_EXCLUSIVE) != 0) { + goto bad_write_fallback; } - if (mp != NULL) - vn_finished_write(mp); - } while (error == 0); - if (error != 0) - return (error); + } else { + vn_lock_pair(invp, false, outvp, false); + if (VN_IS_DOOMED(invp) || VN_IS_DOOMED(outvp)) { + goto bad_locked_fallback; + } + } + #ifdef MAC error = mac_vnode_check_write(curthread->td_ucred, ap->a_outcred, outvp); if (error != 0) - goto unlock; + goto out_locked; #endif io.uio_offset = *ap->a_outoffp; io.uio_resid = *ap->a_lenp; error = vn_rlimit_fsize(outvp, &io, ap->a_fsizetd); if (error != 0) - goto unlock; + goto out_locked; error = zfs_clone_range(VTOZ(invp), ap->a_inoffp, VTOZ(outvp), ap->a_outoffp, &len, ap->a_outcred); + if (error == EXDEV) + goto bad_locked_fallback; *ap->a_lenp = (size_t)len; - -unlock: +out_locked: if (invp != outvp) VOP_UNLOCK(invp); VOP_UNLOCK(outvp); if (mp != NULL) vn_finished_write(mp); + return (error); +bad_locked_fallback: + if (invp != outvp) + VOP_UNLOCK(invp); + VOP_UNLOCK(outvp); +bad_write_fallback: + if (mp != NULL) + vn_finished_write(mp); + 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); }