Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp573075pxj; Thu, 3 Jun 2021 13:52:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzN0QoYr50S1XUVtui+yUFwPrL2+ME4JxNkIFCDbDByfIy0tZYJohd8Iy/ftRGCo2g3L7Tc X-Received: by 2002:a05:6402:4c5:: with SMTP id n5mr1235438edw.322.1622753551388; Thu, 03 Jun 2021 13:52:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622753551; cv=none; d=google.com; s=arc-20160816; b=Zrp1Okl2Kj6Z2UDj89tapJ1H4aNlnJ0VIWgeZz4ShKPaXi6Tw/8Tj4zaJjUJV2BuZ6 5mu9kbQAejT3ROW1N9Dz3d8RBP9mrRxnO3OC2PkrpjThcQQlLvXxNeA1OBKbRtJpvn3b v086vrshygh9ZSUSKj9MTH75SSz54AMrkr7muqNT3T+4u9PA/mse6f+1u4csklSetk1A vDF4imC4VMBMBKCVk6e6d0kFnK6GCoZGUDGtsrmpyaXV532KfPMATnDJk0rwkG3Acmlc l3kebi/OsuOOUOCWgnLUyVfz8d+BYLtOUh5j4ggnkbd6N7zP6pLUj29SwyqDrS9RZ/jk 8uQQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:cc:to:from :subject; bh=FJhZeU2sUkKfL/e+IZI0GqXXR8lVUYg9/XpOU18ZQEk=; b=jciJJ4RE55A8Nuw3rRowFr6eNwsuhy5qJqzk5vgOYim6MP184qUe8o54NX5Kw3V+RF 74ymg1EkqKD2uPHwAtDJlCNQlWPhcypGh/wYbCNfsp5wvI66Pb6hwM0pfvnW2jL6HKA9 qZbl4DcZ8uTsO/4Gho7tFVWGMG39ryzp2Yh2OYvN8TgbJf98TNkQEcadrJ/LIXHwf0Dd FtNc56iZlB3gIs2Xahr6e9mU/hjNr/HRZ/F6u/rKFvzdUxl0537tA5XKvk1/ZxW4dKAj ZYJHF78pa8zzwjr1ckz46KtMBgFD8vEziGjvrT8rOR32s1hPFYOBP57xG/HdLqw/qHOz YY+w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=oracle.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id m19si3393055edd.490.2021.06.03.13.52.08; Thu, 03 Jun 2021 13:52:31 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=oracle.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229894AbhFCUwi (ORCPT + 99 others); Thu, 3 Jun 2021 16:52:38 -0400 Received: from mail.kernel.org ([198.145.29.99]:44598 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229576AbhFCUwi (ORCPT ); Thu, 3 Jun 2021 16:52:38 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id D90F2613E7; Thu, 3 Jun 2021 20:50:52 +0000 (UTC) Subject: [PATCH 03/29] lockd: Common NLM XDR helpers From: Chuck Lever To: bfields@fieldses.org Cc: linux-nfs@vger.kernel.org Date: Thu, 03 Jun 2021 16:50:52 -0400 Message-ID: <162275345217.32691.12086548088820348898.stgit@klimt.1015granger.net> In-Reply-To: <162275337584.32691.3943139351165347555.stgit@klimt.1015granger.net> References: <162275337584.32691.3943139351165347555.stgit@klimt.1015granger.net> User-Agent: StGit/1.1 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org Add a .h file containing xdr_stream-based XDR helpers common to both NLMv3 and NLMv4. Signed-off-by: Chuck Lever --- fs/lockd/svcxdr.h | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 fs/lockd/svcxdr.h diff --git a/fs/lockd/svcxdr.h b/fs/lockd/svcxdr.h new file mode 100644 index 000000000000..c69a0bb76c94 --- /dev/null +++ b/fs/lockd/svcxdr.h @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Encode/decode NLM basic data types + * + * Basic NLMv3 XDR data types are not defined in an IETF standards + * document. X/Open has a description of these data types that + * is useful. See Chapter 10 of "Protocols for Interworking: + * XNFS, Version 3W". + * + * Basic NLMv4 XDR data types are defined in Appendix II.1.4 of + * RFC 1813: "NFS Version 3 Protocol Specification". + * + * Author: Chuck Lever + * + * Copyright (c) 2020, Oracle and/or its affiliates. + */ + +#ifndef _LOCKD_SVCXDR_H_ +#define _LOCKD_SVCXDR_H_ + +static inline bool +svcxdr_decode_stats(struct xdr_stream *xdr, __be32 *status) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, XDR_UNIT); + if (!p) + return false; + *status = *p; + + return true; +} + +static inline bool +svcxdr_encode_stats(struct xdr_stream *xdr, __be32 status) +{ + __be32 *p; + + p = xdr_reserve_space(xdr, XDR_UNIT); + if (!p) + return false; + *p = status; + + return true; +} + +static inline bool +svcxdr_decode_string(struct xdr_stream *xdr, char **data, unsigned int *data_len) +{ + __be32 *p; + u32 len; + + if (xdr_stream_decode_u32(xdr, &len) < 0) + return false; + if (len > NLM_MAXSTRLEN) + return false; + p = xdr_inline_decode(xdr, len); + if (!p) + return false; + *data_len = len; + *data = (char *)p; + + return true; +} + +/* + * NLM cookies are defined by specification to be a variable-length + * XDR opaque no longer than 1024 bytes. However, this implementation + * limits their length to 32 bytes, and treats zero-length cookies + * specially. + */ +static inline bool +svcxdr_decode_cookie(struct xdr_stream *xdr, struct nlm_cookie *cookie) +{ + __be32 *p; + u32 len; + + if (xdr_stream_decode_u32(xdr, &len) < 0) + return false; + if (len > NLM_MAXCOOKIELEN) + return false; + if (!len) + goto out_hpux; + + p = xdr_inline_decode(xdr, len); + if (!p) + return false; + cookie->len = len; + memcpy(cookie->data, p, len); + + return true; + + /* apparently HPUX can return empty cookies */ +out_hpux: + cookie->len = 4; + memset(cookie->data, 0, 4); + return true; +} + +static inline bool +svcxdr_encode_cookie(struct xdr_stream *xdr, const struct nlm_cookie *cookie) +{ + __be32 *p; + + if (xdr_stream_encode_u32(xdr, cookie->len) < 0) + return false; + p = xdr_reserve_space(xdr, cookie->len); + if (!p) + return false; + memcpy(p, cookie->data, cookie->len); + + return true; +} + +static inline bool +svcxdr_decode_owner(struct xdr_stream *xdr, struct xdr_netobj *obj) +{ + __be32 *p; + u32 len; + + if (xdr_stream_decode_u32(xdr, &len) < 0) + return false; + if (len > XDR_MAX_NETOBJ) + return false; + p = xdr_inline_decode(xdr, len); + if (!p) + return false; + obj->len = len; + obj->data = (u8 *)p; + + return true; +} + +static inline bool +svcxdr_encode_owner(struct xdr_stream *xdr, const struct xdr_netobj *obj) +{ + unsigned int quadlen = XDR_QUADLEN(obj->len); + __be32 *p; + + if (xdr_stream_encode_u32(xdr, obj->len) < 0) + return false; + p = xdr_reserve_space(xdr, obj->len); + if (!p) + return false; + p[quadlen - 1] = 0; /* XDR pad */ + memcpy(p, obj->data, obj->len); + + return true; +} + +#endif /* _LOCKD_SVCXDR_H_ */