From patchwork Fri Feb 14 21:12:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11383291 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 E2B43139A for ; Fri, 14 Feb 2020 21:12:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C2E75222C4 for ; Fri, 14 Feb 2020 21:12:32 +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="uwUHJd9w" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388880AbgBNVMc (ORCPT ); Fri, 14 Feb 2020 16:12:32 -0500 Received: from mail-yb1-f194.google.com ([209.85.219.194]:46083 "EHLO mail-yb1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388611AbgBNVMc (ORCPT ); Fri, 14 Feb 2020 16:12:32 -0500 Received: by mail-yb1-f194.google.com with SMTP id n131so2083929ybg.13 for ; Fri, 14 Feb 2020 13:12:30 -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=JdeyJJxBiPoYKIpc2OOvNsxuYuaYaRTbJwkLpmvnKo4=; b=uwUHJd9wgzovLpHjJ6XTFsTAxtlXOYvNXsXLSCmnBpBECJnjNFWLL66Mzfgy8T1YQx StUjEa3KgJS5sCS36dH3PhznVOCTzL5RM6llOnXa8RPe60bdO7whvF6vtR9FhQr3UB84 iUdaW4XmQGRxgtnGEk1YAeIX9FPOfh2hFTW+GQUlOqgivsqX4Uiovp1shTlh9TJoEXFP XUjXaKNU5De11gR6HEQozy6T7uo5gDafrmTUKLTMae3aTWhssqjYeueGt63Wt2vCcaZa y0rDaNChSjxjHp/80onab2Amjt5c0/FNRr+Wr1jSp9e2TgP4MpV7ztLGDad9+fyzq3Im EmOA== 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=JdeyJJxBiPoYKIpc2OOvNsxuYuaYaRTbJwkLpmvnKo4=; b=svbsQQ1r828DFZPj1x6e2nclHNyOkbP8UeoucdHk/hR+OVZ4Vr2XxD+GNS4jyFIhVg Pb0YszpjFMzKFY2CIKhZjHmvP6pxxkvCc/sY6PGaAwaFr3d+PZCsnGMpgxbpHZaExDgv o2DIuVSYpGS63j/iSqpXvp/heYragdglZpgtVhRkwVWO2qxtvuLatK6lnLKJaiCvpK2Z //j4veT+vxfa3qR8+0G664sqyxJaogH6g14Ce2GvLs7QzHuldHpGYYUfsTjYnfqz6oXS JreoFjWP8o6LsN8++sqJmfSLIfmXSTcMianT/hQdt80/DrNTVcXbsjeqAY+R1oWTmt9W Nm6w== X-Gm-Message-State: APjAAAVbEZI3BKp+czgLWqoDoQxPAnunQVtMxaev0oG+QsnAuqxZd4ex FCrQUtq/xN01jXbSnHcnNwE= X-Google-Smtp-Source: APXvYqwvrwsG0xZK+V3hqpPtGpegJyFYfvJlwpMo7MBpX99kvTlNPckONoSFomNNTtaqs2RobbGUYw== X-Received: by 2002:a25:854f:: with SMTP id f15mr4452892ybn.463.1581714749971; Fri, 14 Feb 2020 13:12:29 -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 z2sm2840636ywb.13.2020.02.14.13.12.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Feb 2020 13:12:29 -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 v2 1/6] SUNRPC: Split out a function for setting current page Date: Fri, 14 Feb 2020 16:12:22 -0500 Message-Id: <20200214211227.407836-2-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200214211227.407836-1-Anna.Schumaker@Netapp.com> References: <20200214211227.407836-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 Feb 14 21:12:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11383293 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 851E01820 for ; Fri, 14 Feb 2020 21:12:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5CF3C222C4 for ; Fri, 14 Feb 2020 21:12:33 +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="bt3z0tuc" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388889AbgBNVMc (ORCPT ); Fri, 14 Feb 2020 16:12:32 -0500 Received: from mail-yw1-f68.google.com ([209.85.161.68]:45957 "EHLO mail-yw1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388783AbgBNVMc (ORCPT ); Fri, 14 Feb 2020 16:12:32 -0500 Received: by mail-yw1-f68.google.com with SMTP id a125so4860580ywe.12 for ; Fri, 14 Feb 2020 13:12:31 -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=/HwZzRb8kfAIfGOyJ8K3y1FUu20TYSwp6DTuTITtZxM=; b=bt3z0tuc63nLVS1R97+qe5FCBTWzRBF1loaln7WdVyICMxWh5rTmcHwUq9O350UnS1 VWb2eHHX5ym7gULOHK6sv4sB4RYY9/luQiH7hIfD023KTGUjFV9QKfLcr2QKK/r5PA5q ZUW+GquokN8dgNV17q8ELRceHNP6Ydegcf02fdWNaqqgiIrc1w4WazCI5edxmExopFuk iPs4lQAUx45kfoeiGc50/ItRjEqUUGRGtfyAO3uS2g5ZudFCG4wrGXTfdg7XbybNsepF PlnFyCT60sdalajAMOC4xmNDC2fHCc7PTg+tEVVnAQ1Ll9iaM+u2QjdB3bEj7cng/N6I mcJA== 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=/HwZzRb8kfAIfGOyJ8K3y1FUu20TYSwp6DTuTITtZxM=; b=PMNT1KO6jfK5eegSJhTr1JpJuHnUiCkbh7C0KBrpHC/DjA41uv4Tdrijq2MMa2qdy/ oEZwAOBfbvZSkfqaP4at/gYInANVFFufAQY++s6w5t8tssEeq/rPpK+t1ZP5k81x4zv6 ra+Oe3MYCtl1Jgf319Uy6XhCM731Wq8vo8whtIVhJsUwQYj3gAGdZtlNv8NcmYeJm/FV pFq4lwB6jjSw6hoW/IBjmoxSNg3mcfmrnZhRTmtmoRO/uMRN0nMguk8nfB4J1ddhLZ1L u1LNKRtKGOLl7BQH3un/UKX/6EQ8fWy3xAQNt3b4xHcnewwTcnHXvIuAYtH36CHXo0+D c9WQ== X-Gm-Message-State: APjAAAW2e1AAGNG5rocgSfm82PnXIVyjUftSGHfM0tmi0YwLe/mL+WpN 8SyTX4ncsKWNgBbjV7EKIzI= X-Google-Smtp-Source: APXvYqysDkMJBlbJTQKN+UoD6rb1RONe6CVlG7OXViD9rxydD8bPtFnBmRsFs9VzR0Hov1o0PA7VGQ== X-Received: by 2002:a81:1ad5:: with SMTP id a204mr3982321ywa.486.1581714751112; Fri, 14 Feb 2020 13:12:31 -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 z2sm2840636ywb.13.2020.02.14.13.12.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Feb 2020 13:12:30 -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 v2 2/6] SUNRPC: Add the ability to expand holes in data pages Date: Fri, 14 Feb 2020 16:12:23 -0500 Message-Id: <20200214211227.407836-3-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200214211227.407836-1-Anna.Schumaker@Netapp.com> References: <20200214211227.407836-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 Feb 14 21:12:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11383295 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 413001580 for ; Fri, 14 Feb 2020 21:12:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 204E5222C4 for ; Fri, 14 Feb 2020 21:12:34 +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="HKJGBMW6" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388783AbgBNVMd (ORCPT ); Fri, 14 Feb 2020 16:12:33 -0500 Received: from mail-yw1-f68.google.com ([209.85.161.68]:43068 "EHLO mail-yw1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388611AbgBNVMd (ORCPT ); Fri, 14 Feb 2020 16:12:33 -0500 Received: by mail-yw1-f68.google.com with SMTP id f204so4861961ywc.10 for ; Fri, 14 Feb 2020 13:12:32 -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=DU/9mGOna4azTXBZcHD1jvVU7+OrAAyBceq+tZpYVLY=; b=HKJGBMW6xuObddKjddHGTJdSK/n8OqGKz+4Xtlwgxf3H9opRt2i8vxtngchkUmJeUT wUjmzTJT3vLOxdlmhtA1reJ8fWIlq48kcAlY4zVRDRoK+JxmoRP5YXauI8yNFJt94aMq TElDrzWNZan2ssADoIwox2WxybOuORT1JO3SoLoKzjJHiV3ddo9BDCd08FTexwioDLsk uuoPtS+/rV8YcsxWvIOS4TeB6sbTch/7d5DbVY8d0O76XJBqMIKkvmXeE/kMEazubU71 SBi2Lsnrzt7+j2ZQoow1BOmCK9MN+fPhZgtaM5JvpRJd1t4wvWUAC+jCPdHhXwZc4867 7aAw== 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=DU/9mGOna4azTXBZcHD1jvVU7+OrAAyBceq+tZpYVLY=; b=bb/H0D2XMT4dSrCHDIW0aq6QpVhfej5amEmMPMtwTnazf4pOK5xq0DQvGvLor+CEqJ ej5xjcAxdz0yvRfxc5PtwKVDR5jw2FKqStDNDbAsnv4IbqxvpTAAdUM2f5fnPno5txLQ apWX9sDUsws9Kd1GMiQiqizuLptbQhkZwYrkRORtvqPTUVwXiNitd0b/V64awYIyFjT4 sfS1loMiexV3GFFfinP2ViAw4ykX4NVSJH9JZW8eaTSD5cb+xNTEXdycVHMDDelm6Ll+ HMWziaUFhwpOmZFT1ea16/gZBjZVZb1QDp8j7Ql58eWun6NMw1jbLxMy56ELkOmtRJSg jf2w== X-Gm-Message-State: APjAAAV64ppUKxiB0nx7gs8Aavb8Hq7qmMvsQYIZ5rS/o0ignin4Mw9V 9KEWSDdWjBzNl4j4+oy3GBk= X-Google-Smtp-Source: APXvYqyPqafHVqUNUHIQrq3D5nV3qgZ3DsP6vw0kvKdZqe3Q/TF+QnQvx0/uZK/s1uGwumT7uDg05A== X-Received: by 2002:a81:8785:: with SMTP id x127mr3727369ywf.455.1581714752201; Fri, 14 Feb 2020 13:12:32 -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 z2sm2840636ywb.13.2020.02.14.13.12.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Feb 2020 13:12:31 -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 v2 3/6] SUNRPC: Add the ability to shift data to a specific offset Date: Fri, 14 Feb 2020 16:12:24 -0500 Message-Id: <20200214211227.407836-4-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200214211227.407836-1-Anna.Schumaker@Netapp.com> References: <20200214211227.407836-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 Feb 14 21:12:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11383297 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 36B201580 for ; Fri, 14 Feb 2020 21:12:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0E01E222C4 for ; Fri, 14 Feb 2020 21:12:36 +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="ZykNWgHG" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388793AbgBNVMf (ORCPT ); Fri, 14 Feb 2020 16:12:35 -0500 Received: from mail-yw1-f67.google.com ([209.85.161.67]:37673 "EHLO mail-yw1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388611AbgBNVMf (ORCPT ); Fri, 14 Feb 2020 16:12:35 -0500 Received: by mail-yw1-f67.google.com with SMTP id l5so4894985ywd.4 for ; Fri, 14 Feb 2020 13:12:33 -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=Ota7SihxH20GwGjM/+nSRdUD9/bCi0WbGiJXk6qQtsg=; b=ZykNWgHGnM8ypie3BR59usDi9joEpTUpFmLF6HdGXM9eS+2tkWWeOMZPmRbZnBNzJM wk7+w37O97qhAxOXCsC5grP0Oncyp9ZRFV4gVqZBy3ehxrhCv9+/aCKeOZsF8icBFZY4 1R06Nrvjet8E+5rQMsNMamZFeGUpr1QA9/rMALKK0hdW4OaEJjkLNOoucJyzEUovXGFn SvPLmYW12i8Ig/aO1VJ41W87CmlMdYpXeVim+4NJd+HJ3EG9cOhlZaNRhP3ApGemrVvV NF6hHPaV25scvfnINvfmNW9CGCEzu4JoJEO5PIwtm/K7m4vr7hVh+oXT9k3wa5ArWIUt J9Qw== 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=Ota7SihxH20GwGjM/+nSRdUD9/bCi0WbGiJXk6qQtsg=; b=qYknXxfZSIBboJXxg7WQA/7abDIW/dhMbCx25t1+EVnpm2titu1dBOMfv/PTlcZ7V7 LsVEljDV0yQNJzXKH1KEoYZH3k3oo1rmffjsBzrYpJaLNh6bT5mB5htMpSgptgpyGUa5 qr356SwqqYESbmVMJpBiWNhocMhiphR20/9y1DMDT291lwlCZ8NU7v8n5zmlhFu6YLlS KjW4/9iRAeKcgO2yEfVL++NxDG5WHegad3mDv7dnbJTmNtlMEpb5yikGvgDzN53DRHqR pfr+cA7a8SxETTxLfj2fAFfUeeZfJ1ZcvJ8wzpmhnjYzYbe2rBMZKV+bTLRHFhgGg9rZ xc3g== X-Gm-Message-State: APjAAAXh1ENIMK79q58HfIS16xcukJJ4UIHGQ1y4ezBEk+j/0q0tkvjr b+Shca7bdTad5BmXfisF2qpeCQs5 X-Google-Smtp-Source: APXvYqx41Q328WaC5NXq5ohYA/0ngq2woI2hoxuWmVziRDwlqoEuvsSsc7/lAS2LI8/osaUmpYYZrg== X-Received: by 2002:a0d:d1c6:: with SMTP id t189mr3902682ywd.393.1581714753382; Fri, 14 Feb 2020 13:12:33 -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 z2sm2840636ywb.13.2020.02.14.13.12.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Feb 2020 13:12:32 -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 v2 4/6] NFS: Add READ_PLUS data segment support Date: Fri, 14 Feb 2020 16:12:25 -0500 Message-Id: <20200214211227.407836-5-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200214211227.407836-1-Anna.Schumaker@Netapp.com> References: <20200214211227.407836-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 | 43 +++++++++++- 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, 182 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 95d07a3dc5d1..ed3ec8c36273 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 @@ -5199,28 +5203,60 @@ static bool nfs4_read_stateid_changed(struct rpc_task *task, return true; } +static bool nfs4_read_plus_not_supported(struct rpc_task *task, + struct nfs_pgio_header *hdr) +{ + struct nfs_server *server = NFS_SERVER(hdr->inode); + struct rpc_message *msg = &task->tk_msg; + + if (msg->rpc_proc == &nfs4_procedures[NFSPROC4_CLNT_READ_PLUS] && + server->caps & NFS_CAP_READ_PLUS && task->tk_status == -ENOTSUPP) { + server->caps &= ~NFS_CAP_READ_PLUS; + msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ]; + rpc_restart_call_prepare(task); + return true; + } + return false; +} + static int nfs4_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr) { - dprintk("--> %s\n", __func__); if (!nfs4_sequence_done(task, &hdr->res.seq_res)) return -EAGAIN; if (nfs4_read_stateid_changed(task, &hdr->args)) return -EAGAIN; + if (nfs4_read_plus_not_supported(task, hdr)) + return -EAGAIN; if (task->tk_status > 0) nfs_invalidate_atime(hdr->inode); return hdr->pgio_done_cb ? hdr->pgio_done_cb(task, 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); } @@ -9970,7 +10006,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 47817ef0aadb..68b2917d0537 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -7584,6 +7584,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 94c77ed55ce1..8efbf3d8b263 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 Feb 14 21:12:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11383299 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 6064E139A for ; Fri, 14 Feb 2020 21:12:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 407F6217F4 for ; Fri, 14 Feb 2020 21:12:36 +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="FJPvo5WX" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388611AbgBNVMf (ORCPT ); Fri, 14 Feb 2020 16:12:35 -0500 Received: from mail-yw1-f67.google.com ([209.85.161.67]:36483 "EHLO mail-yw1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388784AbgBNVMf (ORCPT ); Fri, 14 Feb 2020 16:12:35 -0500 Received: by mail-yw1-f67.google.com with SMTP id n184so4895872ywc.3 for ; Fri, 14 Feb 2020 13:12:35 -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=hQJF/Us8mBq5d5w2VX07T1bAiTh/kW0x7QYbqFKK47M=; b=FJPvo5WXjTC5nzcMgH3NXfFSrzphA2HH7zJ/pbOFGNyF1Vkga9GN9vaYKCGFZ4daWc u3R63QaE3ijs6RNYvtl6OBr31P1uGDrFjCQlcog7PFnabuuTcI9RSRp6kb5zoFgDj4e8 JobmyUNIMRq9gb3LFUIpHWtDwtQIX3O/EOUIpPK5wdarfYlWNBQQ65A5gGLzNlC8nuqP 8cbjE+NZmSY8lbSC0ryy32y+rZN3NuWbCY6uyTGjdCsQwqDd/uNvreO1GbY3MiT1sEAS Rer2AYzRy+3SErrQ6cZLfEDIsXbImuzfWdFl9V2loLNrK2x9enpJTr7A4pE6jBzP6BF0 SMkA== 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=hQJF/Us8mBq5d5w2VX07T1bAiTh/kW0x7QYbqFKK47M=; b=BGBkOBRDsKNiB2I/KXxAvDv/q68a2TdmEdgh1YskkiSeFsqSARf1vxLxnKfzummveD 0ovbozRVM3Un84ywJDJ0P3O7FG2/a0AtaBIBNOUtof6TtSVZXKZ83srSUeQLH+7tjQ0C 8xtsojJHNojckPlNZoJyrdxSfvga4HsfmeromYbiLVDXfjpbIwY4GVycwVrm3Gk/l8p+ ml33Vm+k9U3W0WR5u2izCxMS/YfZqfZNpKlEP93nQm1laQJPcLyQUijy2gX+V5QN9l2X uSS334sp3wf7w4w5fGSv1d3h1ycWM610T6AMuNz5EbEgACGu3E4mgqpFTzx8ZHN5FUms +AYg== X-Gm-Message-State: APjAAAWN7CanQ3Wj9xmHtetFybfbHaSYNXQaRfkzR71pMBXM+xjWjXXs Ybd7Sdj7GXs+R7ZR0jYcsSjlHf/f X-Google-Smtp-Source: APXvYqy9QFsgUDNErv5C/XjB7YRkKlPrwTpLhuVOrDXXdiQROJqsKAOYHsyEn1uCiXEfmsHFC+4O5g== X-Received: by 2002:a0d:d551:: with SMTP id x78mr4101649ywd.50.1581714754470; Fri, 14 Feb 2020 13:12:34 -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 z2sm2840636ywb.13.2020.02.14.13.12.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Feb 2020 13:12:33 -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 v2 5/6] NFS: Add READ_PLUS hole segment decoding Date: Fri, 14 Feb 2020 16:12:26 -0500 Message-Id: <20200214211227.407836-6-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200214211227.407836-1-Anna.Schumaker@Netapp.com> References: <20200214211227.407836-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 Feb 14 21:12:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11383301 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 990291580 for ; Fri, 14 Feb 2020 21:12:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 79B5F222C4 for ; Fri, 14 Feb 2020 21:12:37 +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="cEdO7hpH" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388799AbgBNVMg (ORCPT ); Fri, 14 Feb 2020 16:12:36 -0500 Received: from mail-yw1-f68.google.com ([209.85.161.68]:33096 "EHLO mail-yw1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388784AbgBNVMg (ORCPT ); Fri, 14 Feb 2020 16:12:36 -0500 Received: by mail-yw1-f68.google.com with SMTP id 192so4902472ywy.0 for ; Fri, 14 Feb 2020 13:12:36 -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=0xNABLh/UHDM1w9keGJuUb3+6797t6mQJFRB2SGiWj8=; b=cEdO7hpHnuC84UCRYH6QYzQfPsb6YBARXeYZLpTuXSIdfeJKYSIl94PvlBmJgzgTol PIiV5yvVjPkdqpVVzBdFJ6iPIOtY4i7Cd+IAyufh3zLCOFm1yGZcCGM6Hpm2T7uUpeuo hBbgiewHoqSN/kawqdsXPOFoOqVa+saKnUNjMpvDz1ZRXQwFUukoumoUT+8IBbednqoc nwcKGbayLAeEr+JPlgvbyylTK3our/wlkiZFQL4o41QO4YKYhnHqP/W0NgpTvkgVgBtU UYtU+Ruwu2BoKH18w2x+e0/cSIlhY1Q3VPEj3ipRxyHDZ+t8OQl3JOcZSiKqTpXjvvcu LD9g== 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=0xNABLh/UHDM1w9keGJuUb3+6797t6mQJFRB2SGiWj8=; b=DHY/qrWazNwFClYrsS4Rh5Yyivxj0fVXOoX7zE/ib/f7kXsmgorsWiaXvsg1/orU9j FshlWNHcILs/BWyTBQwL0TmU0FZnzh8F1FVjNgu2RW6jPLx1TG9JUGme9f+FEA6N55OE rUIYMa4URJnXFBPfZBQC7htNraw5uZkPwLO8P7ozTbnZC3YYhuavvwJdlTx157j61cnl JlWtn+MHnAjFd4VXvsr+nbRrfsoqlzHFBxUfGKezuctfkbmaK76qPDB65RH9CuK9ZBWp 0d01VhMtMvOfF/c4Wb+jYU5tThv2v8oL0Y60DFHzRh0lnvORfDW02k+yMT8Xyu/7DTcW fRZg== X-Gm-Message-State: APjAAAXmzmPvZSuQ4r1w58hlb9XIo7fKhy8F0UwUmXm3U5h+zAsxbL6Z 5Nqvy2XU7B2VGXgB2e1rUr+f4iY+ X-Google-Smtp-Source: APXvYqzMvIc8IAYZCh2OavvvWpwjJ3WmxetYceZQz8IqudKL7qTGPP3QZzB0yo4JFY+Rq+zzGHWLrA== X-Received: by 2002:a81:6e09:: with SMTP id j9mr3819871ywc.25.1581714755527; Fri, 14 Feb 2020 13:12:35 -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 z2sm2840636ywb.13.2020.02.14.13.12.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Feb 2020 13:12:34 -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 v2 6/6] NFS: Decode multiple READ_PLUS segments Date: Fri, 14 Feb 2020 16:12:27 -0500 Message-Id: <20200214211227.407836-7-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200214211227.407836-1-Anna.Schumaker@Netapp.com> References: <20200214211227.407836-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; }