From nobody Thu Nov 25 00:36:13 2021 X-Original-To: dev-commits-src-branches@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 3EA9118A3E2D; Thu, 25 Nov 2021 00:36:14 +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 4HzzSs6fpxz4hyN; Thu, 25 Nov 2021 00:36:13 +0000 (UTC) (envelope-from git@FreeBSD.org) 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 C0B6E13C24; Thu, 25 Nov 2021 00:36:13 +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 1AP0aDln075680; Thu, 25 Nov 2021 00:36:13 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1AP0aDEN075679; Thu, 25 Nov 2021 00:36:13 GMT (envelope-from git) Date: Thu, 25 Nov 2021 00:36:13 GMT Message-Id: <202111250036.1AP0aDEN075679@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Rick Macklem Subject: git: 6e8e261f0d4e - stable/13 - nfscl: Add a LayoutError RPC for NFSv4.2 pNFS mounts List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@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/stable/13 X-Git-Reftype: branch X-Git-Commit: 6e8e261f0d4e8b71e2a7ab74a05e0ed7cae5704a Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1637800573; 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=OUKh27L1MEORK3Fn/WplBZX96NWC0R9OXUi0NdzTIfc=; b=wBTzM7gwNjMiVRPWwkxwNrAtXyUCo1o7/tWu3Finyq1fxEoZyKbdTOoJEXYTbmSIKekx2k 4M5Os96KwPBKItZHd9kJ6WqRgBe+wKego+Xcg3TybsbTFdtj+7kRX/XZAc93PpsaBDmOBI kmegzxF4g7MmnQy6jNeBzO4vA1WIu4CkiyXI86uVl7cDAE+UakCqx6O585NiYu0xdY+ZMb dWroQkPWtyJasOKVBwhfO7gWUwp//yw9ZgpbfYkNJy+K9A4UsNHl8TY3a1iV/d5AEADLrt kfHupau7vNsfIvcODyKUKREBf44zRZ5Ugpd1rcYm8m8zgKwmdy/noTI0V5uKIg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1637800573; a=rsa-sha256; cv=none; b=SdDbBe2z/LZRHwnjPYNDxua4CJ+sxAVwN2BA4sTh6yokfRQqiRMR936Bb2ivxJJZZbH1td ohpala+irnW5BqzYQGMuDR7T5dI48N7pauV3lNRDOT7s5Cy9jKC36CfrAfVHclmTdh+Rb9 XukExV2o6uvdZ3NCimzBhM9yxz8gU3XQIf6iOcdQjjtDgGuC2weFOGQg3de/LBhnaRwttD BkqRTXwheCEnF+YS8puaXuw2CgPI1QPZyazmvQfLWM+/bTgEJsm27dJfjiGxnDTKnotTZN GvRVlVIkBM91u/cXMhZTxPEVcpHmrEqF6ESS+QsuUo3VMeNjWYmwscKZy8Suow== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=6e8e261f0d4e8b71e2a7ab74a05e0ed7cae5704a commit 6e8e261f0d4e8b71e2a7ab74a05e0ed7cae5704a Author: Rick Macklem AuthorDate: 2021-11-11 23:43:58 +0000 Commit: Rick Macklem CommitDate: 2021-11-25 00:32:09 +0000 nfscl: Add a LayoutError RPC for NFSv4.2 pNFS mounts If a pNFS server's DS runs out of disk space, it replies NFSERR_NOSPC to the client doing writing. For the Linux client, it then sends a LayoutError RPC to the MDS server to tell it about the error. This patch adds the same to the FreeBSD NFSv4.2 pNFS client, to maintain Linux compatible behaviour, particlularily for non-FreeBSD pNFS servers. (cherry picked from commit 44744f75386e2102584acbca24fbe67de16051ca) --- sys/fs/nfs/nfs_commonsubs.c | 8 ++++-- sys/fs/nfs/nfsport.h | 15 ++++++++--- sys/fs/nfs/nfsproto.h | 11 +++++++- sys/fs/nfsclient/nfs_clrpcops.c | 56 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 6 deletions(-) diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 144b2e215496..58d517b0b13d 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -215,7 +215,7 @@ static struct nfsrv_lughash *nfsgroupnamehash; static int nfs_bigreply[NFSV42_NPROCS] = { 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 1, 0 }; + 1, 0, 0, 1, 0, 0, 0, 0 }; /* local functions */ static int nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep); @@ -299,6 +299,9 @@ static struct { { NFSV4OP_REMOVEXATTR, 2, "Rmxattr", 7, }, { NFSV4OP_LISTXATTRS, 2, "Listxattr", 9, }, { NFSV4OP_BINDCONNTOSESS, 1, "BindConSess", 11, }, + { NFSV4OP_LOOKUP, 5, "LookupOpen", 10, }, + { NFSV4OP_DEALLOCATE, 2, "Deallocate", 10, }, + { NFSV4OP_LAYOUTERROR, 1, "LayoutError", 11, }, }; /* @@ -307,7 +310,8 @@ static struct { static int nfs_bigrequest[NFSV42_NPROCS] = { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0 }; /* diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h index cb82666ab397..5dcce15f7f64 100644 --- a/sys/fs/nfs/nfsport.h +++ b/sys/fs/nfs/nfsport.h @@ -415,10 +415,19 @@ /* BindConnectionToSession, done by the krpc for a new connection. */ #define NFSPROC_BINDCONNTOSESS 65 +/* Do a Lookup+Open for "oneopenown". */ +#define NFSPROC_LOOKUPOPEN 66 + +/* Do an NFSv4.2 Deallocate. */ +#define NFSPROC_DEALLOCATE 67 + +/* Do an NFSv4.2 LayoutError. */ +#define NFSPROC_LAYOUTERROR 68 + /* * Must be defined as one higher than the last NFSv4.2 Proc# above. */ -#define NFSV42_NPROCS 66 +#define NFSV42_NPROCS 69 #endif /* NFS_V3NPROCS */ @@ -447,7 +456,7 @@ struct nfsstatsv1 { uint64_t readlink_bios; uint64_t biocache_readdirs; uint64_t readdir_bios; - uint64_t rpccnt[NFSV42_NPROCS + 14]; + uint64_t rpccnt[NFSV42_NPROCS + 11]; uint64_t rpcretries; uint64_t srvrpccnt[NFSV42_NOPS + NFSV4OP_FAKENOPS + 15]; uint64_t reserved_0; @@ -512,7 +521,7 @@ struct nfsstatsov1 { uint64_t readlink_bios; uint64_t biocache_readdirs; uint64_t readdir_bios; - uint64_t rpccnt[NFSV42_NPROCS + 3]; + uint64_t rpccnt[NFSV42_NPROCS]; uint64_t rpcretries; uint64_t srvrpccnt[NFSV42_PURENOPS + NFSV4OP_FAKENOPS]; uint64_t reserved_0; diff --git a/sys/fs/nfs/nfsproto.h b/sys/fs/nfs/nfsproto.h index 13e146154805..968cc6a41cc3 100644 --- a/sys/fs/nfs/nfsproto.h +++ b/sys/fs/nfs/nfsproto.h @@ -396,10 +396,19 @@ /* BindConnectionToSession, done by the krpc for a new connection. */ #define NFSPROC_BINDCONNTOSESS 65 +/* Do a Lookup+Open for "oneopenown". */ +#define NFSPROC_LOOKUPOPEN 66 + +/* Do an NFSv4.2 Deallocate. */ +#define NFSPROC_DEALLOCATE 67 + +/* Do an NFSv4.2 LayoutError. */ +#define NFSPROC_LAYOUTERROR 68 + /* * Must be defined as one higher than the last NFSv4.2 Proc# above. */ -#define NFSV42_NPROCS 66 +#define NFSV42_NPROCS 69 #endif /* NFS_V3NPROCS */ diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 6489569f8acf..b616cd729ab1 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -147,6 +147,9 @@ static int nfsrpc_locku(struct nfsrv_descript *, struct nfsmount *, u_int32_t, struct ucred *, NFSPROC_T *, int); static int nfsrpc_setaclrpc(vnode_t, struct ucred *, NFSPROC_T *, struct acl *, nfsv4stateid_t *, void *); +static int nfsrpc_layouterror(struct nfsmount *, uint8_t *, int, uint64_t, + uint64_t, nfsv4stateid_t *, struct ucred *, NFSPROC_T *, uint32_t, + uint32_t, char *); static int nfsrpc_getlayout(struct nfsmount *, vnode_t, struct nfsfh *, int, uint32_t, uint32_t *, nfsv4stateid_t *, uint64_t, struct nfscllayout **, struct ucred *, NFSPROC_T *); @@ -5459,6 +5462,44 @@ nfsmout: return (error); } +/* + * Do the NFSv4.2 LayoutError. + */ +static int +nfsrpc_layouterror(struct nfsmount *nmp, uint8_t *fh, int fhlen, uint64_t offset, + uint64_t len, nfsv4stateid_t *stateidp, struct ucred *cred, NFSPROC_T *p, + uint32_t stat, uint32_t op, char *devid) +{ + uint32_t *tl; + struct nfsrv_descript nfsd, *nd = &nfsd; + int error; + + nfscl_reqstart(nd, NFSPROC_LAYOUTERROR, nmp, fh, fhlen, NULL, NULL, + 0, 0); + NFSM_BUILD(tl, uint32_t *, 2 * NFSX_HYPER + NFSX_STATEID + + NFSX_V4DEVICEID + 3 * NFSX_UNSIGNED); + txdr_hyper(offset, tl); tl += 2; + txdr_hyper(len, tl); tl += 2; + *tl++ = txdr_unsigned(stateidp->seqid); + *tl++ = stateidp->other[0]; + *tl++ = stateidp->other[1]; + *tl++ = stateidp->other[2]; + *tl++ = txdr_unsigned(1); + NFSBCOPY(devid, tl, NFSX_V4DEVICEID); + tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED); + *tl++ = txdr_unsigned(stat); + *tl = txdr_unsigned(op); + nd->nd_flag |= ND_USEGSSNAME; + error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred, + NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL); + if (error != 0) + return (error); + if (nd->nd_repstat != 0) + error = nd->nd_repstat; + m_freem(nd->nd_mrep); + return (error); +} + /* * Acquire a layout and devinfo, if possible. The caller must have acquired * a reference count on the nfsclclient structure before calling this. @@ -5798,6 +5839,7 @@ nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, size_t iovlen = 0; off_t offs = 0; ssize_t resid = 0; + uint32_t op; if (!NFSHASPNFS(nmp) || nfscl_enablecallb == 0 || nfs_numnfscbd == 0 || (np->n_flag & NNOLAYOUT) != 0) @@ -5977,6 +6019,20 @@ nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, NFSLOCKMNT(nmp); nmp->nm_state |= NFSSTA_OPENMODE; NFSUNLOCKMNT(nmp); + } else if ((error == NFSERR_NOSPC || + error == NFSERR_IO || error == NFSERR_NXIO) && + nmp->nm_minorvers == NFSV42_MINORVERSION) { + if (docommit != 0) + op = NFSV4OP_COMMIT; + else if (rwaccess == NFSV4OPEN_ACCESSREAD) + op = NFSV4OP_READ; + else + op = NFSV4OP_WRITE; + nfsrpc_layouterror(nmp, np->n_fhp->nfh_fh, + np->n_fhp->nfh_len, off, xfer, + &layp->nfsly_stateid, newcred, p, error, op, + dip->nfsdi_deviceid); + error = EIO; } else error = EIO; if (error == 0)