From nobody Fri May 16 00:30:03 2025 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 4Zz7JX0tgjz5vj8j; Fri, 16 May 2025 00:30:04 +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 "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Zz7JW4lZ1z3QmS; Fri, 16 May 2025 00:30:03 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1747355403; 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=jYRcUGdEjG7Tz1mFFT2ubxp069UE9cImweZQyzb8r1M=; b=nMkBIEMD/46d4VXisVdakceB2PePp7eCCZQXZcOMTd55DljArmj7oiOVFiQ5PNRhIC9DnR zS4/ExDP1GQEjfRsSLQ/+FKpfYyF1bovAeSQx/LxpXL5++mPie1Almvy9yWGdNh2ng4Vmm z6bZIa9zq36+/4iohqP71Iuww+aBZ2rY5VHKBFynIX5BZ4QnvrokuwSArLbjlMc9/+wCjW p95ibpTumd2dfg7akI4BytfZLNjGgs8gu+kF56CLbJET/2vOqWRP/do/xvuPsG3GJsb1o1 rt542EjjjNr3e8dqJz0y+2Jyhm2xUHnYd9XLt5ydZCGPPdxLU0QWKGCfd2gUHQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1747355403; 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=jYRcUGdEjG7Tz1mFFT2ubxp069UE9cImweZQyzb8r1M=; b=Lj0zS3laXfAGzDoyTicrHmV8/8WYQSyPDt44SWb/PD7hlNTpgTz5WEg4+lMk23mWrL0YIT F5xhhKUXtUSD4pRq0b0QC563KUNOMVGHEddl5seYwmmILnsLrLyaOiebcJSwdDQVI22EE3 lwJIvh2GdBBecFbsTU3YZ1ALeqg+t++KGgekPrSO2+FCsPGe25PVJ8UVrn0NVlrS0PR2j5 Va4ilcanDD5O8uM06VRkKxRhmhK767Q/724w0bSsnz1vFLx5Fy9aRObmcBH4vILQBk6yJF CCHhq7dVqqPYjXMAg3Bpr9PdouDr4GwpwJYwwj/pJXBDz4doyrIKmXHjrAau9A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1747355403; a=rsa-sha256; cv=none; b=XPfwjOBeqSoz6Q1qGm87ofrVqeGVLK5FUKAdSc6fz5lUso6Q4XIXyYlh/ZnHuG5bOpUQXe C7YoB1Nhrv3m4AzUohqFsTgPnwv442tbf/7Bk0z5jRg3HiReo0erRaAghTD9ePl5T9INMj qS94OmNZRRuy5lyKEENvt1Oi3g4v1SlK7iuUxqEmzHynsvpgLpVDidLSrDa8OQswssM/Ye bpVufC4cT9A6gOUVyEmJ5Q3Ot5hbeuc+03LeqD4zektR2xInaQoHALE4WraCSyxKfgd51E VTjFSbzzNiySozQOjejgHKKh4h3c83OSsf55AAqX4xfXnc/Nas13cZDv3omVgw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none 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 4Zz7JW2c0lzgdg; Fri, 16 May 2025 00:30:03 +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 54G0U3Ns087243; Fri, 16 May 2025 00:30:03 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 54G0U3Jw087233; Fri, 16 May 2025 00:30:03 GMT (envelope-from git) Date: Fri, 16 May 2025 00:30:03 GMT Message-Id: <202505160030.54G0U3Jw087233@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Rick Macklem Subject: git: 772258c89f28 - main - nfs_clrpcops.c: Fix acquisition of post-op attributes for link 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: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rmacklem X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 772258c89f28501546844a60616211f44f55f4ce Auto-Submitted: auto-generated The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=772258c89f28501546844a60616211f44f55f4ce commit 772258c89f28501546844a60616211f44f55f4ce Author: Rick Macklem AuthorDate: 2025-05-16 00:27:14 +0000 Commit: Rick Macklem CommitDate: 2025-05-16 00:27:14 +0000 nfs_clrpcops.c: Fix acquisition of post-op attributes for link Without this patch, the link RPC (done by nfsrpc_link()) did not acquire post link operation attributes for the file object for NFSv4. For some recent Linux NFSv4 servers that support delegations, this would result in the client's cached attribute for st_nlinks not being increased right away, because the delegation would indicate that the now stale cached attributes were still valid. This patch fixes the problem by acquiring post link attributes and updating the client's cached copy in the same manner as the NFSv3 RPC did. Detected at the recent NFSv4 Bakeathon testing event. Applications will only be affected if they examine st_nlinks after a new hard link is created for a file object. MFC after: 2 weeks --- sys/fs/nfs/nfs_commonsubs.c | 2 +- sys/fs/nfsclient/nfs_clrpcops.c | 40 +++++++++++++++++++++++++++------------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 39fa6f091eee..eeeb079a6aa7 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -254,7 +254,7 @@ static struct { { NFSV4OP_REMOVE, 1, "Remove", 6, }, { NFSV4OP_REMOVE, 1, "Remove", 6, }, { NFSV4OP_SAVEFH, 5, "Rename", 6, }, - { NFSV4OP_SAVEFH, 4, "Link", 4, }, + { NFSV4OP_SAVEFH, 6, "Link", 4, }, { NFSV4OP_READDIR, 2, "Readdir", 7, }, { NFSV4OP_READDIR, 2, "Readdir", 7, }, { NFSV4OP_GETATTR, 1, "Getattr", 7, }, diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 0fb08df74a54..c1f94a65e506 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -3113,15 +3113,20 @@ nfsrpc_link(vnode_t dvp, vnode_t vp, char *name, int namelen, (void)nfsm_fhtom(VFSTONFS(dvp->v_mount), nd, VTONFS(dvp)->n_fhp->nfh_fh, VTONFS(dvp)->n_fhp->nfh_len, 0); if (nd->nd_flag & ND_NFSV4) { - NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(NFSV4OP_GETATTR); - NFSWCCATTR_ATTRBIT(&attrbits); - (void) nfsrv_putattrbit(nd, &attrbits); - nd->nd_flag |= ND_V4WCCATTR; NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(NFSV4OP_LINK); } (void) nfsm_strtom(nd, name, namelen); + if (nd->nd_flag & ND_NFSV4) { + NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV4OP_GETATTR); + NFSGETATTR_ATTRBIT(&attrbits); + (void)nfsrv_putattrbit(nd, &attrbits); + NFSM_BUILD(tl, uint32_t *, 2 * NFSX_UNSIGNED); + *tl++ = txdr_unsigned(NFSV4OP_RESTOREFH); + *tl = txdr_unsigned(NFSV4OP_GETATTR); + (void)nfsrv_putattrbit(nd, &attrbits); + } error = nfscl_request(nd, vp, p, cred); if (error) return (error); @@ -3130,19 +3135,28 @@ nfsrpc_link(vnode_t dvp, vnode_t vp, char *name, int namelen, if (!error) error = nfscl_wcc_data(nd, dvp, dnap, dattrflagp, NULL, NULL); - } else if ((nd->nd_flag & (ND_NFSV4 | ND_NOMOREDATA)) == ND_NFSV4) { + } else if (nd->nd_repstat == 0 && (nd->nd_flag & ND_NFSV4) != 0) { /* - * First, parse out the PutFH and Getattr result. + * First and parse out the PutFH and Link results. */ - NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - if (!(*(tl + 1))) - NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - if (*(tl + 1)) + NFSM_DISSECT(tl, uint32_t *, 5 * NFSX_UNSIGNED + + 2 * NFSX_HYPER); + if (*(tl + 3)) nd->nd_flag |= ND_NOMOREDATA; /* - * Get the pre-op attributes. + * Get the directory post-op attributes. */ - error = nfscl_wcc_data(nd, dvp, dnap, dattrflagp, NULL, NULL); + if ((nd->nd_flag & ND_NOMOREDATA) == 0) + error = nfscl_postop_attr(nd, dnap, dattrflagp); + if (error == 0 && (nd->nd_flag & ND_NOMOREDATA) == 0) { + /* Get rid of the RestoreFH reply. */ + NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED); + if (*(tl + 1)) + nd->nd_flag |= ND_NOMOREDATA; + } + /* Get the file's post-op attributes. */ + if (error == 0 && (nd->nd_flag & ND_NOMOREDATA) == 0) + error = nfscl_postop_attr(nd, nap, attrflagp); } if (nd->nd_repstat && !error) error = nd->nd_repstat;