From patchwork Fri Nov 17 21:14:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 13459373 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2A45CC54FB9 for ; Fri, 17 Nov 2023 21:16:06 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 81BBC8D000D; Fri, 17 Nov 2023 16:16:05 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 7A3F08D0002; Fri, 17 Nov 2023 16:16:05 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 61CC08D000D; Fri, 17 Nov 2023 16:16:05 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id 4E4638D0002 for ; Fri, 17 Nov 2023 16:16:05 -0500 (EST) Received: from smtpin03.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay08.hostedemail.com (Postfix) with ESMTP id 1F8551406B4 for ; Fri, 17 Nov 2023 21:16:05 +0000 (UTC) X-FDA: 81468703890.03.9680DB4 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by imf08.hostedemail.com (Postfix) with ESMTP id 5F13216000A for ; Fri, 17 Nov 2023 21:16:03 +0000 (UTC) Authentication-Results: imf08.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=LhFGWUfr; spf=pass (imf08.hostedemail.com: domain of dhowells@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1700255763; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=Dka1EwiXDRUytdRCyJT/oQw9pikuMSUHi7xS1VhzWac=; b=h1mBvQEJsenQ2YtBptLjrSO2MicE6kVmeMpC3WlGgcQkoKlqJ1YHkrp7rGWgt78irKildN NuJ5mx0F2jefRrjnH0mT9MgB+K+LQGKxXhJXd51ItF1JO3Ho7lBlaVSmV1HZUGGvvRSKuM Zx1N+v1iDtt0vugCBlDXrZS1tq6tT1I= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1700255763; a=rsa-sha256; cv=none; b=TPlDGBzres7Ncij2s6qLmpuZmcA3akcSJi61wclN43xijpdfziuUSTMN8N5KHBDNxYXOTG 9CseqZfq3vGXNX628y/Q2RJ8715c6vAmdl3mx3uxdE5bknXHzLSHLGck2alhCwH70lRfwm iXfpXO3ppxwrGJTVkKaPWLu8Z2Zmmlo= ARC-Authentication-Results: i=1; imf08.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=LhFGWUfr; spf=pass (imf08.hostedemail.com: domain of dhowells@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1700255762; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Dka1EwiXDRUytdRCyJT/oQw9pikuMSUHi7xS1VhzWac=; b=LhFGWUfrzmoM9vwyrtTo0bYJRpuM8LeBgsf0Ng2mc13oe17KHpWL8lctkRJhVl7dZrTvjG DLuUdiLHnHoDyoP3YM2VkD8/R90t/+7cO4epo++ZKOSwe8Lf4zpfEOeOb2zZEt/miMtR6j eYzbSCOYakiQSC+tRp3uwcWQIVn00bk= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-50-sqDwWwknOjOxLJdA_LpJWQ-1; Fri, 17 Nov 2023 16:15:57 -0500 X-MC-Unique: sqDwWwknOjOxLJdA_LpJWQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2607681B560; Fri, 17 Nov 2023 21:15:56 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.16]) by smtp.corp.redhat.com (Postfix) with ESMTP id 804AD5036; Fri, 17 Nov 2023 21:15:53 +0000 (UTC) From: David Howells To: Jeff Layton , Steve French Cc: David Howells , Matthew Wilcox , Marc Dionne , Paulo Alcantara , Shyam Prasad N , Tom Talpey , Dominique Martinet , Ilya Dryomov , Christian Brauner , linux-cachefs@redhat.com, linux-afs@lists.infradead.org, linux-cifs@vger.kernel.org, linux-nfs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 02/51] netfs: Track the fpos above which the server has no data Date: Fri, 17 Nov 2023 21:14:54 +0000 Message-ID: <20231117211544.1740466-3-dhowells@redhat.com> In-Reply-To: <20231117211544.1740466-1-dhowells@redhat.com> References: <20231117211544.1740466-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.5 X-Rspamd-Queue-Id: 5F13216000A X-Rspam-User: X-Rspamd-Server: rspam11 X-Stat-Signature: 7zohj4xad7btf3fd6yc8xwm3553f8rhw X-HE-Tag: 1700255763-47497 X-HE-Meta: U2FsdGVkX1/Z12OVQ46Q9ZqQ2kTTu/JmjwOq0vYBLVJKcI2yc0j4A/aEEMcMlboJWwNT66pSJK0a2Ram44OQm93G9JnHS0KPNwB43PtGrixOV6/w1V6rmF+o46q4JZX5Ggye8IpcyPPL/UM9lbN9WlLiIF801oGQE+7gg+CkiAAL/k3oQGBdCcnnB6AqtMgGLpaLfXLl2iO5ToMbfXs0PDHccnD1F+MxA4NiAnfVJgYF1OruIKW+tOlaLtWG7MAp7C/9lR7MnAjmnoSzjovxKvRhxxIROwQreEPKXkEfUrkLxyxhm9btK4BAyqyqRujLwsSMr05FDV4/NLPFzPJ77WGAV0eCfWPHpSfgGDjSoTWIBXXGKjOyJtfbHMuHZ/6RtjSpp7EnQAovLlPzpAdM2vKr+WxsmNXZGVz8a+dwtKE40LgthKWqW2MypgeAapckRVHUQAqmBiG4memLY5u5+5kERVSCYD8bPRKyc/UpUono5EJmCFghqAqwtLQhqBCf6bTmdBIO06inOUKpDwyTB+0VA+VNEbrQyIcVGstRKt76f1PTQo4DCv+iLfE8yOwNnn0ks9IMT9Wj89hQvWcSEItboq/v/dlXKWfjRLRjhnhiBErucOxebklOZR88P3rduDyIsFgxQXuME1Xnl93tCI0cPydEj42HcABVohEqAP55tn/aZqsuC1+kM0wQHmV+Aqk5xihynR9+ghw3WPzl7qlBEKXdaXOzreIpkXM2ITInDGQQTnRCnFihLeymzcbXXqv9uZgdy8R5ypm5G82GsGJYAxkgKJrGqGmDmD8uYMd9EFiaOYckfQKq5o6zYojS5YGXiQSNhybYY86E64AbLKEnT+3p73v+JHmuLVPQopt2pWPZK2rm+IFBLvVLj0EdXG2umH3ZuPUG0JTKuk844C/kqYu0szI+gm++MEpNkwyJrBJRfrMWHmjp5Fu3oS9q2San5kSKhAdJhZ+pJV/ BWKaHC1K JeJkyLMHbXXr8lZaBwuAqoe2E1g5JYKogG0zLXNM7Qqmre4ycddPaTvmWIaoX1041pDiZ0fHuw8DPA+Bq8H0TKfbFrkLuPpsUrO6Wi1rGl+92J7Uzdh+InU8DVRCcUHHB0HXuvJuJCwuJWZZ8OtmxpgvqJVDl0iHrr/y4weaChRg9BM/M6Fnl5X7pSzUAtXP51g2fpGQuaObetoGoYBFc/G5xOddR9MgLttr2Zsh1VSdWgCvgOfcvDICOy2ag6dyIgQsayy8s9sO/Xru+e6fZq5Fw34RcLbH2C7B3Oy9DjYPSZJU= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Track the file position above which the server is not expected to have any data and preemptively assume that we can simply fill blocks with zeroes locally rather than attempting to download them - even if we've written data back to the server. Assume that any data that was written back above that position is held in the local cache. Call this the "zero point". Make use of this to optimise away some reads from the server. We need to set the zero point in the following circumstances: (1) When we see an extant remote inode and have no cache for it, we set the zero_point to i_size. (2) On local inode creation, we set zero_point to 0. (3) On local truncation down, we reduce zero_point to the new i_size if the new i_size is lower. (4) On local truncation up, we don't change zero_point. (5) On local modification, we don't change zero_point. (6) On remote invalidation, we set zero_point to the new i_size. (7) If stored data is culled from fscache, we must set zero_point above that if the data also got written to the server. (8) If dirty data is written back to the server, but not fscache, we must set zero_point above that. Assuming the above, any read from the server at or above the zero_point position will return all zeroes. The zero_point value can be stored in the cache, provided the above rules are applied to it by any code that culls part of the local cache. Signed-off-by: David Howells cc: Jeff Layton cc: linux-cachefs@redhat.com cc: linux-fsdevel@vger.kernel.org cc: linux-mm@kvack.org --- fs/afs/inode.c | 13 +++++++------ fs/netfs/buffered_read.c | 40 +++++++++++++++++++++++++--------------- include/linux/netfs.h | 5 +++++ 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 78efc9719349..8b4c2ef610ee 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -252,6 +252,7 @@ static void afs_apply_status(struct afs_operation *op, vnode->netfs.remote_i_size = status->size; if (change_size) { afs_set_i_size(vnode, status->size); + vnode->netfs.zero_point = status->size; inode_set_ctime_to_ts(inode, t); inode_set_atime_to_ts(inode, t); } @@ -865,17 +866,17 @@ static void afs_setattr_success(struct afs_operation *op) static void afs_setattr_edit_file(struct afs_operation *op) { struct afs_vnode_param *vp = &op->file[0]; - struct inode *inode = &vp->vnode->netfs.inode; + struct afs_vnode *vnode = vp->vnode; if (op->setattr.attr->ia_valid & ATTR_SIZE) { loff_t size = op->setattr.attr->ia_size; loff_t i_size = op->setattr.old_i_size; - if (size < i_size) - truncate_pagecache(inode, size); - if (size != i_size) - fscache_resize_cookie(afs_vnode_cache(vp->vnode), - vp->scb.status.size); + if (size != i_size) { + truncate_pagecache(&vnode->netfs.inode, size); + netfs_resize_file(&vnode->netfs, size); + fscache_resize_cookie(afs_vnode_cache(vnode), size); + } } } diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c index 2cd3ccf4c439..a2852fa64ad0 100644 --- a/fs/netfs/buffered_read.c +++ b/fs/netfs/buffered_read.c @@ -147,6 +147,22 @@ static void netfs_rreq_expand(struct netfs_io_request *rreq, } } +/* + * Begin an operation, and fetch the stored zero point value from the cookie if + * available. + */ +static int netfs_begin_cache_operation(struct netfs_io_request *rreq, + struct netfs_inode *ctx) +{ + int ret = -ENOBUFS; + + if (ctx->ops->begin_cache_operation) { + ret = ctx->ops->begin_cache_operation(rreq); + /* TODO: Get the zero point value from the cache */ + } + return ret; +} + /** * netfs_readahead - Helper to manage a read request * @ractl: The description of the readahead request @@ -180,11 +196,9 @@ void netfs_readahead(struct readahead_control *ractl) if (IS_ERR(rreq)) return; - if (ctx->ops->begin_cache_operation) { - ret = ctx->ops->begin_cache_operation(rreq); - if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS) - goto cleanup_free; - } + ret = netfs_begin_cache_operation(rreq, ctx); + if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS) + goto cleanup_free; netfs_stat(&netfs_n_rh_readahead); trace_netfs_read(rreq, readahead_pos(ractl), readahead_length(ractl), @@ -238,11 +252,9 @@ int netfs_read_folio(struct file *file, struct folio *folio) goto alloc_error; } - if (ctx->ops->begin_cache_operation) { - ret = ctx->ops->begin_cache_operation(rreq); - if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS) - goto discard; - } + ret = netfs_begin_cache_operation(rreq, ctx); + if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS) + goto discard; netfs_stat(&netfs_n_rh_readpage); trace_netfs_read(rreq, rreq->start, rreq->len, netfs_read_trace_readpage); @@ -390,11 +402,9 @@ int netfs_write_begin(struct netfs_inode *ctx, rreq->no_unlock_folio = folio_index(folio); __set_bit(NETFS_RREQ_NO_UNLOCK_FOLIO, &rreq->flags); - if (ctx->ops->begin_cache_operation) { - ret = ctx->ops->begin_cache_operation(rreq); - if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS) - goto error_put; - } + ret = netfs_begin_cache_operation(rreq, ctx); + if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS) + goto error_put; netfs_stat(&netfs_n_rh_write_begin); trace_netfs_read(rreq, pos, len, netfs_read_trace_write_begin); diff --git a/include/linux/netfs.h b/include/linux/netfs.h index b447cb67f599..282511090ead 100644 --- a/include/linux/netfs.h +++ b/include/linux/netfs.h @@ -129,6 +129,8 @@ struct netfs_inode { struct fscache_cookie *cache; #endif loff_t remote_i_size; /* Size of the remote file */ + loff_t zero_point; /* Size after which we assume there's no data + * on the server */ }; /* @@ -330,6 +332,7 @@ static inline void netfs_inode_init(struct netfs_inode *ctx, { ctx->ops = ops; ctx->remote_i_size = i_size_read(&ctx->inode); + ctx->zero_point = ctx->remote_i_size; #if IS_ENABLED(CONFIG_FSCACHE) ctx->cache = NULL; #endif @@ -345,6 +348,8 @@ static inline void netfs_inode_init(struct netfs_inode *ctx, static inline void netfs_resize_file(struct netfs_inode *ctx, loff_t new_i_size) { ctx->remote_i_size = new_i_size; + if (new_i_size < ctx->zero_point) + ctx->zero_point = new_i_size; } /**