Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp894568pxf; Wed, 7 Apr 2021 14:23:17 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxEKu0bIGobhcLfI164YS5J5kk1yiiu7DqFHFZDv4mV0GoZ2JCV12hYdcI3JcZd5CiRLRAd X-Received: by 2002:aa7:d341:: with SMTP id m1mr6928366edr.120.1617830597261; Wed, 07 Apr 2021 14:23:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1617830597; cv=none; d=google.com; s=arc-20160816; b=0uhxyH3Z9VX+10OXTLuQKsC7DrpXU4pHZ4AYNiOXfC2Z0qsUsavBLU4+ySEb4K0CUv P+1r0fUBjgPnaPnPehgmtzERR+bTFzRTOs4sstzGdawD9wtRGLU7zcjbxQOYeVL31PDY p971Ati8xZ4RpKxhZlpC/HRKkO0zXgGvPnCSwnmMJ+T+/v9Ymo50CBq8UX97pC4XE2CT ZkKfVsfF1Xjy9BpjCneokpoY+lAeXBWZ3Oz4mnEYIbN3hDpjP2+AiTkqgJuaiH1I8yH4 25caQoAaD6MqkvwUpqe+6AQaNVZ+2RHnlsmDnv3sukUhNDBYvVvBiGupCV8FBPIYiHnj JEPg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:cc:to:from :subject:organization:dkim-signature; bh=WULWsN3uOe2W6umAHISiBdK6m4Z+piU8XcyQ1XGELSQ=; b=Sg96dzO4AeG1QnewervbBJjuuJOPqv1EeXeX9EX5Ewv39s87BNAwFLHOBzdhGqg3bJ 745dt8IxrpnikGESIT+94EXeG0XcG3hastj1XB2pTbbU1qNTPIvYnKacoDXcsVy7TLaF nIKypeQG6JyHruRaofL6VJHzJeTHXrDmAg+04R7k7h0b/lUmpXZCin4Uk6VVSmYRqQu1 0bxov9zeiqCOIlcKHYy9+JYAOH7IZzAKYsAgcpCF7Gc5vpQRQ4BEyvj8F7tPlPOMcbQ1 cx78TApGqbvWUf3JIhEW5u5+NHFO8Ou+zlbcjmU+1gaeBG5sFDyCFn35ro0ZKx6MMk3G Ts9g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Yjm2Vd7J; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id a12si8952542ejk.28.2021.04.07.14.22.54; Wed, 07 Apr 2021 14:23:17 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Yjm2Vd7J; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353820AbhDGPsv (ORCPT + 99 others); Wed, 7 Apr 2021 11:48:51 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:50396 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353824AbhDGPsQ (ORCPT ); Wed, 7 Apr 2021 11:48:16 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1617810486; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WULWsN3uOe2W6umAHISiBdK6m4Z+piU8XcyQ1XGELSQ=; b=Yjm2Vd7Jz9ybVFFdQdqXCYvbYVritq4QqXf9NKRk11jcFClLAuJomzVwMHdA2L/z+BfqUa UTk+SGtYzeQ3ODxqa0rHMDsoxCQ/KUaCDaZsHvLB3A7rQC9Kq/gRIqHAdLYeLqrd1tEYmj OLAPOcBGLhuY08SB37NdK6rFRAh5DHg= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-26-mZS2mNHpOlyDiFJYF0vuxA-1; Wed, 07 Apr 2021 11:48:04 -0400 X-MC-Unique: mZS2mNHpOlyDiFJYF0vuxA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E55425B364; Wed, 7 Apr 2021 15:48:02 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-115-201.rdu2.redhat.com [10.10.115.201]) by smtp.corp.redhat.com (Postfix) with ESMTP id C805160C5C; Wed, 7 Apr 2021 15:47:57 +0000 (UTC) Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [PATCH 4/5] netfs: Fix copy-to-cache amalgamation From: David Howells To: jlayton@kernel.org Cc: dwysocha@redhat.com, linux-cachefs@redhat.com, v9fs-developer@lists.sourceforge.net, linux-afs@lists.infradead.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Wed, 07 Apr 2021 16:47:56 +0100 Message-ID: <161781047695.463527.7463536103593997492.stgit@warthog.procyon.org.uk> In-Reply-To: <161781041339.463527.18139104281901492882.stgit@warthog.procyon.org.uk> References: <161781041339.463527.18139104281901492882.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org Fix the amalgamation of subrequests when copying to the cache. We shouldn't be rounding up the size to PAGE_SIZE as we go along as that ends up with the composite subrequest length being too long - and this leads to EIO from the cache write because the source iterator doesn't contain enough data. Instead, we only need to deal with contiguous subreqs and then ask the cache to round off as it needs - which also means we don't have to make any assumptions about the cache granularity. Signed-off-by: David Howells --- fs/cachefiles/io.c | 17 +++++++++++++++++ fs/netfs/read_helper.c | 19 +++++++++---------- include/linux/netfs.h | 6 ++++++ include/trace/events/netfs.h | 2 ++ 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index 620959d1e95b..b13fb45fc3f3 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -330,6 +330,22 @@ static enum netfs_read_source cachefiles_prepare_read(struct netfs_read_subreque return NETFS_DOWNLOAD_FROM_SERVER; } +/* + * Prepare for a write to occur. + */ +static int cachefiles_prepare_write(struct netfs_cache_resources *cres, + loff_t *_start, size_t *_len, loff_t i_size) +{ + loff_t start = *_start; + size_t len = *_len, down; + + /* Round to DIO size */ + down = start - round_down(start, PAGE_SIZE); + *_start = start - down; + *_len = round_up(down + len, PAGE_SIZE); + return 0; +} + /* * Clean up an operation. */ @@ -355,6 +371,7 @@ static const struct netfs_cache_ops cachefiles_netfs_cache_ops = { .read = cachefiles_read, .write = cachefiles_write, .prepare_read = cachefiles_prepare_read, + .prepare_write = cachefiles_prepare_write, }; /* diff --git a/fs/netfs/read_helper.c b/fs/netfs/read_helper.c index ad0dc01319ce..ce2f31d20250 100644 --- a/fs/netfs/read_helper.c +++ b/fs/netfs/read_helper.c @@ -293,7 +293,7 @@ static void netfs_rreq_do_write_to_cache(struct netfs_read_request *rreq) struct netfs_cache_resources *cres = &rreq->cache_resources; struct netfs_read_subrequest *subreq, *next, *p; struct iov_iter iter; - loff_t pos; + int ret; trace_netfs_rreq(rreq, netfs_rreq_trace_write); @@ -311,23 +311,22 @@ static void netfs_rreq_do_write_to_cache(struct netfs_read_request *rreq) list_for_each_entry(subreq, &rreq->subrequests, rreq_link) { /* Amalgamate adjacent writes */ - pos = round_down(subreq->start, PAGE_SIZE); - if (pos != subreq->start) { - subreq->len += subreq->start - pos; - subreq->start = pos; - } - subreq->len = round_up(subreq->len, PAGE_SIZE); - while (!list_is_last(&subreq->rreq_link, &rreq->subrequests)) { next = list_next_entry(subreq, rreq_link); - if (next->start > subreq->start + subreq->len) + if (next->start != subreq->start + subreq->len) break; subreq->len += next->len; - subreq->len = round_up(subreq->len, PAGE_SIZE); list_del_init(&next->rreq_link); netfs_put_subrequest(next, false); } + ret = cres->ops->prepare_write(cres, &subreq->start, &subreq->len, + rreq->i_size); + if (ret < 0) { + trace_netfs_sreq(subreq, netfs_sreq_trace_write_skip); + continue; + } + iov_iter_xarray(&iter, WRITE, &rreq->mapping->i_pages, subreq->start, subreq->len); diff --git a/include/linux/netfs.h b/include/linux/netfs.h index 2299e7662ff0..9062adfa2fb9 100644 --- a/include/linux/netfs.h +++ b/include/linux/netfs.h @@ -206,6 +206,12 @@ struct netfs_cache_ops { */ enum netfs_read_source (*prepare_read)(struct netfs_read_subrequest *subreq, loff_t i_size); + + /* Prepare a write operation, working out what part of the write we can + * actually do. + */ + int (*prepare_write)(struct netfs_cache_resources *cres, + loff_t *_start, size_t *_len, loff_t i_size); }; struct readahead_control; diff --git a/include/trace/events/netfs.h b/include/trace/events/netfs.h index a2bf6cd84bd4..e3ebeabd3852 100644 --- a/include/trace/events/netfs.h +++ b/include/trace/events/netfs.h @@ -43,6 +43,7 @@ enum netfs_sreq_trace { netfs_sreq_trace_submit, netfs_sreq_trace_terminated, netfs_sreq_trace_write, + netfs_sreq_trace_write_skip, netfs_sreq_trace_write_term, }; @@ -77,6 +78,7 @@ enum netfs_sreq_trace { EM(netfs_sreq_trace_submit, "SUBMT") \ EM(netfs_sreq_trace_terminated, "TERM ") \ EM(netfs_sreq_trace_write, "WRITE") \ + EM(netfs_sreq_trace_write_skip, "SKIP ") \ E_(netfs_sreq_trace_write_term, "WTERM")