From nobody Fri Jul 4 13:28:56 2025 X-Original-To: dev-commits-src-all@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 4bYZGc4Vdhz615FW; Fri, 04 Jul 2025 13:28:56 +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 "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4bYZGc1Z4zz3M97; Fri, 04 Jul 2025 13:28:56 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1751635736; 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=DB/RCy/qCxJ6+N1k4ZYmbL7KiUq77VbAOQA7lau5b/w=; b=p+Aca+974V5EFPP8OYrV0MRYykpp//TNWs2XAndoHp/EbBMqK7AR5j4PJD+A5q+TYMOZsR 43LIi6b+4JuQD6GII4HDMEViA+qqycJeZLUC5IQHsQVNh/B1Ds043ReoJTMF9nX12s2jTs uVJEv8Ym8FlW4gEcFfx6Ngeoi5bGFcCiqh57oeulUIYBLNFOctOqqg381Sqxz7kXljnCfU qm9kyCA6j/OzfQc/KP98fQYv8gm+mglACqOS6GQ6MbbV1pirfxn8Vo6tkzImwEYxORx6Tf 8HA+WKZ1j5ybLt7i0HbS7LHQsM74nVjdUdTBVKj/419wW6iHDivcV7ZkuUjfCw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1751635736; 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=DB/RCy/qCxJ6+N1k4ZYmbL7KiUq77VbAOQA7lau5b/w=; b=a8N1HjS9M261y0i5CNrAwJKqmw0PQ+yYan1DfiaJdzsmNo/ADtsEX9Y8OteXkBVtCqd8Cm Y3bItruzRxiCES0Ofa6rX/v+2mCXtjWN2wSoW5yQQYPaLzfeUQvd0CZyTdinrpPzb2gl8H UovbWwkRiZ5nD4epXC0RdwRZbjHPvrhbGYttYzm9qKw5Z5fztk4QLN2BwqOoiz/N5F7x3s yMWd77Fu9XTSeQ+wHRLSBei/+SE1WoQ5DdhRS19NQOnJXJY33I7HL/HvbvWrBw7wssmald 8qeitTzocUHoBLlQR+n3NS1YGpeSJPMV6jirbYlF/ZOfAukrazVjNzHh5gRung== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1751635736; a=rsa-sha256; cv=none; b=LgE95v3MNhqnG8FBKOmqHdGtHb1g09alHzAvv9wNaKcN+6qqGZ4kjG/JsHRgplVw4dWi9U UZzLeu8nPX83YPXG/Xr+PdXcCKPu/Z64dXWMCVtD7/JfWw5Hi03jPe1B+ZJNeDWJqCRXTv JnzhSPvS/UL84n4oYLYusa5TVtqxQU6WYJw9wMQ0NG1fCGmFMS4/0g/Xn4RMoPNaWAa8Rd 9hC3fcMICpChZQNK4PQAOXKC729f+5I0SsWzBVGw4d1Pfp5Dlk3SenvKe9OFMOXonvYh66 iPwKYtqlk7XEVD0Z6bWi7hV0J0dYQI+2uUBIRwdZT7qUtS3wJbl3k2dAKnO9bA== 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 4bYZGc0tv9zsD6; Fri, 04 Jul 2025 13:28:56 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 564DSuYL006165; Fri, 4 Jul 2025 13:28:56 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 564DSutn006160; Fri, 4 Jul 2025 13:28:56 GMT (envelope-from git) Date: Fri, 4 Jul 2025 13:28:56 GMT Message-Id: <202507041328.564DSutn006160@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Gleb Popov Subject: git: d888c75dd49e - stable/14 - p9fs: Use UNLINKAT instead of REMOVE to implement removals List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: arrowd X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: d888c75dd49e0f07f3bce297c87850f7c06f3938 Auto-Submitted: auto-generated The branch stable/14 has been updated by arrowd: URL: https://cgit.FreeBSD.org/src/commit/?id=d888c75dd49e0f07f3bce297c87850f7c06f3938 commit d888c75dd49e0f07f3bce297c87850f7c06f3938 Author: Mark Johnston AuthorDate: 2024-11-07 18:23:32 +0000 Commit: Gleb Popov CommitDate: 2025-07-04 13:28:06 +0000 p9fs: Use UNLINKAT instead of REMOVE to implement removals REMOVE doesn't work properly in the face of hard links. Use UNLINKAT instead, which is implemented by qemu and bhyve and lets the client specify the name being removed. PR: 282432 Reviewed by: dfr Differential Revision: https://reviews.freebsd.org/D47438 (cherry picked from commit 1d99e8d9a37e1ba528628186df57b79fe74e196c) --- sys/fs/p9fs/p9_client.c | 21 +++++++++++++++++++++ sys/fs/p9fs/p9_client.h | 1 + sys/fs/p9fs/p9_protocol.h | 2 ++ sys/fs/p9fs/p9fs_vnops.c | 21 ++++++++++++++------- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/sys/fs/p9fs/p9_client.c b/sys/fs/p9fs/p9_client.c index 45d24870306c..547de98c4c03 100644 --- a/sys/fs/p9fs/p9_client.c +++ b/sys/fs/p9fs/p9_client.c @@ -669,6 +669,27 @@ p9_client_remove(struct p9_fid *fid) return (error); } +int +p9_client_unlink(struct p9_fid *dfid, const char *name, int32_t flags) +{ + int error; + struct p9_client *clnt; + struct p9_req_t *req; + + error = 0; + clnt = dfid->clnt; + + req = p9_client_request(clnt, P9PROTO_TUNLINKAT, &error, "dsd", + dfid->fid, name, flags); + if (error != 0) { + P9_DEBUG(PROTO, "RUNLINKAT fid %d\n", dfid->fid); + return (error); + } + + p9_free_req(clnt, req); + return (error); +} + /* Inform the file server that the current file represented by fid is no longer * needed by the client. Any allocated fid on the server needs a clunk to be * destroyed. diff --git a/sys/fs/p9fs/p9_client.h b/sys/fs/p9fs/p9_client.h index 8597c0732ba3..79d402c174e8 100644 --- a/sys/fs/p9fs/p9_client.h +++ b/sys/fs/p9fs/p9_client.h @@ -140,6 +140,7 @@ int p9_client_write(struct p9_fid *fid, uint64_t offset, uint32_t count, char *d int p9_client_file_create(struct p9_fid *fid, char *name, uint32_t perm, int mode, char *extension); int p9_client_remove(struct p9_fid *fid); +int p9_client_unlink(struct p9_fid *dfid, const char *name, int32_t flags); int p9_dirent_read(struct p9_client *clnt, char *buf, int start, int len, struct p9_dirent *dirent); int p9_client_statfs(struct p9_fid *fid, struct p9_statfs *stat); diff --git a/sys/fs/p9fs/p9_protocol.h b/sys/fs/p9fs/p9_protocol.h index ddd8571adc8d..7ffd7dd67bcf 100644 --- a/sys/fs/p9fs/p9_protocol.h +++ b/sys/fs/p9fs/p9_protocol.h @@ -267,6 +267,8 @@ struct p9_iattr_dotl { #define P9PROTO_TGETATTR_BLK 512 +#define P9PROTO_UNLINKAT_REMOVEDIR 0x200 + /* PDU buffer used for SG lists. */ struct p9_buffer { uint32_t size; diff --git a/sys/fs/p9fs/p9fs_vnops.c b/sys/fs/p9fs/p9fs_vnops.c index 14951e96b59d..cfb50c704019 100644 --- a/sys/fs/p9fs/p9fs_vnops.c +++ b/sys/fs/p9fs/p9fs_vnops.c @@ -1497,7 +1497,8 @@ out: * After that, does a node metadata cleanup on client side. */ static int -remove_common(struct p9fs_node *np, struct ucred *cred) +remove_common(struct p9fs_node *dnp, struct p9fs_node *np, const char *name, + struct ucred *cred) { int error; struct p9fs_session *vses; @@ -1508,21 +1509,23 @@ remove_common(struct p9fs_node *np, struct ucred *cred) vses = np->p9fs_ses; vp = P9FS_NTOV(np); - vfid = p9fs_get_fid(vses->clnt, np, cred, VFID, -1, &error); + vfid = p9fs_get_fid(vses->clnt, dnp, cred, VFID, -1, &error); if (error != 0) return (error); - error = p9_client_remove(vfid); + error = p9_client_unlink(vfid, name, + np->v_node->v_type == VDIR ? P9PROTO_UNLINKAT_REMOVEDIR : 0); if (error != 0) return (error); /* Remove all non-open fids associated with the vp */ - p9fs_fid_remove_all(np, TRUE); + if (np->inode.i_links_count == 1) + p9fs_fid_remove_all(np, TRUE); /* Invalidate all entries of vnode from name cache and hash list. */ cache_purge(vp); - vfs_hash_remove(vp); + np->flags |= P9FS_NODE_DELETED; return (error); @@ -1537,8 +1540,10 @@ p9fs_remove(struct vop_remove_args *ap) struct vnode *dvp; struct p9fs_node *dnp; struct p9fs_inode *dinode; + struct componentname *cnp; int error; + cnp = ap->a_cnp; vp = ap->a_vp; np = P9FS_VTON(vp); dvp = ap->a_dvp; @@ -1550,7 +1555,7 @@ p9fs_remove(struct vop_remove_args *ap) if (vp->v_type == VDIR) return (EISDIR); - error = remove_common(np, ap->a_cnp->cn_cred); + error = remove_common(dnp, np, cnp->cn_nameptr, cnp->cn_cred); if (error == 0) P9FS_DECR_LINKS(dinode); @@ -1566,8 +1571,10 @@ p9fs_rmdir(struct vop_rmdir_args *ap) struct vnode *dvp; struct p9fs_node *dnp; struct p9fs_inode *dinode; + struct componentname *cnp; int error; + cnp = ap->a_cnp; vp = ap->a_vp; np = P9FS_VTON(vp); dvp = ap->a_dvp; @@ -1576,7 +1583,7 @@ p9fs_rmdir(struct vop_rmdir_args *ap) P9_DEBUG(VOPS, "%s: vp %p node %p \n", __func__, vp, np); - error = remove_common(np, ap->a_cnp->cn_cred); + error = remove_common(dnp, np, cnp->cn_nameptr, cnp->cn_cred); if (error == 0) P9FS_DECR_LINKS(dinode);