From patchwork Fri Aug 16 12:42:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 13766069 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0E7961B4C4B; Fri, 16 Aug 2024 12:42:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723812155; cv=none; b=j56Nh2DFY1Z05jfanbrvYeOO8C3a+dAESIEU14n2as8k688qudXsWRiqI9neGtoqabMfeowNYqZvLN7IyvIFjsSa50pciUGTmGNRr4v6BshJo4vusQU6KVvBF7Pr/klASf+vwHahAvfk2iLIT53jnrYQXEwTjc9imoJdur1Dr8g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723812155; c=relaxed/simple; bh=XAVNd7eNGetYO/s4SKS4PDcX3zzd1/jHRso3c7tiSmE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZAXqwd35+Pn/F5bm25aVSfCLqZWSYptOLR5GASdTpkeV1l8ko9QPXQZHZcHRzRFZEwc+7tQI72acnOOLfpVQ0Nzt3vR4+iqFNHCIaC2hVtZtvW4kmwHeNgfZY27Y63LWhihM9XHwjVPShGHewRdyEINBSCP0HUaz+UCuNI+k20I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gBjwsILu; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gBjwsILu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8DC69C4AF10; Fri, 16 Aug 2024 12:42:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1723812154; bh=XAVNd7eNGetYO/s4SKS4PDcX3zzd1/jHRso3c7tiSmE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=gBjwsILugEhIcfbeRoqLUoZv915kh3omE4Sa6jEABgSdhguf08Uv86G10cJlHqnFt yZ4PwTBdz3oxNSZrX+fcTD3mGM85eVlgb6bQTQTq4HnS6653rm8mBIWpJmvZzEoQyU S7eJm9lnSwO2u8BxuUsS89bPo8DdGij4FCVIrvEvL43w9ZFVFtsaKM/SDy4MKaJ6kR li64YowvYUhz4b6sllkbe8ZjCXCSyxdoS4rwsPrFCayS2ATYB1ljCehlGCnCEmvMtm FjrCEkRq43hO8Z+FO6JfUPCUqmMRpc4Ayi60mOA4WO50n189E/7h9WtpFQpjgCbr/e q2UlvDNMkL78A== From: Jeff Layton Date: Fri, 16 Aug 2024 08:42:07 -0400 Subject: [PATCH 1/3] nfsd: bring in support for delstid draft XDR encoding Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240816-delstid-v1-1-c221c3dc14cd@kernel.org> References: <20240816-delstid-v1-0-c221c3dc14cd@kernel.org> In-Reply-To: <20240816-delstid-v1-0-c221c3dc14cd@kernel.org> To: Chuck Lever , Neil Brown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Tom Haynes , linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=15959; i=jlayton@kernel.org; h=from:subject:message-id; bh=XAVNd7eNGetYO/s4SKS4PDcX3zzd1/jHRso3c7tiSmE=; b=owEBbQKS/ZANAwAIAQAOaEEZVoIVAcsmYgBmv0k3/XxnMJjtI6vbJHTZqzIKf6jrsumJxOM4F foq+wrdNxCJAjMEAAEIAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCZr9JNwAKCRAADmhBGVaC FaMsD/0RW6jpspLZzCvAbO6I2I/sb7voE5bJgy0H8Zz48AEXDUgqvJARoMxpfJgGtKYl8dMAMZU wEE/y7GWZTasAi8wfoUgRJACWGG7asYUHvzV3ZNfY6I/9lE3R0AyfTFJe9yA4N8H7gHh0+5V1tI Z0K3Vx9tHZAFpXImk+MR6Ou8JXFt0kx5eXGSUoLy8y5CujOhPMMnLX86wcQpvzwxIy0Lk7M9jMC ExWVFOO08lKlyfaIdGKXhneqernyiX+NhM0nWhwfGqyrB+fT+zdzXgMiJvY4tun45vLSIHI/VYo Nhx9aXtwi/tDZzwdHjH4GiHVA+J6IkcA9eSo6DUvH4JymfeHv+R44FzzbV7yhDThOzu74kIMwek SOJ57gGeWvZIySaAXM1DM1QNGzygbnKy5XRw3qfvO393qbY9c6Ob8SDGVpGJQhu6sBlSVytxuaL v1O2a36371ERpx9fnlPrTz3WWbg55jLmEIXfihKGaGRdvkN9DKCb5KROON/txZS7M+Yj0iCR6QR K/AD4w/jaQNU97VDs9rIJjrXSjqM2PJPTGaEBNbJgML9pfiAnw8yXUtgkL30ySADz7k3nq4yE2V EYDdPl4Yf6jBSSuiMPbEQXNNwkX/ucYAsAPlbo35Dx33ydd3wIFmnxEdOh/Zh3e4mb1zsGjsJ4L fePOFDV0pxSi+RA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 This adds support for the "delstid" draft: https://datatracker.ietf.org/doc/draft-ietf-nfsv4-delstid/05/ Most of this was autogenerated using Chuck's lkxdrgen tool with some by-hand tweaks to work around some symbol conflicts, and to add some missing pieces that were needed from nfs4_1.x. Signed-off-by: Jeff Layton --- fs/nfsd/Makefile | 2 +- fs/nfsd/delstid_xdr.c | 464 ++++++++++++++++++++++++++++++++++++++++++++++++++ fs/nfsd/delstid_xdr.h | 102 +++++++++++ fs/nfsd/nfs4xdr.c | 1 + 4 files changed, 568 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/Makefile b/fs/nfsd/Makefile index b8736a82e57c..187fa45640e6 100644 --- a/fs/nfsd/Makefile +++ b/fs/nfsd/Makefile @@ -18,7 +18,7 @@ nfsd-$(CONFIG_NFSD_V2) += nfsproc.o nfsxdr.o nfsd-$(CONFIG_NFSD_V2_ACL) += nfs2acl.o nfsd-$(CONFIG_NFSD_V3_ACL) += nfs3acl.o nfsd-$(CONFIG_NFSD_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4idmap.o \ - nfs4acl.o nfs4callback.o nfs4recover.o + nfs4acl.o nfs4callback.o nfs4recover.o delstid_xdr.o nfsd-$(CONFIG_NFSD_PNFS) += nfs4layouts.o nfsd-$(CONFIG_NFSD_BLOCKLAYOUT) += blocklayout.o blocklayoutxdr.o nfsd-$(CONFIG_NFSD_SCSILAYOUT) += blocklayout.o blocklayoutxdr.o diff --git a/fs/nfsd/delstid_xdr.c b/fs/nfsd/delstid_xdr.c new file mode 100644 index 000000000000..63494d14f5d2 --- /dev/null +++ b/fs/nfsd/delstid_xdr.c @@ -0,0 +1,464 @@ +// SPDX-License-Identifier: GPL-2.0 +// Generated by lkxdrgen, with hand-edits. +// XDR specification modification time: Wed Aug 14 13:35:03 2024 + +#include "delstid_xdr.h" + +static inline bool +xdrgen_decode_void(struct xdr_stream *xdr) +{ + return true; +} + +static inline bool +xdrgen_decode_bool(struct xdr_stream *xdr, bool *ptr) +{ + __be32 *p = xdr_inline_decode(xdr, XDR_UNIT); + + if (unlikely(!p)) + return false; + *ptr = (*p != xdr_zero); + return true; +} + +static inline bool +xdrgen_decode_int(struct xdr_stream *xdr, s32 *ptr) +{ + __be32 *p = xdr_inline_decode(xdr, XDR_UNIT); + + if (unlikely(!p)) + return false; + *ptr = be32_to_cpup(p); + return true; +} + +static inline bool +xdrgen_decode_unsigned_int(struct xdr_stream *xdr, u32 *ptr) +{ + __be32 *p = xdr_inline_decode(xdr, XDR_UNIT); + + if (unlikely(!p)) + return false; + *ptr = be32_to_cpup(p); + return true; +} + +static inline bool +xdrgen_decode_uint32_t(struct xdr_stream *xdr, u32 *ptr) +{ + return xdrgen_decode_unsigned_int(xdr, ptr); +} + +static inline bool +xdrgen_decode_long(struct xdr_stream *xdr, s32 *ptr) +{ + __be32 *p = xdr_inline_decode(xdr, XDR_UNIT); + + if (unlikely(!p)) + return false; + *ptr = be32_to_cpup(p); + return true; +} + +static inline bool +xdrgen_decode_unsigned_long(struct xdr_stream *xdr, u32 *ptr) +{ + __be32 *p = xdr_inline_decode(xdr, XDR_UNIT); + + if (unlikely(!p)) + return false; + *ptr = be32_to_cpup(p); + return true; +} + +static inline bool +xdrgen_decode_hyper(struct xdr_stream *xdr, s64 *ptr) +{ + __be32 *p = xdr_inline_decode(xdr, XDR_UNIT * 2); + + if (unlikely(!p)) + return false; + *ptr = get_unaligned_be64(p); + return true; +} + +static inline bool +xdrgen_decode_int64_t(struct xdr_stream *xdr, s64 *ptr) +{ + return xdrgen_decode_hyper(xdr, ptr); +} + +static inline bool +xdrgen_decode_unsigned_hyper(struct xdr_stream *xdr, u64 *ptr) +{ + __be32 *p = xdr_inline_decode(xdr, XDR_UNIT * 2); + + if (unlikely(!p)) + return false; + *ptr = get_unaligned_be64(p); + return true; +} + +static bool __maybe_unused +xdrgen_decode_opaque(struct xdr_stream *xdr, opaque *ptr, u32 maxlen) +{ + __be32 *p; + u32 len; + + if (unlikely(xdr_stream_decode_u32(xdr, &len) != XDR_UNIT)) + return false; + if (unlikely(maxlen && len > maxlen)) + return false; + if (len != 0) { + p = xdr_inline_decode(xdr, len); + if (unlikely(!p)) + return false; + ptr->data = (u8 *)p; + } + ptr->len = len; + return true; +} + +static bool __maybe_unused +xdrgen_decode_string(struct xdr_stream *xdr, string *ptr, u32 maxlen) +{ + __be32 *p; + u32 len; + + if (unlikely(xdr_stream_decode_u32(xdr, &len) != XDR_UNIT)) + return false; + if (unlikely(maxlen && len > maxlen)) + return false; + if (len != 0) { + p = xdr_inline_decode(xdr, len); + if (unlikely(!p)) + return false; + ptr->data = (unsigned char *)p; + } + ptr->len = len; + return true; +} + +static inline bool +xdrgen_encode_void(struct xdr_stream *xdr) +{ + return true; +} + +static inline bool +xdrgen_encode_bool(struct xdr_stream *xdr, bool val) +{ + __be32 *p = xdr_reserve_space(xdr, XDR_UNIT); + + if (unlikely(!p)) + return false; + *p = val ? xdr_one : xdr_zero; + return true; +} + +static inline bool +xdrgen_encode_int(struct xdr_stream *xdr, s32 val) +{ + __be32 *p = xdr_reserve_space(xdr, XDR_UNIT); + + if (unlikely(!p)) + return false; + *p = cpu_to_be32(val); + return true; +} + +static inline bool +xdrgen_encode_unsigned_int(struct xdr_stream *xdr, u32 val) +{ + __be32 *p = xdr_reserve_space(xdr, XDR_UNIT); + + if (unlikely(!p)) + return false; + *p = cpu_to_be32(val); + return true; +} + +static inline bool +xdrgen_encode_uint32_t(struct xdr_stream *xdr, u32 val) +{ + return xdrgen_encode_unsigned_int(xdr, val); +} + +static inline bool +xdrgen_encode_long(struct xdr_stream *xdr, s32 val) +{ + __be32 *p = xdr_reserve_space(xdr, XDR_UNIT); + + if (unlikely(!p)) + return false; + *p = cpu_to_be32(val); + return true; +} + +static inline bool +xdrgen_encode_unsigned_long(struct xdr_stream *xdr, u32 val) +{ + __be32 *p = xdr_reserve_space(xdr, XDR_UNIT); + + if (unlikely(!p)) + return false; + *p = cpu_to_be32(val); + return true; +} + +static inline bool +xdrgen_encode_hyper(struct xdr_stream *xdr, s64 val) +{ + __be32 *p = xdr_reserve_space(xdr, XDR_UNIT * 2); + + if (unlikely(!p)) + return false; + put_unaligned_be64(val, p); + return true; +} + +static inline bool +xdrgen_encode_int64_t(struct xdr_stream *xdr, s64 val) +{ + return xdrgen_encode_hyper(xdr, val); +} + +static inline bool +xdrgen_encode_unsigned_hyper(struct xdr_stream *xdr, u64 val) +{ + __be32 *p = xdr_reserve_space(xdr, XDR_UNIT * 2); + + if (unlikely(!p)) + return false; + put_unaligned_be64(val, p); + return true; +} + +static bool __maybe_unused +xdrgen_encode_opaque(struct xdr_stream *xdr, opaque val) +{ + __be32 *p = xdr_reserve_space(xdr, XDR_UNIT + xdr_align_size(val.len)); + + if (unlikely(!p)) + return false; + xdr_encode_opaque(p, val.data, val.len); + return true; +} + +static bool __maybe_unused +xdrgen_encode_string(struct xdr_stream *xdr, string val, u32 maxlen) +{ + __be32 *p = xdr_reserve_space(xdr, XDR_UNIT + xdr_align_size(val.len)); + + if (unlikely(!p)) + return false; + xdr_encode_opaque(p, val.data, val.len); + return true; +} + +static bool __maybe_unused +xdrgen_decode_fattr4_offline(struct xdr_stream *xdr, fattr4_offline *ptr) +{ + return xdrgen_decode_bool(xdr, ptr); +}; + +static bool __maybe_unused +xdrgen_decode_bitmap4(struct xdr_stream *xdr, bitmap4 *ptr) +{ + if (xdr_stream_decode_u32(xdr, &ptr->count) < 0) + return false; + for (u32 i = 0; i < ptr->count; i++) + if (!xdrgen_decode_uint32_t(xdr, &ptr->element[i])) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_decode_open_arguments4(struct xdr_stream *xdr, struct open_arguments4 *ptr) +{ + if (!xdrgen_decode_bitmap4(xdr, &ptr->oa_share_access)) + return false; + if (!xdrgen_decode_bitmap4(xdr, &ptr->oa_share_deny)) + return false; + if (!xdrgen_decode_bitmap4(xdr, &ptr->oa_share_access_want)) + return false; + if (!xdrgen_decode_bitmap4(xdr, &ptr->oa_open_claim)) + return false; + if (!xdrgen_decode_bitmap4(xdr, &ptr->oa_create_mode)) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_decode_open_args_share_access4(struct xdr_stream *xdr, enum open_args_share_access4 *ptr) +{ + u32 val; + + if (xdr_stream_decode_u32(xdr, &val) < 0) + return false; + *ptr = val; + return true; +} + +static bool __maybe_unused +xdrgen_decode_open_args_share_deny4(struct xdr_stream *xdr, enum open_args_share_deny4 *ptr) +{ + u32 val; + + if (xdr_stream_decode_u32(xdr, &val) < 0) + return false; + *ptr = val; + return true; +} + +static bool __maybe_unused +xdrgen_decode_open_args_share_access_want4(struct xdr_stream *xdr, enum open_args_share_access_want4 *ptr) +{ + u32 val; + + if (xdr_stream_decode_u32(xdr, &val) < 0) + return false; + *ptr = val; + return true; +} + +static bool __maybe_unused +xdrgen_decode_open_args_open_claim4(struct xdr_stream *xdr, enum open_args_open_claim4 *ptr) +{ + u32 val; + + if (xdr_stream_decode_u32(xdr, &val) < 0) + return false; + *ptr = val; + return true; +} + +static bool __maybe_unused +xdrgen_decode_open_args_createmode4(struct xdr_stream *xdr, enum open_args_createmode4 *ptr) +{ + u32 val; + + if (xdr_stream_decode_u32(xdr, &val) < 0) + return false; + *ptr = val; + return true; +} + +static bool __maybe_unused +xdrgen_decode_fattr4_open_arguments(struct xdr_stream *xdr, fattr4_open_arguments *ptr) +{ + return xdrgen_decode_open_arguments4(xdr, ptr); +}; + +static bool __maybe_unused +xdrgen_decode_nfstime4(struct xdr_stream *xdr, struct _nfstime4 *ptr) +{ + if (!xdrgen_decode_int64_t(xdr, &ptr->seconds)) + return false; + if (!xdrgen_decode_uint32_t(xdr, &ptr->nseconds)) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_decode_fattr4_time_deleg_access(struct xdr_stream *xdr, fattr4_time_deleg_access *ptr) +{ + return xdrgen_decode_nfstime4(xdr, ptr); +}; + +static bool __maybe_unused +xdrgen_decode_fattr4_time_deleg_modify(struct xdr_stream *xdr, fattr4_time_deleg_modify *ptr) +{ + return xdrgen_decode_nfstime4(xdr, ptr); +}; + +static bool __maybe_unused +xdrgen_encode_fattr4_offline(struct xdr_stream *xdr, const fattr4_offline value) +{ + return xdrgen_encode_bool(xdr, value); +}; + +static bool __maybe_unused +xdrgen_encode_bitmap4(struct xdr_stream *xdr, const bitmap4 value) +{ + if (xdr_stream_encode_u32(xdr, value.count) != XDR_UNIT) + return false; + for (u32 i = 0; i < value.count; i++) + if (!xdrgen_encode_uint32_t(xdr, value.element[i])) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_encode_open_arguments4(struct xdr_stream *xdr, const struct open_arguments4 *value) +{ + if (!xdrgen_encode_bitmap4(xdr, value->oa_share_access)) + return false; + if (!xdrgen_encode_bitmap4(xdr, value->oa_share_deny)) + return false; + if (!xdrgen_encode_bitmap4(xdr, value->oa_share_access_want)) + return false; + if (!xdrgen_encode_bitmap4(xdr, value->oa_open_claim)) + return false; + if (!xdrgen_encode_bitmap4(xdr, value->oa_create_mode)) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_encode_open_args_share_access4(struct xdr_stream *xdr, enum open_args_share_access4 value) +{ + return xdr_stream_encode_u32(xdr, value) == XDR_UNIT; +} + +static bool __maybe_unused +xdrgen_encode_open_args_share_deny4(struct xdr_stream *xdr, enum open_args_share_deny4 value) +{ + return xdr_stream_encode_u32(xdr, value) == XDR_UNIT; +} + +static bool __maybe_unused +xdrgen_encode_open_args_share_access_want4(struct xdr_stream *xdr, enum open_args_share_access_want4 value) +{ + return xdr_stream_encode_u32(xdr, value) == XDR_UNIT; +} + +static bool __maybe_unused +xdrgen_encode_open_args_open_claim4(struct xdr_stream *xdr, enum open_args_open_claim4 value) +{ + return xdr_stream_encode_u32(xdr, value) == XDR_UNIT; +} + +static bool __maybe_unused +xdrgen_encode_open_args_createmode4(struct xdr_stream *xdr, enum open_args_createmode4 value) +{ + return xdr_stream_encode_u32(xdr, value) == XDR_UNIT; +} + +static bool __maybe_unused +xdrgen_encode_fattr4_open_arguments(struct xdr_stream *xdr, const fattr4_open_arguments *value) +{ + return xdrgen_encode_open_arguments4(xdr, value); +}; + +static bool __maybe_unused +xdrgen_encode_nfstime4(struct xdr_stream *xdr, const struct _nfstime4 *value) +{ + if (!xdrgen_encode_int64_t(xdr, value->seconds)) + return false; + if (!xdrgen_encode_uint32_t(xdr, value->nseconds)) + return false; + return true; +}; + +static bool __maybe_unused +xdrgen_encode_fattr4_time_deleg_access(struct xdr_stream *xdr, const fattr4_time_deleg_access value) +{ + return xdrgen_encode_nfstime4(xdr, &value); +}; + +static bool __maybe_unused +xdrgen_encode_fattr4_time_deleg_modify(struct xdr_stream *xdr, const fattr4_time_deleg_modify value) +{ + return xdrgen_encode_nfstime4(xdr, &value); +}; diff --git a/fs/nfsd/delstid_xdr.h b/fs/nfsd/delstid_xdr.h new file mode 100644 index 000000000000..3ca8d0cc8569 --- /dev/null +++ b/fs/nfsd/delstid_xdr.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Generated by lkxdrgen, with hand edits. */ +/* XDR specification modification time: Wed Aug 14 13:35:03 2024 */ + +#ifndef _DELSTID_H +#define _DELSTID_H + +#include +#include +#include + +typedef struct { + u32 len; + unsigned char *data; +} string; + +typedef struct { + u32 len; + u8 *data; +} opaque; + +typedef struct { + u32 count; + uint32_t *element; +} bitmap4; + +typedef struct _nfstime4 { + int64_t seconds; + uint32_t nseconds; +} nfstime4; + +typedef bool fattr4_offline; + +#define FATTR4_OFFLINE (83) + +typedef struct open_arguments4 { + bitmap4 oa_share_access; + bitmap4 oa_share_deny; + bitmap4 oa_share_access_want; + bitmap4 oa_open_claim; + bitmap4 oa_create_mode; +} open_arguments4; + +enum open_args_share_access4 { + OPEN_ARGS_SHARE_ACCESS_READ = 1, + OPEN_ARGS_SHARE_ACCESS_WRITE = 2, + OPEN_ARGS_SHARE_ACCESS_BOTH = 3, +}; + +enum open_args_share_deny4 { + OPEN_ARGS_SHARE_DENY_NONE = 0, + OPEN_ARGS_SHARE_DENY_READ = 1, + OPEN_ARGS_SHARE_DENY_WRITE = 2, + OPEN_ARGS_SHARE_DENY_BOTH = 3, +}; + +enum open_args_share_access_want4 { + OPEN_ARGS_SHARE_ACCESS_WANT_ANY_DELEG = 3, + OPEN_ARGS_SHARE_ACCESS_WANT_NO_DELEG = 4, + OPEN_ARGS_SHARE_ACCESS_WANT_CANCEL = 5, + OPEN_ARGS_SHARE_ACCESS_WANT_SIGNAL_DELEG_WHEN_RESRC_AVAIL = 17, + OPEN_ARGS_SHARE_ACCESS_WANT_PUSH_DELEG_WHEN_UNCONTENDED = 18, + OPEN_ARGS_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS = 20, + OPEN_ARGS_SHARE_ACCESS_WANT_OPEN_XOR_DELEGATION = 21, +}; + +enum open_args_open_claim4 { + OPEN_ARGS_OPEN_CLAIM_NULL = 0, + OPEN_ARGS_OPEN_CLAIM_PREVIOUS = 1, + OPEN_ARGS_OPEN_CLAIM_DELEGATE_CUR = 2, + OPEN_ARGS_OPEN_CLAIM_DELEGATE_PREV = 3, + OPEN_ARGS_OPEN_CLAIM_FH = 4, + OPEN_ARGS_OPEN_CLAIM_DELEG_CUR_FH = 5, + OPEN_ARGS_OPEN_CLAIM_DELEG_PREV_FH = 6, +}; + +enum open_args_createmode4 { + OPEN_ARGS_CREATEMODE_UNCHECKED4 = 0, + OPEN_ARGS_CREATE_MODE_GUARDED = 1, + OPEN_ARGS_CREATEMODE_EXCLUSIVE4 = 2, + OPEN_ARGS_CREATE_MODE_EXCLUSIVE4_1 = 3, +}; + +typedef open_arguments4 fattr4_open_arguments; + +#define FATTR4_OPEN_ARGUMENTS (86) + +#define OPEN4_SHARE_ACCESS_WANT_OPEN_XOR_DELEGATION (0x200000) + +#define OPEN4_RESULT_NO_OPEN_STATEID (0x00000010) + +typedef nfstime4 fattr4_time_deleg_access; + +typedef nfstime4 fattr4_time_deleg_modify; + +#define FATTR4_TIME_DELEG_ACCESS (84) + +#define FATTR4_TIME_DELEG_MODIFY (85) + +#define OPEN4_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS (0x100000) + +#endif /* _DELSTID_H */ diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 643ca3f8ebb3..b3d2000c8a08 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -55,6 +55,7 @@ #include "netns.h" #include "pnfs.h" #include "filecache.h" +#include "delstid_xdr.h" #include "trace.h" From patchwork Fri Aug 16 12:42:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 13766070 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3E0271B86D9; Fri, 16 Aug 2024 12:42:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723812156; cv=none; b=r5S3P/g8dTqSoL7WCmZkzygSxmodXF+gC2KX7SRxhE+qnq4Z9qWdoif0582EbbMsF95ObsF9VnQ98zmzqpPFBva0Unf1g6iVFkRfxI6bSpF3dvP24eJaOER7kRd2VAN0PF21ZC/TJP2zkLrDiuDnKsr5P3diQC1sVOUyh5jfv+M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723812156; c=relaxed/simple; bh=CKoZNlO+6BHaTw/P0n89Z7vG8n4Zt/QDOReFNcFnseM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Gw9SQ9n+5RU3jmHQC9g/g287+uqGthCeREMN+mbIZ3vvOa46I6MVmHKU22qHZsOass6tKw/AbTgUbuBwPJ7iVp6a8P/TghEcvm36KOO7UxklV0xsDjbDcBC53T5POEfXR21wWPf1oWY50xcXzRFrij/ZIkqi363RwuzCdkissAo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=euV7CHMS; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="euV7CHMS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D9EB7C4AF13; Fri, 16 Aug 2024 12:42:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1723812155; bh=CKoZNlO+6BHaTw/P0n89Z7vG8n4Zt/QDOReFNcFnseM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=euV7CHMS3W7SH0xggwpp5wMsvsY0gK8lkZSi10JiiFIqN60fz4FWCi2vy3Gb1aqzp 7aMmm8FK3xvhAGB75PuMnxoDuqAdGSgk+L9bKKhFuLj8Royy/Bqqd9yZDJPS+WrTJx tb+mLeMLzB+hoRUjDT1F1tWiQGbi1hPQ8Yj/K1eFfC/60zqpe8kC0ckjxWel/htxap PJtRFGH1Q+50JcDkniiH+kVJNFqanqrjIpwMobrkQ/ucHovqiYssHNOtbj5aFGMQSn TysidcQ2sCOF+sjuzaALEnYMGngTkmn69lsZGEcNC1sUednY+84r8kFR1NKHyBujBw kREIZ88FeGlwQ== From: Jeff Layton Date: Fri, 16 Aug 2024 08:42:08 -0400 Subject: [PATCH 2/3] nfsd: add support for FATTR4_OPEN_ARGUMENTS Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240816-delstid-v1-2-c221c3dc14cd@kernel.org> References: <20240816-delstid-v1-0-c221c3dc14cd@kernel.org> In-Reply-To: <20240816-delstid-v1-0-c221c3dc14cd@kernel.org> To: Chuck Lever , Neil Brown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Tom Haynes , linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4607; i=jlayton@kernel.org; h=from:subject:message-id; bh=CKoZNlO+6BHaTw/P0n89Z7vG8n4Zt/QDOReFNcFnseM=; b=owEBbQKS/ZANAwAIAQAOaEEZVoIVAcsmYgBmv0k384xDAHU2ZhGgfyCvNsQuInKf+6GIKttrj lADjeRPhuWJAjMEAAEIAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCZr9JNwAKCRAADmhBGVaC FepuD/4x2LkUlCdvtHBrs6VUHVV45f0GiR5QpoDsbKJoA/xjsBvD/Wbn4vP/wl+NmlGs5xBoukH I3zH0r5yakjkgtmulYGgP/ZsbnYHR0qt6j117HaSiHa8hOdUaW2Pd/HKSUGlZ722Gm4uCDgVyCv RnrH+X9N4rUOK+sWBjcn5XgIhlJ66xpgIOGOc+VTEOv08l3oUSL3rmpMh1l/e6wqurxL+f5FPRz 0SxOquihSCQgkqIo4PDVsB1waKAEDcqiBRnWvrl74Q/5SWU8x6TnzI9ileZ6+lbSqGHG5z3qK5x UlGMZlYUt5xBfPRJhsrunk60EjVqMhX1TSPBxAG2xE2AdW5VOKnlI9Ga3Ptn5H1uw11LO3texsF fzDZuI6HtjbK1gqfZnUByM2yLbt5muP0zhxZXw1Q8l1UmgirgwjpuLnwpASDAKJMbkTEWeclgah UVJSISAg0F/AX9zP13P8UbnJVhe++lT09EA2bMnETskV9uUiTT4Kx+x/v94e7HLmWuNOSoFV3vX LWPwcGOIXt+AbJpfYrKoLT2SRlmkaVI6gBu8aIR0Lq6WaDGsdP6ETaHzF1gg+4m11hAd9Cmufoq 7WxNj92ctc5VfRYg5X+bTVuiOhB9OiQpFe3OAo2y6X9zaQZ/fYCHBz9djR2UF9Uq6mpvEpEu7sq HAJotCnCzrwnz1g== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add support for FATTR4_OPEN_ARGUMENTS. This a new mechanism for the client to discover what OPEN features the server supports. Signed-off-by: Jeff Layton --- fs/nfsd/delstid_xdr.c | 2 +- fs/nfsd/delstid_xdr.h | 3 +++ fs/nfsd/nfs4xdr.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ fs/nfsd/nfsd.h | 3 ++- 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/delstid_xdr.c b/fs/nfsd/delstid_xdr.c index 63494d14f5d2..b63f338da357 100644 --- a/fs/nfsd/delstid_xdr.c +++ b/fs/nfsd/delstid_xdr.c @@ -435,7 +435,7 @@ xdrgen_encode_open_args_createmode4(struct xdr_stream *xdr, enum open_args_creat return xdr_stream_encode_u32(xdr, value) == XDR_UNIT; } -static bool __maybe_unused +bool xdrgen_encode_fattr4_open_arguments(struct xdr_stream *xdr, const fattr4_open_arguments *value) { return xdrgen_encode_open_arguments4(xdr, value); diff --git a/fs/nfsd/delstid_xdr.h b/fs/nfsd/delstid_xdr.h index 3ca8d0cc8569..2a91a353ab93 100644 --- a/fs/nfsd/delstid_xdr.h +++ b/fs/nfsd/delstid_xdr.h @@ -99,4 +99,7 @@ typedef nfstime4 fattr4_time_deleg_modify; #define OPEN4_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS (0x100000) +/* delstid.c */ +bool xdrgen_encode_fattr4_open_arguments(struct xdr_stream *xdr, + const fattr4_open_arguments *value); #endif /* _DELSTID_H */ diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index b3d2000c8a08..dbaadb0ad980 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3400,6 +3400,58 @@ static __be32 nfsd4_encode_fattr4_xattr_support(struct xdr_stream *xdr, return nfsd4_encode_bool(xdr, err == 0); } +#define NFSD_OA_SHARE_ACCESS (BIT(OPEN_ARGS_SHARE_ACCESS_READ) | \ + BIT(OPEN_ARGS_SHARE_ACCESS_WRITE) | \ + BIT(OPEN_ARGS_SHARE_ACCESS_BOTH)) + +#define NFSD_OA_SHARE_DENY (BIT(OPEN_ARGS_SHARE_DENY_NONE) | \ + BIT(OPEN_ARGS_SHARE_DENY_READ) | \ + BIT(OPEN_ARGS_SHARE_DENY_WRITE) | \ + BIT(OPEN_ARGS_SHARE_DENY_BOTH)) + +#define NFSD_OA_SHARE_ACCESS_WANT (BIT(OPEN_ARGS_SHARE_ACCESS_WANT_ANY_DELEG) | \ + BIT(OPEN_ARGS_SHARE_ACCESS_WANT_NO_DELEG) | \ + BIT(OPEN_ARGS_SHARE_ACCESS_WANT_CANCEL)) + +#define NFSD_OA_OPEN_CLAIM (BIT(OPEN_ARGS_OPEN_CLAIM_NULL) | \ + BIT(OPEN_ARGS_OPEN_CLAIM_PREVIOUS) | \ + BIT(OPEN_ARGS_OPEN_CLAIM_DELEGATE_CUR) | \ + BIT(OPEN_ARGS_OPEN_CLAIM_DELEGATE_PREV)| \ + BIT(OPEN_ARGS_OPEN_CLAIM_FH) | \ + BIT(OPEN_ARGS_OPEN_CLAIM_DELEG_CUR_FH) | \ + BIT(OPEN_ARGS_OPEN_CLAIM_DELEG_PREV_FH)) + +#define NFSD_OA_CREATE_MODE (BIT(OPEN_ARGS_CREATEMODE_UNCHECKED4) | \ + BIT(OPEN_ARGS_CREATE_MODE_GUARDED) | \ + BIT(OPEN_ARGS_CREATEMODE_EXCLUSIVE4) | \ + BIT(OPEN_ARGS_CREATE_MODE_EXCLUSIVE4_1)) + +static __be32 nfsd4_encode_fattr4_open_arguments(struct xdr_stream *xdr, + const struct nfsd4_fattr_args *args) +{ + uint32_t oa_share_access = NFSD_OA_SHARE_ACCESS; + uint32_t oa_share_deny = NFSD_OA_SHARE_DENY; + uint32_t oa_share_access_want = NFSD_OA_SHARE_ACCESS_WANT; + uint32_t oa_open_claim = NFSD_OA_OPEN_CLAIM; + uint32_t oa_create_mode = NFSD_OA_CREATE_MODE; + struct open_arguments4 oa; + + oa.oa_share_access.count = 1; + oa.oa_share_access.element = &oa_share_access; + oa.oa_share_deny.count = 1; + oa.oa_share_deny.element = &oa_share_deny; + oa.oa_share_access_want.count = 1; + oa.oa_share_access_want.element = &oa_share_access_want; + oa.oa_open_claim.count = 1; + oa.oa_open_claim.element = &oa_open_claim; + oa.oa_create_mode.count = 1; + oa.oa_create_mode.element = &oa_create_mode; + + if (!xdrgen_encode_fattr4_open_arguments(xdr, &oa)) + return nfserr_resource; + return nfs_ok; +} + static const nfsd4_enc_attr nfsd4_enc_fattr4_encode_ops[] = { [FATTR4_SUPPORTED_ATTRS] = nfsd4_encode_fattr4_supported_attrs, [FATTR4_TYPE] = nfsd4_encode_fattr4_type, @@ -3500,6 +3552,7 @@ static const nfsd4_enc_attr nfsd4_enc_fattr4_encode_ops[] = { [FATTR4_MODE_UMASK] = nfsd4_encode_fattr4__noop, [FATTR4_XATTR_SUPPORT] = nfsd4_encode_fattr4_xattr_support, + [FATTR4_OPEN_ARGUMENTS] = nfsd4_encode_fattr4_open_arguments, }; /* diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 4ccbf014a2c7..c98fb104ba7d 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -454,7 +454,8 @@ enum { (NFSD4_1_SUPPORTED_ATTRS_WORD2 | \ FATTR4_WORD2_MODE_UMASK | \ NFSD4_2_SECURITY_ATTRS | \ - FATTR4_WORD2_XATTR_SUPPORT) + FATTR4_WORD2_XATTR_SUPPORT | \ + FATTR4_WORD2_OPEN_ARGUMENTS) extern const u32 nfsd_suppattrs[3][3]; From patchwork Fri Aug 16 12:42:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 13766071 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 32DCC1B86FB; Fri, 16 Aug 2024 12:42:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723812157; cv=none; b=FQe3roroq8kU9ZFLaQSnVH5Rl7yKS5vaXY6BhkcOkDQsSBUu3edk+XgC4E9EIbw3D+EJRnxyh4q0oYg9gvrG4mMvGFYxl20S4T5hdwv7+Fb90p3o0M+W5Kt6uHWTk/XJcm6AVikdbAaQCUCsQqN30bNPITa7tF16SbxbgSNHrZ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723812157; c=relaxed/simple; bh=2Rn+7obbQILo75kJbV/0b2zIBmSLl5DIxT28qY2BWXU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Fydi5HcCYnyps4OalFtZdxwtgQ7Nnb89z4Yzrw2nXRI5aBKnpY3+8D4zM96aJTfnuKdj43t4lIRsEsecGu5ib2t/7Z4ZKTwvge2lzBa6fp51b4ewvUJnh0jBbDW8sIgOlsN6U9utp9JPkMpSkwLCHxyxi2ucNH9s2XudxGTTZsg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=A7TvqmQK; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="A7TvqmQK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1253BC32782; Fri, 16 Aug 2024 12:42:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1723812157; bh=2Rn+7obbQILo75kJbV/0b2zIBmSLl5DIxT28qY2BWXU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=A7TvqmQKvEqghTYmZSsxs8PX1YQTz2iorX6Y0k8t2jXQzqIzGAzPEJaWjyuqKqpkp jRtd7rLV6DK67O8qai3l32IIZkQsYydxmm+V9rQ7azHzS6CFMxZMOorZuTbX9WTuIQ M+5fEU0mFUurpRKBZUQclG50M0NfPP+5oMiFTUNr4A7SXRptXC/GkvYDT/kBTJvdPX LPisENFRshMAtbdfmmiEWG+SQQ/OM+U2T57n8yHnZ03mTQ5LYpTsSggq6KcIrrHUrj 3SLS2HAXjI/53Eaw6o9JfMwT3iXFQOXuk+GO05GZADs7IDKFa2BP3jCJp2LSLdIdaS 5a0XyY7hjYzow== From: Jeff Layton Date: Fri, 16 Aug 2024 08:42:09 -0400 Subject: [PATCH 3/3] nfsd: implement OPEN_ARGS_SHARE_ACCESS_WANT_OPEN_XOR_DELEGATION Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240816-delstid-v1-3-c221c3dc14cd@kernel.org> References: <20240816-delstid-v1-0-c221c3dc14cd@kernel.org> In-Reply-To: <20240816-delstid-v1-0-c221c3dc14cd@kernel.org> To: Chuck Lever , Neil Brown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker Cc: Tom Haynes , linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5770; i=jlayton@kernel.org; h=from:subject:message-id; bh=2Rn+7obbQILo75kJbV/0b2zIBmSLl5DIxT28qY2BWXU=; b=owEBbQKS/ZANAwAIAQAOaEEZVoIVAcsmYgBmv0k4OSAyuXEt4tdH+4tnp4U6uVekWYFeDvkph VC5Vc2vPEiJAjMEAAEIAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCZr9JOAAKCRAADmhBGVaC FfrqD/4u58lJLNqhuJn0g+OhIMScCoQw5x8/UOS3b9Fsxp4xkdlewMUw9P+k7t0oazQvB6QKICW y94PQKDi9dMezICQJI+h7qnf28tFciP4hUMc6c+rRY2QGouoXycilp8LoX59i+yWtxbrK/ArOnv woiMSSyIht4CPVTfPOCeGPT+VD5RCe+muaqfJB8fL/ivMjiZdmk98sYsy8ve3rRb2ARKQh1gVEs sM0U2/rLsH8/iFaPdgp/SEO5HuGhKIk0cjmnI4qnmyGsw9aVx2nJX5LeEcTelguVhKsmePgmmjt C+srLNpj14stn12u7Yp0heVdwC3ffJScRZkLQaV1bdvkGZImOEWD39jnUUimJdIlY8wWX6BczO+ 3a4UpG4Ynnogty/SuisPRtJJ3IOSddOKUUm+PpC2WU1oK7H81I9vTXs/kitlWhYutt8BMbmxFp3 HZrPGs6feBApBrHmg6Qykw9+whOtfiUP7CBTwxbbh9Z7+irEWnO2NyIFPqL+AEi21brOV54uaCt 0bS3JtRerhGHUrXik1fsM6N//YT+8ghc5LEdppeo6kbx9o4zxOIf23MtGXx/na9TiBVjrAeo1Y9 YncdobMaQJNJnV12Y34f22Fpt2I+QLG/nBhwzvO3nYRcgktdY1jcqqhZNFGXD+OZm0s3xxMl6Ss d8by10kunM5lwpA== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Allow clients to request getting a delegation xor an open stateid if a delegation isn't available. This allows the client to avoid sending a final CLOSE for the (useless) open stateid, when it is granted a delegation. This is done by moving the increment of the open stateid and unlocking of the st_mutex until after we acquire a delegation. If we get a delegation, we zero out the op_stateid field and set the NO_OPEN_STATEID flag. If the open stateid was brand new, then unhash it too in this case since it won't be needed. If we can't get a delegation or the new flag wasn't requested, then just increment and copy the open stateid as usual. Signed-off-by: Jeff Layton --- fs/nfsd/nfs4state.c | 29 +++++++++++++++++++++++++---- fs/nfsd/nfs4xdr.c | 5 +++-- include/uapi/linux/nfs4.h | 7 +++++-- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index b67f151837c1..9d209cbd95cd 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -56,6 +56,7 @@ #include "pnfs.h" #include "filecache.h" #include "trace.h" +#include "delstid_xdr.h" #define NFSDDBG_FACILITY NFSDDBG_PROC @@ -6029,6 +6030,17 @@ static void nfsd4_deleg_xgrade_none_ext(struct nfsd4_open *open, */ } +/* Are we only returning a delegation stateid? */ +static bool open_xor_delegation(struct nfsd4_open *open) +{ + if (!(open->op_deleg_want & OPEN4_SHARE_ACCESS_WANT_OPEN_XOR_DELEGATION)) + return false; + if (open->op_delegate_type != NFS4_OPEN_DELEGATE_READ && + open->op_delegate_type != NFS4_OPEN_DELEGATE_WRITE) + return false; + return true; +} + /** * nfsd4_process_open2 - finish open processing * @rqstp: the RPC transaction being executed @@ -6051,6 +6063,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf struct nfs4_delegation *dp = NULL; __be32 status; bool new_stp = false; + bool deleg_only = false; /* * Lookup file; if found, lookup stateid and check open request, @@ -6105,9 +6118,6 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf open->op_odstate = NULL; } - nfs4_inc_and_copy_stateid(&open->op_stateid, &stp->st_stid); - mutex_unlock(&stp->st_mutex); - if (nfsd4_has_session(&resp->cstate)) { if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) { open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE_EXT; @@ -6121,7 +6131,18 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf * OPEN succeeds even if we fail. */ nfs4_open_delegation(open, stp, &resp->cstate.current_fh); + deleg_only = open_xor_delegation(open); nodeleg: + if (deleg_only) { + memcpy(&open->op_stateid, &zero_stateid, sizeof(open->op_stateid)); + open->op_rflags |= OPEN4_RESULT_NO_OPEN_STATEID; + if (new_stp) + release_open_stateid(stp); + } else { + nfs4_inc_and_copy_stateid(&open->op_stateid, &stp->st_stid); + } + mutex_unlock(&stp->st_mutex); + status = nfs_ok; trace_nfsd_open(&stp->st_stid.sc_stateid); out: @@ -6137,7 +6158,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf /* * To finish the open response, we just need to set the rflags. */ - open->op_rflags = NFS4_OPEN_RESULT_LOCKTYPE_POSIX; + open->op_rflags |= NFS4_OPEN_RESULT_LOCKTYPE_POSIX; if (nfsd4_has_session(&resp->cstate)) open->op_rflags |= NFS4_OPEN_RESULT_MAY_NOTIFY_LOCK; else if (!(open->op_openowner->oo_flags & NFS4_OO_CONFIRMED)) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index dbaadb0ad980..ecc9ddf4c28d 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1067,7 +1067,7 @@ static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *sh return nfs_ok; if (!argp->minorversion) return nfserr_bad_xdr; - switch (w & NFS4_SHARE_WANT_MASK) { + switch (w & NFS4_SHARE_WANT_TYPE_MASK) { case NFS4_SHARE_WANT_NO_PREFERENCE: case NFS4_SHARE_WANT_READ_DELEG: case NFS4_SHARE_WANT_WRITE_DELEG: @@ -3411,7 +3411,8 @@ static __be32 nfsd4_encode_fattr4_xattr_support(struct xdr_stream *xdr, #define NFSD_OA_SHARE_ACCESS_WANT (BIT(OPEN_ARGS_SHARE_ACCESS_WANT_ANY_DELEG) | \ BIT(OPEN_ARGS_SHARE_ACCESS_WANT_NO_DELEG) | \ - BIT(OPEN_ARGS_SHARE_ACCESS_WANT_CANCEL)) + BIT(OPEN_ARGS_SHARE_ACCESS_WANT_CANCEL) | \ + BIT(OPEN_ARGS_SHARE_ACCESS_WANT_OPEN_XOR_DELEGATION)) #define NFSD_OA_OPEN_CLAIM (BIT(OPEN_ARGS_OPEN_CLAIM_NULL) | \ BIT(OPEN_ARGS_OPEN_CLAIM_PREVIOUS) | \ diff --git a/include/uapi/linux/nfs4.h b/include/uapi/linux/nfs4.h index caf4db2fcbb9..4273e0249fcb 100644 --- a/include/uapi/linux/nfs4.h +++ b/include/uapi/linux/nfs4.h @@ -58,7 +58,7 @@ #define NFS4_SHARE_DENY_BOTH 0x0003 /* nfs41 */ -#define NFS4_SHARE_WANT_MASK 0xFF00 +#define NFS4_SHARE_WANT_TYPE_MASK 0xFF00 #define NFS4_SHARE_WANT_NO_PREFERENCE 0x0000 #define NFS4_SHARE_WANT_READ_DELEG 0x0100 #define NFS4_SHARE_WANT_WRITE_DELEG 0x0200 @@ -66,13 +66,16 @@ #define NFS4_SHARE_WANT_NO_DELEG 0x0400 #define NFS4_SHARE_WANT_CANCEL 0x0500 -#define NFS4_SHARE_WHEN_MASK 0xF0000 +#define NFS4_SHARE_WHEN_MASK 0xF0000 #define NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL 0x10000 #define NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED 0x20000 +#define NFS4_SHARE_WANT_MOD_MASK 0xF00000 #define NFS4_SHARE_WANT_DELEG_TIMESTAMPS 0x100000 #define NFS4_SHARE_WANT_OPEN_XOR_DELEGATION 0x200000 +#define NFS4_SHARE_WANT_MASK (NFS4_SHARE_WANT_TYPE_MASK | NFS4_SHARE_WANT_MOD_MASK) + #define NFS4_CDFC4_FORE 0x1 #define NFS4_CDFC4_BACK 0x2 #define NFS4_CDFC4_BOTH 0x3