From patchwork Fri Jan 10 22:34:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11328563 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1D4F0921 for ; Fri, 10 Jan 2020 22:35:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F0102205F4 for ; Fri, 10 Jan 2020 22:35:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nSe4Jgsu" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727460AbgAJWfA (ORCPT ); Fri, 10 Jan 2020 17:35:00 -0500 Received: from mail-yb1-f194.google.com ([209.85.219.194]:46522 "EHLO mail-yb1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727324AbgAJWfA (ORCPT ); Fri, 10 Jan 2020 17:35:00 -0500 Received: by mail-yb1-f194.google.com with SMTP id k128so1356728ybc.13 for ; Fri, 10 Jan 2020 14:34:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=exiG3GqNe0eX6JhDS66gE2pn/HyCAzCxwXkZUXHpG1M=; b=nSe4JgsuxjJ3p9Ki7VFOMLhC5pOqRFAX6LkG1a1ZIeYbfOKuLdNmuxj0fjlQ2nBCO/ PoFZ04+9kTloPV/QaKX1Qgb2bI4PiMX/WiMTZg4niXAsm2/iT+SveCE23GpV/HQbfHY3 ODQ9aLFaRw+Yp/o8AVkg9FB685+AKg32slV0tyjHR9KZQepXqPIE4ayZ341Wn2xzkcdn FH+inWEFMOQ7hqNOlyMH/AWAIpD4qXCpTwKrPE3ggY6ZTCUmRJFFHZ01pwUGzGFgDTjF igee0bKO69Lsd9h1iTskW6vsPV+LKzrms9/sd4fNiTaCIEhpG0N7cBBbjInrTG/lYiVZ Cv6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=exiG3GqNe0eX6JhDS66gE2pn/HyCAzCxwXkZUXHpG1M=; b=o0Nu7B54abCMeEdscVa2UHv5MD0NYil/7tQULQAFk38DOBbOf+B5Pnbs7v0w3OabQm XCe2rl73m+KEQmZes5V/icGIUVD867jwniwaq4udOtlRILuZArMCdg1XwUCEyK9VqgFX Pdx6O+G3d6Gp31YIvNzghLoCWX/qJ9t85XcZmftl1kczl8M+U3xEyIZ51JU9+6q28uGL JF7LrjOAMsUyq3VXCAui1WqRv5sNQQNybq6I29hHVtAcMk/u0DgMxzRVaw/HB/4RZUiS KGvp9QG2ekIFYyzb2YqQsAGSkoYcQ25UVahID/ep+8RBVIHKBAwLMYYU+d6oayJwdzaQ Goyg== X-Gm-Message-State: APjAAAVgkamZvon0rUW5oV5W7hUamCof2ozZirQAATFmGu+A3Qc7r0nZ QByURT1nTur5cKGM5+rKb0W59rSL7VQ= X-Google-Smtp-Source: APXvYqz99d8nToN/6SWau6T1gIZcN9suDKZ/f40dWdhsd49p7fsbE93G6x0LhCgNQPL+VOkqoFhfEg== X-Received: by 2002:a25:b9d2:: with SMTP id y18mr4542500ybj.202.1578695699244; Fri, 10 Jan 2020 14:34:59 -0800 (PST) Received: from gouda.nowheycreamery.com (c-68-32-74-190.hsd1.mi.comcast.net. [68.32.74.190]) by smtp.gmail.com with ESMTPSA id e186sm1554060ywb.73.2020.01.10.14.34.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jan 2020 14:34:58 -0800 (PST) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: Trond.Myklebust@hammerspace.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH 1/7] SUNRPC: Split out a function for setting current page Date: Fri, 10 Jan 2020 17:34:49 -0500 Message-Id: <20200110223455.528471-2-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200110223455.528471-1-Anna.Schumaker@Netapp.com> References: <20200110223455.528471-1-Anna.Schumaker@Netapp.com> MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Anna Schumaker I'm going to need this bit of code in a few places for READ_PLUS decoding, so let's make it a helper function. Signed-off-by: Anna Schumaker --- net/sunrpc/xdr.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index e5497dc2475b..8bed0ec21563 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -825,6 +825,12 @@ static int xdr_set_page_base(struct xdr_stream *xdr, return 0; } +static void xdr_set_page(struct xdr_stream *xdr, unsigned int base) +{ + if (xdr_set_page_base(xdr, base, PAGE_SIZE) < 0) + xdr_set_iov(xdr, xdr->buf->tail, xdr->nwords << 2); +} + static void xdr_set_next_page(struct xdr_stream *xdr) { unsigned int newbase; @@ -832,8 +838,7 @@ static void xdr_set_next_page(struct xdr_stream *xdr) newbase = (1 + xdr->page_ptr - xdr->buf->pages) << PAGE_SHIFT; newbase -= xdr->buf->page_base; - if (xdr_set_page_base(xdr, newbase, PAGE_SIZE) < 0) - xdr_set_iov(xdr, xdr->buf->tail, xdr->nwords << 2); + xdr_set_page(xdr, newbase); } static bool xdr_set_next_buffer(struct xdr_stream *xdr) From patchwork Fri Jan 10 22:34:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11328565 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AE950921 for ; Fri, 10 Jan 2020 22:35:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 83DCC20721 for ; Fri, 10 Jan 2020 22:35:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="DSWeMBhh" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727482AbgAJWfC (ORCPT ); Fri, 10 Jan 2020 17:35:02 -0500 Received: from mail-yb1-f195.google.com ([209.85.219.195]:33486 "EHLO mail-yb1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727324AbgAJWfB (ORCPT ); Fri, 10 Jan 2020 17:35:01 -0500 Received: by mail-yb1-f195.google.com with SMTP id n66so1384776ybg.0 for ; Fri, 10 Jan 2020 14:35:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=57QAqPf0t/LbTmyzGx9rgDaeNch3OArcCT1NgmNT0Xw=; b=DSWeMBhho7szGs9YHfbq0xDtFWFKx+3hhuDDa2y6n6nvF2SDp/fv4zhjNrfth8JCFH ZlrI8ov1z5J4K8H3fJc4sA9oVPfnnZJ3HVDhJOmMtCeAsFB5OlHlkx5eYe58Bzkh2HKn 6uCluSl0nR6QVmWEt25LjJ6kASDnvkoQlFRgbCK4qiJwOg1aRcvpLYPmXEttlUojL2YP Vmiv421ogrrsNqddnaw40RzjE+qDGaZWeKE08ODQM38rje6E25iIlnFyEh7KyiLlmQBw /nllE9fEK/5LUX4JaAwYt8BPxyuaNOrtP8YTpPfbofIWdp7CU2zd1qXay89vclDJRkIc XNvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=57QAqPf0t/LbTmyzGx9rgDaeNch3OArcCT1NgmNT0Xw=; b=EVhUuslQZbYDDc9WPQJJao9YRd0gmE65YgSD7weTUzexxpWVSypwQcsP0jQU6w2XiH hHLhVd3mx3TulyxBddDz3iPF0shXIMVMfeAU3q04/FpeWfMFI1XXrTTvDtkonWEzVYsI YXbGAVj+22QumVseeZtS2yPpW4+/hQ61aXtK1+2wuhDbwCRoB3spMC7oryQ62ddvBCmy mcQZ7mv7xe9FSR4TJu087F+Ok4142MPalh0uZ9AFbGwDXQx72GWnGvisvGSRg3qi6T4o Wk/Uld6mepadxhmVkMpnit7px/cuFh/zv7+YY5kKCr1oYFwbgaXW8ai9N1JALHwo7l7w tsMg== X-Gm-Message-State: APjAAAUFTKKIUbz5m/T+uREP/oncbaoxXArv9rZat4Zead8SXp0xkOEG aOChBaO0edvI0jjXFg0H0iQ= X-Google-Smtp-Source: APXvYqxTvXuNyfSxQ3fVB5D2P+ZKaKPFzwKRWgOnPLzHFXA2/xXW7ow3zDrckdrxi83f42SMgseYvA== X-Received: by 2002:a25:6f02:: with SMTP id k2mr4238426ybc.254.1578695700479; Fri, 10 Jan 2020 14:35:00 -0800 (PST) Received: from gouda.nowheycreamery.com (c-68-32-74-190.hsd1.mi.comcast.net. [68.32.74.190]) by smtp.gmail.com with ESMTPSA id e186sm1554060ywb.73.2020.01.10.14.34.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jan 2020 14:34:59 -0800 (PST) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: Trond.Myklebust@hammerspace.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH 2/7] SUNRPC: Add the ability to expand holes in data pages Date: Fri, 10 Jan 2020 17:34:50 -0500 Message-Id: <20200110223455.528471-3-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200110223455.528471-1-Anna.Schumaker@Netapp.com> References: <20200110223455.528471-1-Anna.Schumaker@Netapp.com> MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Anna Schumaker This patch adds the ability to "read a hole" into a set of XDR data pages by taking the following steps: 1) Shift all data after the current xdr->p to the right, possibly into the tail, 2) Zero the specified range, and 3) Update xdr->p to point beyond the hole. Signed-off-by: Anna Schumaker --- include/linux/sunrpc/xdr.h | 1 + net/sunrpc/xdr.c | 100 +++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index b41f34977995..81a79099ed3b 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -263,6 +263,7 @@ extern __be32 *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes); extern unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len); extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len); extern int xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, int (*actor)(struct scatterlist *, void *), void *data); +extern size_t xdr_expand_hole(struct xdr_stream *, size_t, uint64_t); /** * xdr_stream_remaining - Return the number of bytes remaining in the stream diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 8bed0ec21563..bc9b9b0945f5 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -266,6 +266,40 @@ _shift_data_right_pages(struct page **pages, size_t pgto_base, } while ((len -= copy) != 0); } +static void +_shift_data_right_tail(struct xdr_buf *buf, size_t pgfrom_base, size_t len) +{ + struct kvec *tail = buf->tail; + + /* Make room for new data. */ + if (tail->iov_len > 0) + memmove((char *)tail->iov_base + len, tail->iov_base, len); + + _copy_from_pages((char *)tail->iov_base, + buf->pages, + buf->page_base + pgfrom_base, + len); + + tail->iov_len += len; +} + +static void +_shift_data_right(struct xdr_buf *buf, size_t to, size_t from, size_t len) +{ + size_t shift = len; + + if ((to + len) > buf->page_len) { + shift = (to + len) - buf->page_len; + _shift_data_right_tail(buf, (from + len) - shift, shift); + shift = len - shift; + } + + _shift_data_right_pages(buf->pages, + buf->page_base + to, + buf->page_base + from, + shift); +} + /** * _copy_to_pages * @pages: array of pages @@ -350,6 +384,33 @@ _copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len) } EXPORT_SYMBOL_GPL(_copy_from_pages); +/** + * _zero_data_pages + * @pages: array of pages + * @pgbase: beginning page vector address + * @len: length + */ +static void +_zero_data_pages(struct page **pages, size_t pgbase, size_t len) +{ + struct page **page; + size_t zero; + + page = pages + (pgbase >> PAGE_SHIFT); + pgbase &= ~PAGE_MASK; + + do { + zero = len; + if (pgbase + zero > PAGE_SIZE) + zero = PAGE_SIZE - pgbase; + + zero_user_segment(*page, pgbase, pgbase + zero); + page++; + pgbase = 0; + + } while ((len -= zero) != 0); +} + /** * xdr_shrink_bufhead * @buf: xdr_buf @@ -505,6 +566,24 @@ unsigned int xdr_stream_pos(const struct xdr_stream *xdr) } EXPORT_SYMBOL_GPL(xdr_stream_pos); +/** + * xdr_page_pos - Return the current offset from the start of the xdr->buf->pages + * @xdr: pointer to struct xdr_stream + */ +static size_t xdr_page_pos(const struct xdr_stream *xdr) +{ + unsigned int offset; + unsigned int base = xdr->buf->page_len; + void *kaddr = xdr->buf->tail->iov_base;; + + if (xdr->page_ptr) { + base = (xdr->page_ptr - xdr->buf->pages) * PAGE_SIZE; + kaddr = page_address(*xdr->page_ptr); + } + offset = xdr->p - (__be32 *)kaddr; + return base + (offset * sizeof(__be32)); +} + /** * xdr_init_encode - Initialize a struct xdr_stream for sending data. * @xdr: pointer to xdr_stream struct @@ -1062,6 +1141,27 @@ unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len) } EXPORT_SYMBOL_GPL(xdr_read_pages); +size_t xdr_expand_hole(struct xdr_stream *xdr, size_t offset, uint64_t length) +{ + struct xdr_buf *buf = xdr->buf; + size_t from = 0; + + if ((offset + length) < offset || + (offset + length) > buf->page_len) + length = buf->page_len - offset; + + if (offset == 0) + xdr_align_pages(xdr, xdr->nwords << 2); + else + from = xdr_page_pos(xdr); + + _shift_data_right(buf, offset + length, from, xdr->nwords << 2); + _zero_data_pages(buf->pages, buf->page_base + offset, length); + xdr_set_page(xdr, offset + length); + return length; +} +EXPORT_SYMBOL_GPL(xdr_expand_hole); + /** * xdr_enter_page - decode data from the XDR page * @xdr: pointer to xdr_stream struct From patchwork Fri Jan 10 22:34:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11328567 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DA4F492A for ; Fri, 10 Jan 2020 22:35:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id AFC8820721 for ; Fri, 10 Jan 2020 22:35:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Vs0q/JcH" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727483AbgAJWfD (ORCPT ); Fri, 10 Jan 2020 17:35:03 -0500 Received: from mail-yb1-f194.google.com ([209.85.219.194]:40045 "EHLO mail-yb1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727324AbgAJWfD (ORCPT ); Fri, 10 Jan 2020 17:35:03 -0500 Received: by mail-yb1-f194.google.com with SMTP id a2so1369977ybr.7 for ; Fri, 10 Jan 2020 14:35:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=bJAMBzd0CbZgEWxhF4EyEF9/gedk9FYBS1Ahvh4ZpUQ=; b=Vs0q/JcHPVt2YUTrvyHD3pyxbm3Bj2yuZdSlm5VdcoR1bIOQSLfIt8ghOvN+SByxoK EP58eaiZmJY+948U95B1y9uiyB6EQztzSt2VI0ZVOoeYjj28MWb9GVHSMnc2BnUGpNT0 /bLa7Bj5W86h4FeCMzzpBNiGjMHPiExDtPcSP9s3kIg1trZbONayrE5GgzV4q+ax7nyK t1gBfLVJjGqPlXPoS4kocz1qG6cNJvRY9cXZyJU8NWJsEA07NX5PGp7/FKckkflWuCcr wYVZNvoPhBsFYHn4SkSj6foeDuE8agXLuzIvwd9k+rNBeJB6QEbW9M2EmSX8bA+UCc2H VEOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=bJAMBzd0CbZgEWxhF4EyEF9/gedk9FYBS1Ahvh4ZpUQ=; b=Jkq231dc6Qna4BuhUm71qjZBwXavYZULj0NnEci0gvbtGgTY7y60zsTEXX9x2jKzBH 7ETlafivyc76bMq+uO18PoW1bK9ke/MKhyOth2fKjje2y4sf/u5qVhFAh7Xr2193QJWz z799xQAKrUBPnGY4LzC3LVUgwnwcAZRcaGWbBSyXpntpRLDdQA87VrzcZANbcXYobqTL 6Qk1HM6YpU5iP3UC9OzPlQPblLYIuEUyZCSk78+XMmVJo4xzeP5yGkjWg5XWbqhMQDqv pFWShJlEBhWdD9sEFBO7RtONEb2sFSPNkXrhGzmEN9bNPGa6tlO2WpXCkSj2T1Zu4fh6 UTUg== X-Gm-Message-State: APjAAAU18Ccbds+y1nEc1SRTBVbLkFwq57GDkV9fh8v/DqL81bXKvpJw e6aocA5wLbqYTYjQzL0Pkvk= X-Google-Smtp-Source: APXvYqxc16Kg/oHPk6WI6Umi10q1bhZO4PTV76znoCJtRnNSY1o8RMlYQ0E6Lns5eac/0cQQZ7aWsA== X-Received: by 2002:a25:dcc8:: with SMTP id y191mr3298837ybe.103.1578695701938; Fri, 10 Jan 2020 14:35:01 -0800 (PST) Received: from gouda.nowheycreamery.com (c-68-32-74-190.hsd1.mi.comcast.net. [68.32.74.190]) by smtp.gmail.com with ESMTPSA id e186sm1554060ywb.73.2020.01.10.14.35.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jan 2020 14:35:00 -0800 (PST) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: Trond.Myklebust@hammerspace.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH 3/7] SUNRPC: Add the ability to shift data to a specific offset Date: Fri, 10 Jan 2020 17:34:51 -0500 Message-Id: <20200110223455.528471-4-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200110223455.528471-1-Anna.Schumaker@Netapp.com> References: <20200110223455.528471-1-Anna.Schumaker@Netapp.com> MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Anna Schumaker Expanding holes tends to put the data content a few bytes to the right of where we want it. This patch implements a left-shift operation to line everything up properly. Signed-off-by: Anna Schumaker --- include/linux/sunrpc/xdr.h | 1 + net/sunrpc/xdr.c | 135 +++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 81a79099ed3b..90abf732c8ee 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -264,6 +264,7 @@ extern unsigned int xdr_read_pages(struct xdr_stream *xdr, unsigned int len); extern void xdr_enter_page(struct xdr_stream *xdr, unsigned int len); extern int xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, int (*actor)(struct scatterlist *, void *), void *data); extern size_t xdr_expand_hole(struct xdr_stream *, size_t, uint64_t); +extern uint64_t xdr_align_data(struct xdr_stream *, uint64_t, uint64_t); /** * xdr_stream_remaining - Return the number of bytes remaining in the stream diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index bc9b9b0945f5..a857c2308ee1 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -19,6 +19,9 @@ #include #include +static void _copy_to_pages(struct page **, size_t, const char *, size_t); + + /* * XDR functions for basic NFS types */ @@ -300,6 +303,117 @@ _shift_data_right(struct xdr_buf *buf, size_t to, size_t from, size_t len) shift); } + +/** + * _shift_data_left_pages + * @pages: vector of pages containing both the source and dest memory area. + * @pgto_base: page vector address of destination + * @pgfrom_base: page vector address of source + * @len: number of bytes to copy + * + * Note: the addresses pgto_base and pgfrom_base are both calculated in + * the same way: + * if a memory area starts at byte 'base' in page 'pages[i]', + * then its address is given as (i << PAGE_CACHE_SHIFT) + base + * Alse note: pgto_base must be < pgfrom_base, but the memory areas + * they point to may overlap. + */ +static void +_shift_data_left_pages(struct page **pages, size_t pgto_base, + size_t pgfrom_base, size_t len) +{ + struct page **pgfrom, **pgto; + char *vfrom, *vto; + size_t copy; + + BUG_ON(pgfrom_base <= pgto_base); + + pgto = pages + (pgto_base >> PAGE_SHIFT); + pgfrom = pages + (pgfrom_base >> PAGE_SHIFT); + + pgto_base = pgto_base % PAGE_SIZE; + pgfrom_base = pgfrom_base % PAGE_SIZE; + + do { + if (pgto_base >= PAGE_SIZE) { + pgto_base = 0; + pgto++; + } + if (pgfrom_base >= PAGE_SIZE){ + pgfrom_base = 0; + pgfrom++; + } + + copy = len; + if (copy > (PAGE_SIZE - pgto_base)) + copy = PAGE_SIZE - pgto_base; + if (copy > (PAGE_SIZE - pgfrom_base)) + copy = PAGE_SIZE - pgfrom_base; + + if (pgto_base == 131056) + break; + + vto = kmap_atomic(*pgto); + if (*pgto != *pgfrom) { + vfrom = kmap_atomic(*pgfrom); + memcpy(vto + pgto_base, vfrom + pgfrom_base, copy); + kunmap_atomic(vfrom); + } else + memmove(vto + pgto_base, vto + pgfrom_base, copy); + flush_dcache_page(*pgto); + kunmap_atomic(vto); + + pgto_base += copy; + pgfrom_base += copy; + + } while ((len -= copy) != 0); +} + +static void +_shift_data_left_tail(struct xdr_buf *buf, size_t pgto_base, + size_t tail_from, size_t len) +{ + struct kvec *tail = buf->tail; + size_t shift = len; + + if (len == 0) + return; + if (pgto_base + len > buf->page_len) + shift = buf->page_len - pgto_base; + + _copy_to_pages(buf->pages, + buf->page_base + pgto_base, + (char *)(tail->iov_base + tail_from), + shift); + + memmove((char *)tail->iov_base, tail->iov_base + tail_from + shift, shift); + tail->iov_len -= (tail_from + shift); +} + +static void +_shift_data_left(struct xdr_buf *buf, size_t to, size_t from, size_t len) +{ + size_t shift = len; + + if (from < buf->page_len) { + shift = min(len, buf->page_len - from); + _shift_data_left_pages(buf->pages, + buf->page_base + to, + buf->page_base + from, + shift); + to += shift; + from += shift; + shift = len - shift; + } + + if (shift == 0) + return; + if (from >= buf->page_len) + from -= buf->page_len; + + _shift_data_left_tail(buf, to, from, shift); +} + /** * _copy_to_pages * @pages: array of pages @@ -1162,6 +1276,27 @@ size_t xdr_expand_hole(struct xdr_stream *xdr, size_t offset, uint64_t length) } EXPORT_SYMBOL_GPL(xdr_expand_hole); +uint64_t xdr_align_data(struct xdr_stream *xdr, uint64_t offset, uint64_t length) +{ + struct xdr_buf *buf = xdr->buf; + size_t from = offset; + + if (offset + length > buf->page_len) + length = buf->page_len - offset; + + if (offset == 0) + xdr_align_pages(xdr, xdr->nwords << 2); + else { + from = xdr_page_pos(xdr); + _shift_data_left(buf, offset, from, length); + } + + xdr->nwords -= XDR_QUADLEN(length); + xdr_set_page(xdr, from + length); + return length; +} +EXPORT_SYMBOL_GPL(xdr_align_data); + /** * xdr_enter_page - decode data from the XDR page * @xdr: pointer to xdr_stream struct From patchwork Fri Jan 10 22:34:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11328569 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 80FA192A for ; Fri, 10 Jan 2020 22:35:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4B7DD205F4 for ; Fri, 10 Jan 2020 22:35:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BD+jnSrd" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727498AbgAJWfE (ORCPT ); Fri, 10 Jan 2020 17:35:04 -0500 Received: from mail-yb1-f195.google.com ([209.85.219.195]:43486 "EHLO mail-yb1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727324AbgAJWfE (ORCPT ); Fri, 10 Jan 2020 17:35:04 -0500 Received: by mail-yb1-f195.google.com with SMTP id k15so1364161ybd.10 for ; Fri, 10 Jan 2020 14:35:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=GM5cMLAYCKLLf03Bx3+eVSBKiQ2Gvg30E0s6QeTT/nk=; b=BD+jnSrd3JJklOvAKEikUtxnkXYJHwy2cveXEvW04UlZJAiOIFyEJOwblRuiR5N8l1 oEn2uUymusQFdS7pCt8OQGcXJOJZZXsfjG55Kl0BWQ7rpm+h7YI4IvtoK5TZ5veDlVNU 6QHZhAFdUWNgj3sy6YaRpevaWdVwQHrD5DyFL3B+AjzCjJX6RMn6e1au/DTTJXRnqSdS sFVVff6MtFFaXX2jaqmesy94dwFdFCLYsDkuJTgch3AzSumGfVShktvtu/tQDc3rveN9 wUlpR5Kx7c4dPZDH/hAgkakmHQ4GbAdzgkb5EvOAqCLC0L21KQrK/eq9gBXXIi6dgvPf GmEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=GM5cMLAYCKLLf03Bx3+eVSBKiQ2Gvg30E0s6QeTT/nk=; b=fDLwARl79KgX9RDBamWLhSRTzV54YqVDa6GvQarPN37m6/JJ+IboXAB0CEmC9GPNBj gglHiAkLl7jrkxypgLR43YxGlM2FBGgk4Ai67Wa+9UNKC15Z5DcWxqeHZw8eoL2nWAij I0xekoRhU9hguNtzI8KYTazmxrTaelBUMupz9EOAhtcrRcB27kpvzly7UrtP0/SraxHA LkbqtdZiHSh48WUkxU4wzvZVYp9Z9BDz/qrYjWmFWcKS8BrDySdgEwaOI8xUreBKk2SD oIa3LbvZYAX3BRBlDAR455tzF+9iaPLNGOt2h4MqxoU9atwkK8DQbPh+bw6+rUFz85Ab mQuQ== X-Gm-Message-State: APjAAAXDKr1DYOKGh5ssLUI2wmn2DKDuTR1SyGwx3mPfn4qbVX3NtHzf gx5+ccDDyuwOi3XUAkqtaLw= X-Google-Smtp-Source: APXvYqxfNy66Oe8OKHuMkPUKIu5MMp+/G/gbSu4OUkJ7IlIa6z+4YYCs7elaFcH9IOvRd94vZ7mZAg== X-Received: by 2002:a25:ba09:: with SMTP id t9mr667836ybg.207.1578695703077; Fri, 10 Jan 2020 14:35:03 -0800 (PST) Received: from gouda.nowheycreamery.com (c-68-32-74-190.hsd1.mi.comcast.net. [68.32.74.190]) by smtp.gmail.com with ESMTPSA id e186sm1554060ywb.73.2020.01.10.14.35.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jan 2020 14:35:02 -0800 (PST) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: Trond.Myklebust@hammerspace.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH 4/7] NFS: Add READ_PLUS data segment support Date: Fri, 10 Jan 2020 17:34:52 -0500 Message-Id: <20200110223455.528471-5-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200110223455.528471-1-Anna.Schumaker@Netapp.com> References: <20200110223455.528471-1-Anna.Schumaker@Netapp.com> MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Anna Schumaker This patch adds client support for decoding a single NFS4_CONTENT_DATA segment returned by the server. This is the simplest implementation possible, since it does not account for any hole segments in the reply. Signed-off-by: Anna Schumaker --- fs/nfs/nfs42xdr.c | 138 ++++++++++++++++++++++++++++++++++++++ fs/nfs/nfs4proc.c | 32 ++++++++- fs/nfs/nfs4xdr.c | 1 + include/linux/nfs4.h | 2 +- include/linux/nfs_fs_sb.h | 1 + include/linux/nfs_xdr.h | 2 +- 6 files changed, 171 insertions(+), 5 deletions(-) diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c index c03f3246d6c5..bf118ecabe2c 100644 --- a/fs/nfs/nfs42xdr.c +++ b/fs/nfs/nfs42xdr.c @@ -45,6 +45,15 @@ #define encode_deallocate_maxsz (op_encode_hdr_maxsz + \ encode_fallocate_maxsz) #define decode_deallocate_maxsz (op_decode_hdr_maxsz) +#define encode_read_plus_maxsz (op_encode_hdr_maxsz + \ + encode_stateid_maxsz + 3) +#define NFS42_READ_PLUS_SEGMENT_SIZE (1 /* data_content4 */ + \ + 2 /* data_info4.di_offset */ + \ + 2 /* data_info4.di_length */) +#define decode_read_plus_maxsz (op_decode_hdr_maxsz + \ + 1 /* rpr_eof */ + \ + 1 /* rpr_contents count */ + \ + NFS42_READ_PLUS_SEGMENT_SIZE) #define encode_seek_maxsz (op_encode_hdr_maxsz + \ encode_stateid_maxsz + \ 2 /* offset */ + \ @@ -128,6 +137,14 @@ decode_putfh_maxsz + \ decode_deallocate_maxsz + \ decode_getattr_maxsz) +#define NFS4_enc_read_plus_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ + encode_putfh_maxsz + \ + encode_read_plus_maxsz) +#define NFS4_dec_read_plus_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ + decode_putfh_maxsz + \ + decode_read_plus_maxsz) #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \ encode_sequence_maxsz + \ encode_putfh_maxsz + \ @@ -252,6 +269,16 @@ static void encode_deallocate(struct xdr_stream *xdr, encode_fallocate(xdr, args); } +static void encode_read_plus(struct xdr_stream *xdr, + const struct nfs_pgio_args *args, + struct compound_hdr *hdr) +{ + encode_op_hdr(xdr, OP_READ_PLUS, decode_read_plus_maxsz, hdr); + encode_nfs4_stateid(xdr, &args->stateid); + encode_uint64(xdr, args->offset); + encode_uint32(xdr, args->count); +} + static void encode_seek(struct xdr_stream *xdr, const struct nfs42_seek_args *args, struct compound_hdr *hdr) @@ -446,6 +473,29 @@ static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req, encode_nops(&hdr); } +/* + * Encode READ_PLUS request + */ +static void nfs4_xdr_enc_read_plus(struct rpc_rqst *req, + struct xdr_stream *xdr, + const void *data) +{ + const struct nfs_pgio_args *args = data; + struct compound_hdr hdr = { + .minorversion = nfs4_xdr_minorversion(&args->seq_args), + }; + + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_read_plus(xdr, args, &hdr); + + rpc_prepare_reply_pages(req, args->pages, args->pgbase, + args->count, hdr.replen); + req->rq_rcv_buf.flags |= XDRBUF_READ; + encode_nops(&hdr); +} + /* * Encode SEEK request */ @@ -694,6 +744,67 @@ static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *re return decode_op_hdr(xdr, OP_DEALLOCATE); } +static uint32_t decode_read_plus_data(struct xdr_stream *xdr, struct nfs_pgio_res *res, + uint32_t *eof) +{ + __be32 *p; + uint32_t count, recvd; + uint64_t offset; + + p = xdr_inline_decode(xdr, 8 + 4); + if (unlikely(!p)) + return -EIO; + + p = xdr_decode_hyper(p, &offset); + count = be32_to_cpup(p); + if (count == 0) + return 0; + + recvd = xdr_read_pages(xdr, count); + if (count > recvd) { + dprintk("NFS: server cheating in read reply: " + "count %u > recvd %u\n", count, recvd); + count = recvd; + *eof = 0; + } + + return count; +} + +static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res) +{ + __be32 *p; + uint32_t count, eof, segments, type; + int status; + + status = decode_op_hdr(xdr, OP_READ_PLUS); + if (status) + return status; + + p = xdr_inline_decode(xdr, 4 + 4); + if (unlikely(!p)) + return -EIO; + + eof = be32_to_cpup(p++); + segments = be32_to_cpup(p++); + if (segments == 0) + return 0; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) + return -EIO; + + type = be32_to_cpup(p++); + if (type == NFS4_CONTENT_DATA) + count = decode_read_plus_data(xdr, res, &eof); + else + return -EINVAL; + + res->eof = eof; + res->count = count; + return 0; +} + static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) { int status; @@ -870,6 +981,33 @@ static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp, return status; } +/* + * Decode READ_PLUS request + */ +static int nfs4_xdr_dec_read_plus(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + void *data) +{ + struct nfs_pgio_res *res = data; + struct compound_hdr hdr; + int status; + + status = decode_compound_hdr(xdr, &hdr); + if (status) + goto out; + status = decode_sequence(xdr, &res->seq_res, rqstp); + if (status) + goto out; + status = decode_putfh(xdr); + if (status) + goto out; + status = decode_read_plus(xdr, res); + if (!status) + status = res->count; +out: + return status; +} + /* * Decode SEEK request */ diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 64bbb0d0ff5a..60b1ec684751 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -69,6 +69,10 @@ #include "nfs4trace.h" +#ifdef CONFIG_NFS_V4_2 +#include "nfs42.h" +#endif /* CONFIG_NFS_V4_2 */ + #define NFSDBG_FACILITY NFSDBG_PROC #define NFS4_BITMASK_SZ 3 @@ -5195,9 +5199,15 @@ static bool nfs4_read_stateid_changed(struct rpc_task *task, static int nfs4_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr) { - + struct nfs_server *server = NFS_SERVER(hdr->inode); dprintk("--> %s\n", __func__); + if ((server->caps & NFS_CAP_READ_PLUS) && (task->tk_status == -ENOTSUPP)) { + server->caps &= ~NFS_CAP_READ_PLUS; + if (rpc_restart_call_prepare(task)) + task->tk_status = 0; + return -EAGAIN; + } if (!nfs4_sequence_done(task, &hdr->res.seq_res)) return -EAGAIN; if (nfs4_read_stateid_changed(task, &hdr->args)) @@ -5208,13 +5218,28 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr) nfs4_read_done_cb(task, hdr); } +#ifdef CONFIG_NFS_V4_2 +static void nfs42_read_plus_support(struct nfs_server *server, struct rpc_message *msg) +{ + if (server->caps & NFS_CAP_READ_PLUS) + msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ_PLUS]; + else + msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ]; +} +#else +static void nfs42_read_plus_support(struct nfs_server *server, struct rpc_message *msg) +{ + msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ]; +} +#endif /* CONFIG_NFS_V4_2 */ + static void nfs4_proc_read_setup(struct nfs_pgio_header *hdr, struct rpc_message *msg) { hdr->timestamp = jiffies; if (!hdr->pgio_done_cb) hdr->pgio_done_cb = nfs4_read_done_cb; - msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ]; + nfs42_read_plus_support(NFS_SERVER(hdr->inode), msg); nfs4_init_sequence(&hdr->args.seq_args, &hdr->res.seq_res, 0, 0); } @@ -9957,7 +9982,8 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = { | NFS_CAP_SEEK | NFS_CAP_LAYOUTSTATS | NFS_CAP_CLONE - | NFS_CAP_LAYOUTERROR, + | NFS_CAP_LAYOUTERROR + | NFS_CAP_READ_PLUS, .init_client = nfs41_init_client, .shutdown_client = nfs41_shutdown_client, .match_stateid = nfs41_match_stateid, diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 02890606e14a..dd81c9ddd0fb 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -7593,6 +7593,7 @@ const struct rpc_procinfo nfs4_procedures[] = { PROC42(COPY_NOTIFY, enc_copy_notify, dec_copy_notify), PROC(LOOKUPP, enc_lookupp, dec_lookupp), PROC42(LAYOUTERROR, enc_layouterror, dec_layouterror), + PROC42(READ_PLUS, enc_read_plus, dec_read_plus), }; static unsigned int nfs_version4_counts[ARRAY_SIZE(nfs4_procedures)]; diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 82d8fb422092..c1eeef52545c 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -540,8 +540,8 @@ enum { NFSPROC4_CLNT_LOOKUPP, NFSPROC4_CLNT_LAYOUTERROR, - NFSPROC4_CLNT_COPY_NOTIFY, + NFSPROC4_CLNT_READ_PLUS, }; /* nfs41 types */ diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 465fa98258a3..11248c5a7b24 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -281,5 +281,6 @@ struct nfs_server { #define NFS_CAP_OFFLOAD_CANCEL (1U << 25) #define NFS_CAP_LAYOUTERROR (1U << 26) #define NFS_CAP_COPY_NOTIFY (1U << 27) +#define NFS_CAP_READ_PLUS (1U << 28) #endif diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index bb8652792b84..412297a10878 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -655,7 +655,7 @@ struct nfs_pgio_args { struct nfs_pgio_res { struct nfs4_sequence_res seq_res; struct nfs_fattr * fattr; - __u32 count; + __u64 count; __u32 op_status; union { struct { From patchwork Fri Jan 10 22:34:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11328571 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EF139921 for ; Fri, 10 Jan 2020 22:35:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CDD37205F4 for ; Fri, 10 Jan 2020 22:35:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="TUzLeLgD" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727324AbgAJWfF (ORCPT ); Fri, 10 Jan 2020 17:35:05 -0500 Received: from mail-yw1-f65.google.com ([209.85.161.65]:40909 "EHLO mail-yw1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727393AbgAJWfF (ORCPT ); Fri, 10 Jan 2020 17:35:05 -0500 Received: by mail-yw1-f65.google.com with SMTP id i126so1318386ywe.7 for ; Fri, 10 Jan 2020 14:35:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9DOB6QLf1qY1K4DKpSX2YipNAr81v05rvCURJAx9vk4=; b=TUzLeLgDn5ZDyNNcVRZuWrdptQnS+dJbmptfBJml7kSsS2H0HkxzPOIxFjLnjneo3T dLe2Os/oDL3aBvHMDxy5Hq0p9345UGGYBwxB8sFqcdtcQOqAhDdaz2jNDxVVAHwmGkcK U0AmdOSSLA0TAhCkDa192pRFo6u2N6cXovZ8i6IvhbrE9a8/WqLkgFB2CN0VJmYsHv0n /li/f5DGZFaWPGcvw3OZqG0TyyVK9ODtwPFb6pT2N+z4C/b4Cb0kicWxcpdvH/l9fCgE r57ACrQTW2BNHGz0WQB1eEZqCa6kr+mlSaeGr4bec5x8IbOsy2m/+yt9EZcT1cPYt6EO Ya+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=9DOB6QLf1qY1K4DKpSX2YipNAr81v05rvCURJAx9vk4=; b=dji5IWWv4LMIaaR/JAuQp3pcoAYV29M1RlOX1xSQsPebJSI1OO24srnSlo9duKg7No cxB/IbDGyiW4xcBxLs+J4dSBJLxkwKmGA9EUlFKtFOitwm/jbotbmARlClGeISSmxJCZ xnT/jcDVD70qxxla59D9K8tXtW6j/chuek7t93cO4AXZwiKQ2BtdagOqqqbC+2xJ4Sbv kUKHfenOE482iFnluN+Zdw0q0EDe7deyzi4oyafw88JpileMNUPiqtUE6tjUnC9MGqWG VeVPETAdzKLWDcTN+AIq+Od6x2wCkMgN4IImHe40GVoEkYrTVgxyOac5ThuZOKvw85XE I43Q== X-Gm-Message-State: APjAAAVTcdk27hDlyL0f5mcz1WsxAxy6zWlNwh4OTfAA5X7L0gBSQnzo LYJeJk9IeG4I/RUvvHrgsT3SxCYb0mE= X-Google-Smtp-Source: APXvYqxIpgooEP48TqjkIVjlwGu+wQ1zYgTkzu//oamuRcYgtfQ9nq8EGqfhj2OXwVJa9XcEEpUKBw== X-Received: by 2002:a81:844f:: with SMTP id u76mr4357390ywf.99.1578695704276; Fri, 10 Jan 2020 14:35:04 -0800 (PST) Received: from gouda.nowheycreamery.com (c-68-32-74-190.hsd1.mi.comcast.net. [68.32.74.190]) by smtp.gmail.com with ESMTPSA id e186sm1554060ywb.73.2020.01.10.14.35.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jan 2020 14:35:03 -0800 (PST) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: Trond.Myklebust@hammerspace.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH 5/7] NFS: Add READ_PLUS hole segment decoding Date: Fri, 10 Jan 2020 17:34:53 -0500 Message-Id: <20200110223455.528471-6-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200110223455.528471-1-Anna.Schumaker@Netapp.com> References: <20200110223455.528471-1-Anna.Schumaker@Netapp.com> MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Anna Schumaker We keep things simple for now by only decoding a single hole or data segment returned by the server, even if they returned more to us. Signed-off-by: Anna Schumaker --- fs/nfs/nfs42xdr.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c index bf118ecabe2c..3407a3cf2e13 100644 --- a/fs/nfs/nfs42xdr.c +++ b/fs/nfs/nfs42xdr.c @@ -47,7 +47,7 @@ #define decode_deallocate_maxsz (op_decode_hdr_maxsz) #define encode_read_plus_maxsz (op_encode_hdr_maxsz + \ encode_stateid_maxsz + 3) -#define NFS42_READ_PLUS_SEGMENT_SIZE (1 /* data_content4 */ + \ +#define NFS42_READ_PLUS_SEGMENT_SIZE (2 /* data_content4 */ + \ 2 /* data_info4.di_offset */ + \ 2 /* data_info4.di_length */) #define decode_read_plus_maxsz (op_decode_hdr_maxsz + \ @@ -771,6 +771,31 @@ static uint32_t decode_read_plus_data(struct xdr_stream *xdr, struct nfs_pgio_re return count; } +static uint32_t decode_read_plus_hole(struct xdr_stream *xdr, struct nfs_pgio_res *res, + uint32_t *eof) +{ + __be32 *p; + uint64_t offset, length; + size_t recvd; + + p = xdr_inline_decode(xdr, 8 + 8); + if (unlikely(!p)) + return -EIO; + + p = xdr_decode_hyper(p, &offset); + p = xdr_decode_hyper(p, &length); + if (length == 0) + return 0; + + recvd = xdr_expand_hole(xdr, 0, length); + if (recvd < length) { + *eof = 0; + length = recvd; + } + + return length; +} + static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res) { __be32 *p; @@ -798,7 +823,10 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res) if (type == NFS4_CONTENT_DATA) count = decode_read_plus_data(xdr, res, &eof); else - return -EINVAL; + count = decode_read_plus_hole(xdr, res, &eof); + + if (segments > 1) + eof = 0; res->eof = eof; res->count = count; From patchwork Fri Jan 10 22:34:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11328573 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DF7E2921 for ; Fri, 10 Jan 2020 22:35:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BEE4420721 for ; Fri, 10 Jan 2020 22:35:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VgWzjS5K" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727439AbgAJWfH (ORCPT ); Fri, 10 Jan 2020 17:35:07 -0500 Received: from mail-yb1-f194.google.com ([209.85.219.194]:38896 "EHLO mail-yb1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727393AbgAJWfG (ORCPT ); Fri, 10 Jan 2020 17:35:06 -0500 Received: by mail-yb1-f194.google.com with SMTP id c13so1374033ybq.5 for ; Fri, 10 Jan 2020 14:35:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XxZxDJC1OGNPkdu6FTqfNdzC3MlEzliAiWbAbPd4MXM=; b=VgWzjS5KULN0A+3KyOgbU1q/PLC51PO4DKwwQIX8v8IoatwtoJeNaiD0ntCUF+Lj1d zdaTZWE8KHsMYeZCwIsooFM+4/CephsnQeKDABU7jGPa8i4pNhrnfOaQsjQla4PhpJQz ckLblEo9gm1x8rkPJbjWtH3xofZTx5FhcIGFPS9LeILZmxr72CEj4TFd8ZR93C6fdity 7W1MiscreUz0ohkCeJioPCf4Uf5LIjyMPzDuKNeFNDBuk8UbtYn5wxPkvktzsOsuHDBN ppuKQ6OSwuK68UiiX/1E6bLA0Ghzf2qNoY+xHM9a2U/p7RP3jR1m8dJRC3IWPCiNO+aG Cu1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=XxZxDJC1OGNPkdu6FTqfNdzC3MlEzliAiWbAbPd4MXM=; b=KEMQ6+/NCvdAY7bETL77eAWI0MWwJRT7juz2RUnjetiUd7tS+nO7Z2F9gP6fGq/f0O ieBmFk2tBh/sELBcbDhk0F9JPn7MjUtEoyL2mJR1oxqdWONLG2VZgGSLahNM7gJIRf8v e9NtpO70svAwEQnUtaYFWRrJVlfOUcLTkejQRG2LsJ4mnKJAhJENnaLUsJG887VdnyPp MMtgGS9TwjVBCCtOVADa3gxhzrP0DWzN0TpLWbbpKy0bJ68Xf8MxkXV85yQ3PH/U0rBd fBIHHQYSXzpNVpQpp5fxj24uJXtlY9NZAHhf8N/ODNCfFL2OObL3QmCRXfN4rnk3gNmg PqEQ== X-Gm-Message-State: APjAAAXt3cfPslilhHxhIFZZ8doquHP5GHJfBzMRPIPLYZ6+DNynmFYr EloXC1k6yNLXKh2K6nwM0oU= X-Google-Smtp-Source: APXvYqxlwCXWyjj5tqumtCIL+ajfYqastA8LfFP767LQrHojK9u8LUnMf9/xImqEOIgtKqtDMbdlgw== X-Received: by 2002:a25:50c6:: with SMTP id e189mr4572624ybb.472.1578695705880; Fri, 10 Jan 2020 14:35:05 -0800 (PST) Received: from gouda.nowheycreamery.com (c-68-32-74-190.hsd1.mi.comcast.net. [68.32.74.190]) by smtp.gmail.com with ESMTPSA id e186sm1554060ywb.73.2020.01.10.14.35.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jan 2020 14:35:05 -0800 (PST) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: Trond.Myklebust@hammerspace.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH 6/7] NFS: Decode multiple READ_PLUS segments Date: Fri, 10 Jan 2020 17:34:54 -0500 Message-Id: <20200110223455.528471-7-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200110223455.528471-1-Anna.Schumaker@Netapp.com> References: <20200110223455.528471-1-Anna.Schumaker@Netapp.com> MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Anna Schumaker We now have everything we need to read holes and shift data to where it's supposed to be. I switch over to using xdr_align_data() to put data segments in the proper place. Signed-off-by: Anna Schumaker --- fs/nfs/nfs42xdr.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c index 3407a3cf2e13..b5c638bcab66 100644 --- a/fs/nfs/nfs42xdr.c +++ b/fs/nfs/nfs42xdr.c @@ -53,7 +53,7 @@ #define decode_read_plus_maxsz (op_decode_hdr_maxsz + \ 1 /* rpr_eof */ + \ 1 /* rpr_contents count */ + \ - NFS42_READ_PLUS_SEGMENT_SIZE) + (2 * NFS42_READ_PLUS_SEGMENT_SIZE)) #define encode_seek_maxsz (op_encode_hdr_maxsz + \ encode_stateid_maxsz + \ 2 /* offset */ + \ @@ -745,7 +745,7 @@ static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *re } static uint32_t decode_read_plus_data(struct xdr_stream *xdr, struct nfs_pgio_res *res, - uint32_t *eof) + uint32_t *eof, uint64_t total) { __be32 *p; uint32_t count, recvd; @@ -760,7 +760,7 @@ static uint32_t decode_read_plus_data(struct xdr_stream *xdr, struct nfs_pgio_re if (count == 0) return 0; - recvd = xdr_read_pages(xdr, count); + recvd = xdr_align_data(xdr, total, count); if (count > recvd) { dprintk("NFS: server cheating in read reply: " "count %u > recvd %u\n", count, recvd); @@ -772,7 +772,7 @@ static uint32_t decode_read_plus_data(struct xdr_stream *xdr, struct nfs_pgio_re } static uint32_t decode_read_plus_hole(struct xdr_stream *xdr, struct nfs_pgio_res *res, - uint32_t *eof) + uint32_t *eof, uint64_t total) { __be32 *p; uint64_t offset, length; @@ -787,7 +787,7 @@ static uint32_t decode_read_plus_hole(struct xdr_stream *xdr, struct nfs_pgio_re if (length == 0) return 0; - recvd = xdr_expand_hole(xdr, 0, length); + recvd = xdr_expand_hole(xdr, total, length); if (recvd < length) { *eof = 0; length = recvd; @@ -799,8 +799,9 @@ static uint32_t decode_read_plus_hole(struct xdr_stream *xdr, struct nfs_pgio_re static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res) { __be32 *p; - uint32_t count, eof, segments, type; - int status; + uint32_t eof, segments, type, total; + int32_t count; + int status, i; status = decode_op_hdr(xdr, OP_READ_PLUS); if (status) @@ -810,26 +811,28 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res) if (unlikely(!p)) return -EIO; + total = 0; eof = be32_to_cpup(p++); segments = be32_to_cpup(p++); - if (segments == 0) - return 0; - p = xdr_inline_decode(xdr, 4); - if (unlikely(!p)) - return -EIO; + for (i = 0; i < segments; i++) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) + return -EIO; - type = be32_to_cpup(p++); - if (type == NFS4_CONTENT_DATA) - count = decode_read_plus_data(xdr, res, &eof); - else - count = decode_read_plus_hole(xdr, res, &eof); + type = be32_to_cpup(p); + if (type == NFS4_CONTENT_DATA) + count = decode_read_plus_data(xdr, res, &eof, total); + else + count = decode_read_plus_hole(xdr, res, &eof, total); - if (segments > 1) - eof = 0; + if (count < 0) + return count; + total += count; + } res->eof = eof; - res->count = count; + res->count = total; return 0; } From patchwork Fri Jan 10 22:34:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11328575 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2C01E92A for ; Fri, 10 Jan 2020 22:35:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0B40720721 for ; Fri, 10 Jan 2020 22:35:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QlblZCL8" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727499AbgAJWfI (ORCPT ); Fri, 10 Jan 2020 17:35:08 -0500 Received: from mail-yb1-f193.google.com ([209.85.219.193]:40049 "EHLO mail-yb1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727393AbgAJWfI (ORCPT ); Fri, 10 Jan 2020 17:35:08 -0500 Received: by mail-yb1-f193.google.com with SMTP id a2so1370053ybr.7 for ; Fri, 10 Jan 2020 14:35:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=EX9to2JgKDzoS0UYtuWj3O69P1cekZ+X0dJX6EOInOw=; b=QlblZCL8QdAGwlf3j2K92tekYdfbueuiZBKJR4kLcrvi9hyrFpVWysNVThQrOtQWzN 2Ej3uTe0/Km9CnCryqAScIMlBOgOrzeTJeVq/tKzYTcndMVjmN5iJcgycis4KKIkcJIe 7ygPnq1DfgBzHrcwE/aZuHw4uHRAUUJfuO/uQNMyZpzSyC+u5GljIc/YxgwvgQGmloVs Usd5zjyENOOyRGPfzIXzn1OZcAbNX/a/wEEMdC0nMbsb0FhxSV1LjrsAuxGfKyVkmSf1 GbS25vQijlYd0To2+abE1WcjWcmBveImYDBPcsyAwY7+z0Fp6CT4w9fqec9ta77upr5k Pyug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=EX9to2JgKDzoS0UYtuWj3O69P1cekZ+X0dJX6EOInOw=; b=WN/ji1b8K8bSfflH15zGtLVODRKQcEX3/Nv+TpIimA6M2rRnO61tS1KK9CA6N4ipSY UUmjrej6+uqIcRjqRrWXYlBSpKzFxBNaAKj/kQyTWJuEOposQymlC4Cvjn7wFCwP1EOe 4BARAG5TyQxzPTsygjXmSvQOIydpGpjNJWDto9jlBn4Ol/eK+Ssn5UdJ8h9grXfclSbF 3Kjf1yiHyRWEfX8/8T0dslsfmXdILSICrF7jdK6E10ZYSGuKKuQPjktGAtWCcgvi1q+y 632W6HvlEA7pOXU7y+ysYNDbnuKXnKgPY0NJiDJkkD7EBYKB64Vfrh5LFhY1EK4Hp86V 1cNw== X-Gm-Message-State: APjAAAUyGY9+FfRRgbRk3jzZXnBODirE5ozCWKWIf/R47orwjum0+5Py Tk7F5C1zmObx5wn7PUkvdKw= X-Google-Smtp-Source: APXvYqy3MrI3rrWEnBqHikudN+nGfTibJFgf+yFf6z/Vw+RjYYk1HzclgTSnpPgBsEsOf7OW9KZa3g== X-Received: by 2002:a5b:782:: with SMTP id b2mr4130150ybq.25.1578695707274; Fri, 10 Jan 2020 14:35:07 -0800 (PST) Received: from gouda.nowheycreamery.com (c-68-32-74-190.hsd1.mi.comcast.net. [68.32.74.190]) by smtp.gmail.com with ESMTPSA id e186sm1554060ywb.73.2020.01.10.14.35.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jan 2020 14:35:06 -0800 (PST) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: Trond.Myklebust@hammerspace.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH 7/7] NFS: Add a mount option for READ_PLUS Date: Fri, 10 Jan 2020 17:34:55 -0500 Message-Id: <20200110223455.528471-8-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200110223455.528471-1-Anna.Schumaker@Netapp.com> References: <20200110223455.528471-1-Anna.Schumaker@Netapp.com> MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Anna Schumaker There are some workloads where READ_PLUS might end up hurting performance, so let's be nice to users and provide a way to disable this operation similar to how READDIR_PLUS can be disabled. Signed-off-by: Anna Schumaker --- fs/nfs/fs_context.c | 14 ++++++++++++++ fs/nfs/nfs4client.c | 3 +++ include/linux/nfs_fs_sb.h | 1 + 3 files changed, 18 insertions(+) diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index 0247dcb7b316..82ba07c7c1ce 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -64,6 +64,7 @@ enum nfs_param { Opt_proto, Opt_rdirplus, Opt_rdma, + Opt_readplus, Opt_resvport, Opt_retrans, Opt_retry, @@ -120,6 +121,7 @@ static const struct fs_parameter_spec nfs_param_specs[] = { fsparam_string("proto", Opt_proto), fsparam_flag_no("rdirplus", Opt_rdirplus), fsparam_flag ("rdma", Opt_rdma), + fsparam_flag_no("readplus", Opt_readplus), fsparam_flag_no("resvport", Opt_resvport), fsparam_u32 ("retrans", Opt_retrans), fsparam_string("retry", Opt_retry), @@ -555,6 +557,12 @@ static int nfs_fs_context_parse_param(struct fs_context *fc, else ctx->options |= NFS_OPTION_MIGRATION; break; + case Opt_readplus: + if (result.negated) + ctx->options |= NFS_OPTION_NO_READ_PLUS; + else + ctx->options &= ~NFS_OPTION_NO_READ_PLUS; + break; /* * options that take numeric values @@ -1176,6 +1184,10 @@ static int nfs_fs_context_validate(struct fs_context *fc) (ctx->version != 4 || ctx->minorversion != 0)) goto out_migration_misuse; + if (ctx->options & NFS_OPTION_NO_READ_PLUS && + (ctx->version != 4 || ctx->minorversion < 2)) + goto out_noreadplus_misuse; + /* Verify that any proto=/mountproto= options match the address * families in the addr=/mountaddr= options. */ @@ -1254,6 +1266,8 @@ static int nfs_fs_context_validate(struct fs_context *fc) ctx->version, ctx->minorversion); out_migration_misuse: return nfs_invalf(fc, "NFS: 'Migration' not supported for this NFS version"); +out_noreadplus_misuse: + return nfs_invalf(fc, "NFS: 'noreadplus' not supported for this NFS version\n"); out_version_unavailable: nfs_errorf(fc, "NFS: Version unavailable"); return ret; diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 0cd767e5c977..868dc3c36ba1 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -1016,6 +1016,9 @@ static int nfs4_server_common_setup(struct nfs_server *server, server->caps |= server->nfs_client->cl_mvops->init_caps; if (server->flags & NFS_MOUNT_NORDIRPLUS) server->caps &= ~NFS_CAP_READDIRPLUS; + if (server->options & NFS_OPTION_NO_READ_PLUS) + server->caps &= ~NFS_CAP_READ_PLUS; + /* * Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower * authentication. diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 11248c5a7b24..360e70c7bbb6 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -172,6 +172,7 @@ struct nfs_server { unsigned int clone_blksize; /* granularity of a CLONE operation */ #define NFS_OPTION_FSCACHE 0x00000001 /* - local caching enabled */ #define NFS_OPTION_MIGRATION 0x00000002 /* - NFSv4 migration enabled */ +#define NFS_OPTION_NO_READ_PLUS 0x00000004 /* - NFSv4.2 READ_PLUS enabled */ struct nfs_fsid fsid; __u64 maxfilesize; /* maximum file size */