From patchwork Mon Oct 18 14:50:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566803 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 138B3C43217 for ; Mon, 18 Oct 2021 14:50:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EDC8E60174 for ; Mon, 18 Oct 2021 14:50:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232349AbhJROxJ (ORCPT ); Mon, 18 Oct 2021 10:53:09 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:32791 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232367AbhJROxH (ORCPT ); Mon, 18 Oct 2021 10:53:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568656; 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=P95aW/RbR+r1COvJ74mVrlADYswdjosag/BwZTtJNaY=; b=NdcJB/pxv2QPzJY1eHc1tfynAHp+oqLPBToDW3DBBSwto7eM+/HSYK/wJ4AekZi7hRQS+1 v7DLcj2f3duwwTXnTf6lcJ0sg6yCzGTF8b/JmsyadmpjH9bU4wjNqirDksoSubo79aNRtF nwg1wY2tfv+Nht2LFvg8Xi2M3Um+Zso= 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-563-FixGoYv8MVG7e7jQf6HPwA-1; Mon, 18 Oct 2021 10:50:51 -0400 X-MC-Unique: FixGoYv8MVG7e7jQf6HPwA-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 89135800685; Mon, 18 Oct 2021 14:50:47 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0D4EE709B7; Mon, 18 Oct 2021 14:50:32 +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 01/67] mm: Stop filemap_read() from grabbing a superfluous page From: David Howells To: linux-cachefs@redhat.com Cc: Kent Overstreet , "Matthew Wilcox (Oracle)" , linux-mm@kvack.org, linux-fsdevel@vger.kernel.org, dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:50:32 +0100 Message-ID: <163456863216.2614702.6384850026368833133.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Under some circumstances, filemap_read() will allocate sufficient pages to read to the end of the file, call readahead/readpages on them and copy the data over - and then it will allocate another page at the EOF and call readpage on that and then ignore it. This is unnecessary and a waste of time and resources. filemap_read() *does* check for this, but only after it has already done the allocation and I/O. Fix this by checking before calling filemap_get_pages() also. Signed-off-by: David Howells Acked-by: Kent Overstreet cc: Matthew Wilcox (Oracle) cc: linux-mm@kvack.org cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/160588481358.3465195.16552616179674485179.stgit@warthog.procyon.org.uk/ Acked-by: Jeff Layton --- mm/filemap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mm/filemap.c b/mm/filemap.c index dae481293b5d..c0cdc44c844e 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2625,6 +2625,10 @@ ssize_t filemap_read(struct kiocb *iocb, struct iov_iter *iter, if ((iocb->ki_flags & IOCB_WAITQ) && already_read) iocb->ki_flags |= IOCB_NOWAIT; + isize = i_size_read(inode); + if (unlikely(iocb->ki_pos >= isize)) + goto put_pages; + error = filemap_get_pages(iocb, iter, &pvec); if (error < 0) break; From patchwork Mon Oct 18 14:50:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566805 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D61A1C433EF for ; Mon, 18 Oct 2021 14:51:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BE03A61002 for ; Mon, 18 Oct 2021 14:51:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232409AbhJROxd (ORCPT ); Mon, 18 Oct 2021 10:53:33 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:30356 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232484AbhJROxU (ORCPT ); Mon, 18 Oct 2021 10:53:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568665; 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=MQJs2+aC8IkP0rTc6pY/MWaR3TYnd2aoUDR2s9BzwT4=; b=dyVfrx2RK6rzlockXmNHahNDaBkouXA2uo0PL9fF9ReDVVor/7QC/5b5jLQfZr4mf6Gn83 YQElYdnh6BFnvyfHS0ftcHgNGyN4yon5caVC0AaSwscetbacYuonA9X4myuGavFmusid42 /JjiiT4Eghpdq/4GcN+lhosxxKziPlQ= 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-49-_zcvU5ubOp6-JKrGdhZkJg-1; Mon, 18 Oct 2021 10:51:02 -0400 X-MC-Unique: _zcvU5ubOp6-JKrGdhZkJg-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 05FFF362FD; Mon, 18 Oct 2021 14:51:00 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id A9BFA5F4F5; Mon, 18 Oct 2021 14:50:53 +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 02/67] vfs: Provide S_KERNEL_FILE inode flag From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:50:52 +0100 Message-ID: <163456865277.2614702.2064731306330022896.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Provide an S_KERNEL_FILE inode flag that a kernel service, e.g. cachefiles, can set to ward off other kernel services and drivers (including itself) from using files it is actively using. Signed-off-by: David Howells --- include/linux/fs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/fs.h b/include/linux/fs.h index e7a633353fd2..197493507744 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2250,6 +2250,7 @@ struct super_operations { #define S_ENCRYPTED (1 << 14) /* Encrypted file (using fs/crypto/) */ #define S_CASEFOLD (1 << 15) /* Casefolded file */ #define S_VERITY (1 << 16) /* Verity file (using fs/verity/) */ +#define S_KERNEL_FILE (1 << 17) /* File is in use by the kernel (eg. fs/cachefiles) */ /* * Note that nosuid etc flags are inode-specific: setting some file-system From patchwork Mon Oct 18 14:51:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566807 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C0D92C43217 for ; Mon, 18 Oct 2021 14:51:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A71DC61283 for ; Mon, 18 Oct 2021 14:51:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232504AbhJROxl (ORCPT ); Mon, 18 Oct 2021 10:53:41 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:35845 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232380AbhJROxc (ORCPT ); Mon, 18 Oct 2021 10:53:32 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568678; 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=2sONkJBvmJgTAHpzc86BA8e42PAvAoDrxKKcAcC4xT4=; b=PaSg29MqowhoDp1bJo33ekLQ2mcsFt0Q/ijSVwzJYVJYjYm7LcXOFZyllXlegt4lN6NxsX XzZNKqAEGhzxkVGYB1I8S4n98oLvrfaWmdddS7AY3z9l/XUltoERscOtm/9IpLApaA+ZLh dxPfowNWam+kf+kaxA1m683IBZN3yr0= 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-504-BQPyF-z-POWSD8t89bprvw-1; Mon, 18 Oct 2021 10:51:15 -0400 X-MC-Unique: BQPyF-z-POWSD8t89bprvw-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C6450100CCC6; Mon, 18 Oct 2021 14:51:12 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 27CFF68700; Mon, 18 Oct 2021 14:51:06 +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 03/67] vfs, fscache: Force ->write_inode() to occur if cookie pinned for writeback From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:51:05 +0100 Message-ID: <163456866523.2614702.2234665737111683988.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Use an inode flag, I_PINNING_FSCACHE_WB, to indicate that a cookie is pinned in use by that inode for the purposes of writeback. Pinning is necessary because the in-use pin from the open file is released before the writeback takes place, but if the resources aren't pinned, the dirty data can't be written to the cache. Signed-off-by: David Howells --- fs/fs-writeback.c | 8 ++++++++ include/linux/fs.h | 3 +++ include/linux/fscache.h | 1 + include/linux/writeback.h | 1 + 4 files changed, 13 insertions(+) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 81ec192ce067..f3122831c4fe 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -1666,6 +1666,13 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc) if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) inode->i_state |= I_DIRTY_PAGES; + else if (unlikely(inode->i_state & I_PINNING_FSCACHE_WB)) { + if (!(inode->i_state & I_DIRTY_PAGES)) { + inode->i_state &= ~I_PINNING_FSCACHE_WB; + wbc->unpinned_fscache_wb = true; + dirty |= I_PINNING_FSCACHE_WB; /* Cause write_inode */ + } + } spin_unlock(&inode->i_lock); @@ -1675,6 +1682,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc) if (ret == 0) ret = err; } + wbc->unpinned_fscache_wb = false; trace_writeback_single_inode(inode, wbc, nr_to_write); return ret; } diff --git a/include/linux/fs.h b/include/linux/fs.h index 197493507744..336739fed3e9 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2420,6 +2420,8 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src, * Used to detect that mark_inode_dirty() should not move * inode between dirty lists. * + * I_PINNING_FSCACHE_WB Inode is pinning an fscache object for writeback. + * * Q: What is the difference between I_WILL_FREE and I_FREEING? */ #define I_DIRTY_SYNC (1 << 0) @@ -2442,6 +2444,7 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src, #define I_CREATING (1 << 15) #define I_DONTCACHE (1 << 16) #define I_SYNC_QUEUED (1 << 17) +#define I_PINNING_FSCACHE_WB (1 << 18) #define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC) #define I_DIRTY (I_DIRTY_INODE | I_DIRTY_PAGES) diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 01558d155799..ba4878b56717 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE) diff --git a/include/linux/writeback.h b/include/linux/writeback.h index d1f65adf6a26..2fda288600d3 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -69,6 +69,7 @@ struct writeback_control { unsigned for_reclaim:1; /* Invoked from the page allocator */ unsigned range_cyclic:1; /* range_start is cyclic */ unsigned for_sync:1; /* sync(2) WB_SYNC_ALL writeback */ + unsigned unpinned_fscache_wb:1; /* Cleared I_PINNING_FSCACHE_WB */ /* * When writeback IOs are bounced through async layers, only the From patchwork Mon Oct 18 14:51:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566809 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 47668C433F5 for ; Mon, 18 Oct 2021 14:51:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1AB3E61002 for ; Mon, 18 Oct 2021 14:51:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232221AbhJROx4 (ORCPT ); Mon, 18 Oct 2021 10:53:56 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:53950 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231944AbhJROx4 (ORCPT ); Mon, 18 Oct 2021 10:53:56 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568704; 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=Y+qCeINZLIBTHWSqm79M2YS4Y5x6E0M6kC+A8wDfTXg=; b=PSSoEWe4CTydOMnPYZ8+ShC6nUbhGWIg8UtrB6yept6Ha3jflROZpOwctWsDb2/8KcXC/k EquUevg1TORMKFAOwhhquDvfHQ6OFucx0/T1VNZ17Fgo1YrebjlgLD4z2vzKVP1MKW7jIk 7Pfc48KXuLkXhNZwTMvdxWaC4q1BoqM= 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-457-p0UUV0fNOhOb7l9u9xTrAw-1; Mon, 18 Oct 2021 10:51:41 -0400 X-MC-Unique: p0UUV0fNOhOb7l9u9xTrAw-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id AA271801FCE; Mon, 18 Oct 2021 14:51:38 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id E028A9935; Mon, 18 Oct 2021 14:51:18 +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 04/67] afs: Handle len being extending over page end in write_begin/write_end From: David Howells To: linux-cachefs@redhat.com Cc: "Matthew Wilcox (Oracle)" , Jeff Layton , linux-afs@lists.infradead.org, dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:51:18 +0100 Message-ID: <163456867803.2614702.7027702062884078722.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org With transparent huge pages, in the future, write_begin() and write_end() may be passed a length parameter that, in combination with the offset into the page, exceeds the length of that page. This allows grab_cache_page_write_begin() to better choose the size of THP to allocate. Fix afs's functions to handle this by trimming the length as needed after the page has been allocated. [Removed the now-unnecessary index var; spotted by kernel test robot] Fixes: e1b1240c1ff5 ("netfs: Add write_begin helper") Reported-by: Matthew Wilcox (Oracle) Signed-off-by: David Howells Acked-by: Jeff Layton cc: linux-afs@lists.infradead.org Link: https://lore.kernel.org/r/162367681795.460125.11729955608839747375.stgit@warthog.procyon.org.uk/ # v1 --- fs/afs/write.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/fs/afs/write.c b/fs/afs/write.c index f24370f5c774..c09830c9dc43 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c @@ -25,7 +25,8 @@ int afs_set_page_dirty(struct page *page) } /* - * prepare to perform part of a write to a page + * Prepare to perform part of a write to a page. Note that len may extend + * beyond the end of the page. */ int afs_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, @@ -36,7 +37,6 @@ int afs_write_begin(struct file *file, struct address_space *mapping, unsigned long priv; unsigned f, from; unsigned t, to; - pgoff_t index; int ret; _enter("{%llx:%llu},%llx,%x", @@ -51,8 +51,8 @@ int afs_write_begin(struct file *file, struct address_space *mapping, if (ret < 0) return ret; - index = page->index; - from = pos - index * PAGE_SIZE; + from = offset_in_thp(page, pos); + len = min_t(size_t, len, thp_size(page) - from); to = from + len; try_again: @@ -103,7 +103,8 @@ int afs_write_begin(struct file *file, struct address_space *mapping, } /* - * finalise part of a write to a page + * Finalise part of a write to a page. Note that len may extend beyond the end + * of the page. */ int afs_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, @@ -111,7 +112,7 @@ int afs_write_end(struct file *file, struct address_space *mapping, { struct afs_vnode *vnode = AFS_FS_I(file_inode(file)); unsigned long priv; - unsigned int f, from = pos & (thp_size(page) - 1); + unsigned int f, from = offset_in_thp(page, pos); unsigned int t, to = from + copied; loff_t i_size, maybe_i_size; From patchwork Mon Oct 18 14:51:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566811 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81E99C4332F for ; Mon, 18 Oct 2021 14:52:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6968860E0B for ; Mon, 18 Oct 2021 14:52:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232490AbhJROyO (ORCPT ); Mon, 18 Oct 2021 10:54:14 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:40053 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232539AbhJROyJ (ORCPT ); Mon, 18 Oct 2021 10:54:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568718; 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=J2pO0HYOIIwD/Lw/VU0P6w15qtVfjBqMaV1iunSc4EI=; b=Bf7mvUcLvbfo0fI58x35zipm8ZLEXcIjntpxCI3TE+4oEI7t9NYlvl5zIonBWWKXcPBLWy R0R8TfHREK1jwnLnAxq+8TB2guoEDYNsZaS/6gfe8qYzUaIOL+l0z2rAbEN9DzXSnxOWda 3kxzIjRLyE6n/vxggNH58q4DljN/BZ0= 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-174-SRK6oy3jNimOUw2cLzn71A-1; Mon, 18 Oct 2021 10:51:55 -0400 X-MC-Unique: SRK6oy3jNimOUw2cLzn71A-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id B055A362F9; Mon, 18 Oct 2021 14:51:52 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id C0EBB5F4EE; Mon, 18 Oct 2021 14:51:44 +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 05/67] afs: Fix afs_write_end() to handle len > page size From: David Howells To: linux-cachefs@redhat.com Cc: Jeff Layton , Jeff Layton , Al Viro , Matthew Wilcox , linux-afs@lists.infradead.org, dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:51:43 +0100 Message-ID: <163456870391.2614702.14754663282861965969.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org It is possible for the len argument to afs_write_end() to overrun the end of the page (len is used to key the size of the page in afs_write_start() when compound pages become a regular thing). Fix afs_write_end() to correctly trim the write length so that it doesn't exceed the end of the page. Fixes: 3003bbd0697b ("afs: Use the netfs_write_begin() helper") Reported-by: Jeff Layton Signed-off-by: David Howells Acked-by: Jeff Layton cc: Al Viro cc: Matthew Wilcox cc: linux-afs@lists.infradead.org Link: https://lore.kernel.org/r/162367682522.460125.5652091227576721609.stgit@warthog.procyon.org.uk/ # v1 --- fs/afs/write.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/afs/write.c b/fs/afs/write.c index c09830c9dc43..e1cb19cb6314 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c @@ -119,6 +119,7 @@ int afs_write_end(struct file *file, struct address_space *mapping, _enter("{%llx:%llu},{%lx}", vnode->fid.vid, vnode->fid.vnode, page->index); + len = min_t(size_t, len, thp_size(page) - from); if (!PageUptodate(page)) { if (copied < len) { copied = 0; From patchwork Mon Oct 18 14:51:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566813 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6ACF6C433FE for ; Mon, 18 Oct 2021 14:52:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 51AF560E0B for ; Mon, 18 Oct 2021 14:52:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232517AbhJROyn (ORCPT ); Mon, 18 Oct 2021 10:54:43 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:31259 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232221AbhJROyn (ORCPT ); Mon, 18 Oct 2021 10:54:43 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568751; 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=ZPebOEkrhJRGKoG40mJY0j5y/dUWS6qG5BKUsEA5eHA=; b=ixd10weUfUK2xbrz0r8iV9Jwcwna3otopi/oODbSsva3H8mdNrKYgkY+aCxNTu1OxUi9Be FWtUJYxVhPOwi6DA/TRr541BisiYYKuzCf6tn0fnGqDtS4rdipIFk2Xr0JtU54LHtgytYb ELrJvJBGsMd6x9wE/vrCHSR5cgZOR2Y= 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-255-NzHeTYPMOSaXsZFQiybRTQ-1; Mon, 18 Oct 2021 10:52:27 -0400 X-MC-Unique: NzHeTYPMOSaXsZFQiybRTQ-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 03E5F8042DF; Mon, 18 Oct 2021 14:52:25 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id C84281017CE5; Mon, 18 Oct 2021 14:51:58 +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 06/67] nfs, cifs, ceph, 9p: Disable use of fscache prior to its rewrite From: David Howells To: linux-cachefs@redhat.com Cc: Dave Wysochanski , Trond Myklebust , Anna Schumaker , linux-nfs@vger.kernel.org, Jeff Layton , Ilya Dryomov , ceph-devel@vger.kernel.org, Steve French , linux-cifs@vger.kernel.org, Eric Van Hensbergen , Latchesar Ionkov , Dominique Martinet , v9fs-developer@lists.sourceforge.net, dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:51:57 +0100 Message-ID: <163456871794.2614702.15398637170877934146.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Temporarily disable the use of fscache by the various Linux network filesystems, apart from afs, so that the fscache core can be rewritten. Signed-off-by: David Howells cc: Dave Wysochanski cc: Trond Myklebust cc: Anna Schumaker cc: linux-nfs@vger.kernel.org cc: Jeff Layton cc: Ilya Dryomov cc: ceph-devel@vger.kernel.org cc: Steve French cc: linux-cifs@vger.kernel.org cc: Eric Van Hensbergen cc: Latchesar Ionkov cc: Dominique Martinet cc: v9fs-developer@lists.sourceforge.net --- fs/9p/Kconfig | 2 +- fs/ceph/Kconfig | 2 +- fs/cifs/Kconfig | 2 +- fs/fscache/Kconfig | 4 ++++ fs/nfs/Kconfig | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/fs/9p/Kconfig b/fs/9p/Kconfig index d7bc93447c85..b11c15c30bac 100644 --- a/fs/9p/Kconfig +++ b/fs/9p/Kconfig @@ -14,7 +14,7 @@ config 9P_FS if 9P_FS config 9P_FSCACHE bool "Enable 9P client caching support" - depends on 9P_FS=m && FSCACHE || 9P_FS=y && FSCACHE=y + depends on 9P_FS=m && FSCACHE_OLD || 9P_FS=y && FSCACHE_OLD=y help Choose Y here to enable persistent, read-only local caching support for 9p clients using FS-Cache diff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig index 94df854147d3..77ad452337ee 100644 --- a/fs/ceph/Kconfig +++ b/fs/ceph/Kconfig @@ -21,7 +21,7 @@ config CEPH_FS if CEPH_FS config CEPH_FSCACHE bool "Enable Ceph client caching support" - depends on CEPH_FS=m && FSCACHE || CEPH_FS=y && FSCACHE=y + depends on CEPH_FS=m && FSCACHE_OLD || CEPH_FS=y && FSCACHE_OLD=y help Choose Y here to enable persistent, read-only local caching support for Ceph clients using FS-Cache diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig index 3b7e3b9e4fd2..c5477abbcff0 100644 --- a/fs/cifs/Kconfig +++ b/fs/cifs/Kconfig @@ -188,7 +188,7 @@ config CIFS_SMB_DIRECT config CIFS_FSCACHE bool "Provide CIFS client caching support" - depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y + depends on CIFS=m && FSCACHE_OLD || CIFS=y && FSCACHE_OLD=y help Makes CIFS FS-Cache capable. Say Y here if you want your CIFS data to be cached locally on disk through the general filesystem cache diff --git a/fs/fscache/Kconfig b/fs/fscache/Kconfig index b313a978ae0a..7850de3bdee0 100644 --- a/fs/fscache/Kconfig +++ b/fs/fscache/Kconfig @@ -38,3 +38,7 @@ config FSCACHE_DEBUG enabled by setting bits in /sys/modules/fscache/parameter/debug. See Documentation/filesystems/caching/fscache.rst for more information. + +config FSCACHE_OLD + bool + default n diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig index 14a72224b657..a8b73c90aa00 100644 --- a/fs/nfs/Kconfig +++ b/fs/nfs/Kconfig @@ -170,7 +170,7 @@ config ROOT_NFS config NFS_FSCACHE bool "Provide NFS client caching support" - depends on NFS_FS=m && FSCACHE || NFS_FS=y && FSCACHE=y + depends on NFS_FS=m && FSCACHE_OLD || NFS_FS=y && FSCACHE_OLD=y help Say Y here if you want NFS data to be cached locally on disc through the general filesystem cache manager From patchwork Mon Oct 18 14:52:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566815 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E5511C433EF for ; Mon, 18 Oct 2021 14:52:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C2A0861002 for ; Mon, 18 Oct 2021 14:52:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232506AbhJROyy (ORCPT ); Mon, 18 Oct 2021 10:54:54 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:43114 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232617AbhJROyv (ORCPT ); Mon, 18 Oct 2021 10:54:51 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568760; 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=EZ54nn/oL4EcNWMOeJEM4UG5E0gw2fL6+laVKhVi+9k=; b=QvRE8oJU5jrlUS2Bo41LkQwbU25Vt/RwSXs/Btt/Jz21hp00ySkW6+RRGFVxu8L2xlXXVg mTG8vSPL9Lhs+pHvO2HtnvGH1CkFWqjB6Gmi2YQMIJvDdnBvDvGhJv0NFwXpPApRDpuwxQ 8xSRW+E1zD/fZI20qnpsWNFoM4WDVaM= 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-184-c20SFRN4OGCOPuqYT1SEng-1; Mon, 18 Oct 2021 10:52:36 -0400 X-MC-Unique: c20SFRN4OGCOPuqYT1SEng-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id B61EC362FA; Mon, 18 Oct 2021 14:52:34 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 021146A75A; Mon, 18 Oct 2021 14:52:30 +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 07/67] fscache: Remove the netfs data from the cookie From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:52:30 +0100 Message-ID: <163456875022.2614702.16319425026413735075.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Remove the netfs data pointer from the cookie so that we don't refer back to the netfs state and don't need accessors to manage this. Keep the information we do need (of which there's not actually a lot) in the cookie which we can keep hold of if the netfs state goes away. Signed-off-by: David Howells --- fs/afs/cache.c | 39 -------- fs/afs/cell.c | 3 - fs/afs/inode.c | 3 - fs/afs/volume.c | 4 - fs/cachefiles/interface.c | 104 +++------------------ fs/cachefiles/internal.h | 20 +--- fs/cachefiles/namei.c | 10 +- fs/cachefiles/xattr.c | 202 +++++++---------------------------------- fs/fscache/cache.c | 20 +--- fs/fscache/cookie.c | 33 +++---- fs/fscache/fsdef.c | 37 -------- fs/fscache/internal.h | 29 ++++-- fs/fscache/netfs.c | 3 - fs/fscache/object.c | 49 ---------- include/linux/fscache-cache.h | 32 +++++- include/linux/fscache.h | 39 +------- 16 files changed, 136 insertions(+), 491 deletions(-) diff --git a/fs/afs/cache.c b/fs/afs/cache.c index 037af93e3aba..9b2de3014dbf 100644 --- a/fs/afs/cache.c +++ b/fs/afs/cache.c @@ -8,11 +8,6 @@ #include #include "internal.h" -static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data, - const void *buffer, - uint16_t buflen, - loff_t object_size); - struct fscache_netfs afs_cache_netfs = { .name = "afs", .version = 2, @@ -31,38 +26,4 @@ struct fscache_cookie_def afs_volume_cache_index_def = { struct fscache_cookie_def afs_vnode_cache_index_def = { .name = "AFS.vnode", .type = FSCACHE_COOKIE_TYPE_DATAFILE, - .check_aux = afs_vnode_cache_check_aux, }; - -/* - * check that the auxiliary data indicates that the entry is still valid - */ -static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data, - const void *buffer, - uint16_t buflen, - loff_t object_size) -{ - struct afs_vnode *vnode = cookie_netfs_data; - struct afs_vnode_cache_aux aux; - - _enter("{%llx,%x,%llx},%p,%u", - vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version, - buffer, buflen); - - memcpy(&aux, buffer, sizeof(aux)); - - /* check the size of the data is what we're expecting */ - if (buflen != sizeof(aux)) { - _leave(" = OBSOLETE [len %hx != %zx]", buflen, sizeof(aux)); - return FSCACHE_CHECKAUX_OBSOLETE; - } - - if (vnode->status.data_version != aux.data_version) { - _leave(" = OBSOLETE [vers %llx != %llx]", - aux.data_version, vnode->status.data_version); - return FSCACHE_CHECKAUX_OBSOLETE; - } - - _leave(" = SUCCESS"); - return FSCACHE_CHECKAUX_OKAY; -} diff --git a/fs/afs/cell.c b/fs/afs/cell.c index d88407fb9bc0..416f9bd638a5 100644 --- a/fs/afs/cell.c +++ b/fs/afs/cell.c @@ -683,9 +683,10 @@ static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell) #ifdef CONFIG_AFS_FSCACHE cell->cache = fscache_acquire_cookie(afs_cache_netfs.primary_index, &afs_cell_cache_index_def, + NULL, cell->name, strlen(cell->name), NULL, 0, - cell, 0, true); + 0, true); #endif ret = afs_proc_cell_setup(cell); if (ret < 0) diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 8fcffea2daf5..3b696ac7c05a 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -432,9 +432,10 @@ static void afs_get_inode_cache(struct afs_vnode *vnode) vnode->cache = fscache_acquire_cookie(vnode->volume->cache, &afs_vnode_cache_index_def, + NULL, &key, sizeof(key), &aux, sizeof(aux), - vnode, vnode->status.size, true); + vnode->status.size, true); #endif } diff --git a/fs/afs/volume.c b/fs/afs/volume.c index f84194b791d3..9ca246ab1a86 100644 --- a/fs/afs/volume.c +++ b/fs/afs/volume.c @@ -273,9 +273,9 @@ void afs_activate_volume(struct afs_volume *volume) #ifdef CONFIG_AFS_FSCACHE volume->cache = fscache_acquire_cookie(volume->cell->cache, &afs_volume_cache_index_def, + NULL, &volume->vid, sizeof(volume->vid), - NULL, 0, - volume, 0, true); + NULL, 0, 0, true); #endif } diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 83671488a323..6c48e81deccc 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -7,13 +7,9 @@ #include #include +#include #include "internal.h" -struct cachefiles_lookup_data { - struct cachefiles_xattr *auxdata; /* auxiliary data */ - char *key; /* key path */ -}; - static int cachefiles_attr_changed(struct fscache_object *_object); /* @@ -23,11 +19,9 @@ static struct fscache_object *cachefiles_alloc_object( struct fscache_cache *_cache, struct fscache_cookie *cookie) { - struct cachefiles_lookup_data *lookup_data; struct cachefiles_object *object; struct cachefiles_cache *cache; - struct cachefiles_xattr *auxdata; - unsigned keylen, auxlen; + unsigned keylen; void *buffer, *p; char *key; @@ -35,10 +29,6 @@ static struct fscache_object *cachefiles_alloc_object( _enter("{%s},%x,", cache->cache.identifier, cookie->debug_id); - lookup_data = kmalloc(sizeof(*lookup_data), cachefiles_gfp); - if (!lookup_data) - goto nomem_lookup_data; - /* create a new object record and a temporary leaf image */ object = kmem_cache_alloc(cachefiles_object_jar, cachefiles_gfp); if (!object) @@ -62,10 +52,7 @@ static struct fscache_object *cachefiles_alloc_object( goto nomem_buffer; keylen = cookie->key_len; - if (keylen <= sizeof(cookie->inline_key)) - p = cookie->inline_key; - else - p = cookie->key; + p = fscache_get_key(cookie); memcpy(buffer + 2, p, keylen); *(uint16_t *)buffer = keylen; @@ -75,28 +62,13 @@ static struct fscache_object *cachefiles_alloc_object( /* turn the raw key into something that can work with as a filename */ key = cachefiles_cook_key(buffer, keylen + 2, object->type); + kfree(buffer); if (!key) goto nomem_key; - /* get hold of the auxiliary data and prepend the object type */ - auxdata = buffer; - auxlen = cookie->aux_len; - if (auxlen) { - if (auxlen <= sizeof(cookie->inline_aux)) - p = cookie->inline_aux; - else - p = cookie->aux; - memcpy(auxdata->data, p, auxlen); - } - - auxdata->len = auxlen + 1; - auxdata->type = cookie->type; - - lookup_data->auxdata = auxdata; - lookup_data->key = key; - object->lookup_data = lookup_data; + object->lookup_key = key; - _leave(" = %x [%p]", object->fscache.debug_id, lookup_data); + _leave(" = %x [%s]", object->fscache.debug_id, key); return &object->fscache; nomem_key: @@ -106,8 +78,6 @@ static struct fscache_object *cachefiles_alloc_object( kmem_cache_free(cachefiles_object_jar, object); fscache_object_destroyed(&cache->cache); nomem_object: - kfree(lookup_data); -nomem_lookup_data: _leave(" = -ENOMEM"); return ERR_PTR(-ENOMEM); } @@ -118,7 +88,6 @@ static struct fscache_object *cachefiles_alloc_object( */ static int cachefiles_lookup_object(struct fscache_object *_object) { - struct cachefiles_lookup_data *lookup_data; struct cachefiles_object *parent, *object; struct cachefiles_cache *cache; const struct cred *saved_cred; @@ -130,15 +99,12 @@ static int cachefiles_lookup_object(struct fscache_object *_object) parent = container_of(_object->parent, struct cachefiles_object, fscache); object = container_of(_object, struct cachefiles_object, fscache); - lookup_data = object->lookup_data; - ASSERTCMP(lookup_data, !=, NULL); + ASSERTCMP(object->lookup_key, !=, NULL); /* look up the key, creating any missing bits */ cachefiles_begin_secure(cache, &saved_cred); - ret = cachefiles_walk_to_object(parent, object, - lookup_data->key, - lookup_data->auxdata); + ret = cachefiles_walk_to_object(parent, object, object->lookup_key); cachefiles_end_secure(cache, saved_cred); /* polish off by setting the attributes of non-index files */ @@ -165,14 +131,10 @@ static void cachefiles_lookup_complete(struct fscache_object *_object) object = container_of(_object, struct cachefiles_object, fscache); - _enter("{OBJ%x,%p}", object->fscache.debug_id, object->lookup_data); + _enter("{OBJ%x}", object->fscache.debug_id); - if (object->lookup_data) { - kfree(object->lookup_data->key); - kfree(object->lookup_data->auxdata); - kfree(object->lookup_data); - object->lookup_data = NULL; - } + kfree(object->lookup_key); + object->lookup_key = NULL; } /* @@ -204,12 +166,8 @@ struct fscache_object *cachefiles_grab_object(struct fscache_object *_object, static void cachefiles_update_object(struct fscache_object *_object) { struct cachefiles_object *object; - struct cachefiles_xattr *auxdata; struct cachefiles_cache *cache; - struct fscache_cookie *cookie; const struct cred *saved_cred; - const void *aux; - unsigned auxlen; _enter("{OBJ%x}", _object->debug_id); @@ -217,40 +175,9 @@ static void cachefiles_update_object(struct fscache_object *_object) cache = container_of(object->fscache.cache, struct cachefiles_cache, cache); - if (!fscache_use_cookie(_object)) { - _leave(" [relinq]"); - return; - } - - cookie = object->fscache.cookie; - auxlen = cookie->aux_len; - - if (!auxlen) { - fscache_unuse_cookie(_object); - _leave(" [no aux]"); - return; - } - - auxdata = kmalloc(2 + auxlen + 3, cachefiles_gfp); - if (!auxdata) { - fscache_unuse_cookie(_object); - _leave(" [nomem]"); - return; - } - - aux = (auxlen <= sizeof(cookie->inline_aux)) ? - cookie->inline_aux : cookie->aux; - - memcpy(auxdata->data, aux, auxlen); - fscache_unuse_cookie(_object); - - auxdata->len = auxlen + 1; - auxdata->type = cookie->type; - cachefiles_begin_secure(cache, &saved_cred); - cachefiles_update_object_xattr(object, auxdata); + cachefiles_set_object_xattr(object, XATTR_REPLACE); cachefiles_end_secure(cache, saved_cred); - kfree(auxdata); _leave(""); } @@ -354,12 +281,7 @@ void cachefiles_put_object(struct fscache_object *_object, ASSERTCMP(object->fscache.n_ops, ==, 0); ASSERTCMP(object->fscache.n_children, ==, 0); - if (object->lookup_data) { - kfree(object->lookup_data->key); - kfree(object->lookup_data->auxdata); - kfree(object->lookup_data); - object->lookup_data = NULL; - } + kfree(object->lookup_key); cache = object->fscache.cache; fscache_object_destroy(&object->fscache); diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index de982f4f513f..f6b85c370935 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -34,7 +34,7 @@ extern unsigned cachefiles_debug; */ struct cachefiles_object { struct fscache_object fscache; /* fscache handle */ - struct cachefiles_lookup_data *lookup_data; /* cached lookup data */ + char *lookup_key; /* key to look up */ struct dentry *dentry; /* the file/dir representing this object */ struct dentry *backer; /* backing file */ loff_t i_size; /* object size */ @@ -88,15 +88,6 @@ struct cachefiles_cache { char *tag; /* cache binding tag */ }; -/* - * auxiliary data xattr buffer - */ -struct cachefiles_xattr { - uint16_t len; - uint8_t type; - uint8_t data[]; -}; - #include /* @@ -145,8 +136,7 @@ extern int cachefiles_delete_object(struct cachefiles_cache *cache, struct cachefiles_object *object); extern int cachefiles_walk_to_object(struct cachefiles_object *parent, struct cachefiles_object *object, - const char *key, - struct cachefiles_xattr *auxdata); + const char *key); extern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, struct dentry *dir, const char *name); @@ -188,12 +178,8 @@ static inline void cachefiles_end_secure(struct cachefiles_cache *cache, */ extern int cachefiles_check_object_type(struct cachefiles_object *object); extern int cachefiles_set_object_xattr(struct cachefiles_object *object, - struct cachefiles_xattr *auxdata); -extern int cachefiles_update_object_xattr(struct cachefiles_object *object, - struct cachefiles_xattr *auxdata); + unsigned int xattr_flags); extern int cachefiles_check_auxdata(struct cachefiles_object *object); -extern int cachefiles_check_object_xattr(struct cachefiles_object *object, - struct cachefiles_xattr *auxdata); extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, struct dentry *dentry); diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index a9aca5ab5970..dc5e1e48c0a8 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -45,11 +45,10 @@ void __cachefiles_printk_object(struct cachefiles_object *object, spin_lock(&object->fscache.lock); cookie = object->fscache.cookie; if (cookie) { - pr_err("%scookie=%x [pr=%x nd=%p fl=%lx]\n", + pr_err("%scookie=%x [pr=%x fl=%lx]\n", prefix, cookie->debug_id, cookie->parent ? cookie->parent->debug_id : 0, - cookie->netfs_data, cookie->flags); pr_err("%skey=[%u] '", prefix, cookie->key_len); k = (cookie->key_len <= sizeof(cookie->inline_key)) ? @@ -487,8 +486,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache, */ int cachefiles_walk_to_object(struct cachefiles_object *parent, struct cachefiles_object *object, - const char *key, - struct cachefiles_xattr *auxdata) + const char *key) { struct cachefiles_cache *cache; struct dentry *dir, *next = NULL; @@ -636,7 +634,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, if (!object->new) { _debug("validate '%pd'", next); - ret = cachefiles_check_object_xattr(object, auxdata); + ret = cachefiles_check_auxdata(object); if (ret == -ESTALE) { /* delete the object (the deleter drops the directory * mutex) */ @@ -671,7 +669,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, if (object->new) { /* attach data to a newly constructed terminal object */ - ret = cachefiles_set_object_xattr(object, auxdata); + ret = cachefiles_set_object_xattr(object, XATTR_CREATE); if (ret < 0) goto check_error; } else { diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c index 9e82de668595..c99952404932 100644 --- a/fs/cachefiles/xattr.c +++ b/fs/cachefiles/xattr.c @@ -15,6 +15,11 @@ #include #include "internal.h" +struct cachefiles_xattr { + uint8_t type; + uint8_t data[]; +} __packed; + static const char cachefiles_xattr_cache[] = XATTR_USER_PREFIX "CacheFiles.cache"; @@ -98,54 +103,35 @@ int cachefiles_check_object_type(struct cachefiles_object *object) * set the state xattr on a cache file */ int cachefiles_set_object_xattr(struct cachefiles_object *object, - struct cachefiles_xattr *auxdata) -{ - struct dentry *dentry = object->dentry; - int ret; - - ASSERT(dentry); - - _enter("%p,#%d", object, auxdata->len); - - /* attempt to install the cache metadata directly */ - _debug("SET #%u", auxdata->len); - - clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags); - ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache, - &auxdata->type, auxdata->len, XATTR_CREATE); - if (ret < 0 && ret != -ENOMEM) - cachefiles_io_error_obj( - object, - "Failed to set xattr with error %d", ret); - - _leave(" = %d", ret); - return ret; -} - -/* - * update the state xattr on a cache file - */ -int cachefiles_update_object_xattr(struct cachefiles_object *object, - struct cachefiles_xattr *auxdata) + unsigned int xattr_flags) { + struct cachefiles_xattr *buf; struct dentry *dentry = object->dentry; + unsigned int len = object->fscache.cookie->aux_len; int ret; if (!dentry) return -ESTALE; - _enter("%x,#%d", object->fscache.debug_id, auxdata->len); + _enter("%x,#%d", object->fscache.debug_id, len); - /* attempt to install the cache metadata directly */ - _debug("SET #%u", auxdata->len); + buf = kmalloc(sizeof(struct cachefiles_xattr) + len, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + buf->type = object->fscache.cookie->def->type; + if (len > 0) + memcpy(buf->data, fscache_get_aux(object->fscache.cookie), len); clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags); ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache, - &auxdata->type, auxdata->len, XATTR_REPLACE); + buf, sizeof(struct cachefiles_xattr) + len, + xattr_flags); + kfree(buf); if (ret < 0 && ret != -ENOMEM) cachefiles_io_error_obj( object, - "Failed to update xattr with error %d", ret); + "Failed to set xattr with error %d", ret); _leave(" = %d", ret); return ret; @@ -156,148 +142,30 @@ int cachefiles_update_object_xattr(struct cachefiles_object *object, */ int cachefiles_check_auxdata(struct cachefiles_object *object) { - struct cachefiles_xattr *auxbuf; - enum fscache_checkaux validity; - struct dentry *dentry = object->dentry; - ssize_t xlen; - int ret; - - ASSERT(dentry); - ASSERT(d_backing_inode(dentry)); - ASSERT(object->fscache.cookie->def->check_aux); - - auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, GFP_KERNEL); - if (!auxbuf) - return -ENOMEM; - - xlen = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, - &auxbuf->type, 512 + 1); - ret = -ESTALE; - if (xlen < 1 || - auxbuf->type != object->fscache.cookie->def->type) - goto error; - - xlen--; - validity = fscache_check_aux(&object->fscache, &auxbuf->data, xlen, - i_size_read(d_backing_inode(dentry))); - if (validity != FSCACHE_CHECKAUX_OKAY) - goto error; - - ret = 0; -error: - kfree(auxbuf); - return ret; -} - -/* - * check the state xattr on a cache file - * - return -ESTALE if the object should be deleted - */ -int cachefiles_check_object_xattr(struct cachefiles_object *object, - struct cachefiles_xattr *auxdata) -{ - struct cachefiles_xattr *auxbuf; + struct cachefiles_xattr *buf; struct dentry *dentry = object->dentry; - int ret; - - _enter("%p,#%d", object, auxdata->len); + unsigned int len = object->fscache.cookie->aux_len, tlen; + const void *p = fscache_get_aux(object->fscache.cookie); + ssize_t ret; ASSERT(dentry); ASSERT(d_backing_inode(dentry)); - auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, cachefiles_gfp); - if (!auxbuf) { - _leave(" = -ENOMEM"); + tlen = sizeof(struct cachefiles_xattr) + len; + buf = kmalloc(tlen, GFP_KERNEL); + if (!buf) return -ENOMEM; - } - - /* read the current type label */ - ret = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, - &auxbuf->type, 512 + 1); - if (ret < 0) { - if (ret == -ENODATA) - goto stale; /* no attribute - power went off - * mid-cull? */ - - if (ret == -ERANGE) - goto bad_type_length; - cachefiles_io_error_obj(object, - "Can't read xattr on %lu (err %d)", - d_backing_inode(dentry)->i_ino, -ret); - goto error; - } - - /* check the on-disk object */ - if (ret < 1) - goto bad_type_length; - - if (auxbuf->type != auxdata->type) - goto stale; - - auxbuf->len = ret; - - /* consult the netfs */ - if (object->fscache.cookie->def->check_aux) { - enum fscache_checkaux result; - unsigned int dlen; - - dlen = auxbuf->len - 1; - - _debug("checkaux %s #%u", - object->fscache.cookie->def->name, dlen); - - result = fscache_check_aux(&object->fscache, - &auxbuf->data, dlen, - i_size_read(d_backing_inode(dentry))); - - switch (result) { - /* entry okay as is */ - case FSCACHE_CHECKAUX_OKAY: - goto okay; - - /* entry requires update */ - case FSCACHE_CHECKAUX_NEEDS_UPDATE: - break; - - /* entry requires deletion */ - case FSCACHE_CHECKAUX_OBSOLETE: - goto stale; - - default: - BUG(); - } - - /* update the current label */ - ret = vfs_setxattr(&init_user_ns, dentry, - cachefiles_xattr_cache, &auxdata->type, - auxdata->len, XATTR_REPLACE); - if (ret < 0) { - cachefiles_io_error_obj(object, - "Can't update xattr on %lu" - " (error %d)", - d_backing_inode(dentry)->i_ino, -ret); - goto error; - } - } - -okay: - ret = 0; + ret = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, buf, tlen); + if (ret == tlen && + buf->type == object->fscache.cookie->def->type && + memcmp(buf->data, p, len) == 0) + ret = 0; + else + ret = -ESTALE; -error: - kfree(auxbuf); - _leave(" = %d", ret); + kfree(buf); return ret; - -bad_type_length: - pr_err("Cache object %lu xattr length incorrect\n", - d_backing_inode(dentry)->i_ino); - ret = -EIO; - goto error; - -stale: - ret = -ESTALE; - goto error; } /* diff --git a/fs/fscache/cache.c b/fs/fscache/cache.c index cfa60c2faf68..efcdb40267d6 100644 --- a/fs/fscache/cache.c +++ b/fs/fscache/cache.c @@ -30,6 +30,7 @@ struct fscache_cache_tag *__fscache_lookup_cache_tag(const char *name) list_for_each_entry(tag, &fscache_cache_tag_list, link) { if (strcmp(tag->name, name) == 0) { atomic_inc(&tag->usage); + refcount_inc(&tag->ref); up_read(&fscache_addremove_sem); return tag; } @@ -44,6 +45,7 @@ struct fscache_cache_tag *__fscache_lookup_cache_tag(const char *name) return ERR_PTR(-ENOMEM); atomic_set(&xtag->usage, 1); + refcount_set(&xtag->ref, 1); strcpy(xtag->name, name); /* write lock, search again and add if still not present */ @@ -52,6 +54,7 @@ struct fscache_cache_tag *__fscache_lookup_cache_tag(const char *name) list_for_each_entry(tag, &fscache_cache_tag_list, link) { if (strcmp(tag->name, name) == 0) { atomic_inc(&tag->usage); + refcount_inc(&tag->ref); up_write(&fscache_addremove_sem); kfree(xtag); return tag; @@ -64,7 +67,7 @@ struct fscache_cache_tag *__fscache_lookup_cache_tag(const char *name) } /* - * release a reference to a cache tag + * Unuse a cache tag */ void __fscache_release_cache_tag(struct fscache_cache_tag *tag) { @@ -77,8 +80,7 @@ void __fscache_release_cache_tag(struct fscache_cache_tag *tag) tag = NULL; up_write(&fscache_addremove_sem); - - kfree(tag); + fscache_put_cache_tag(tag); } } @@ -130,20 +132,10 @@ struct fscache_cache *fscache_select_cache_for_object( spin_unlock(&cookie->lock); - if (!cookie->def->select_cache) - goto no_preference; - - /* ask the netfs for its preference */ - tag = cookie->def->select_cache(cookie->parent->netfs_data, - cookie->netfs_data); + tag = cookie->preferred_cache; if (!tag) goto no_preference; - if (tag == ERR_PTR(-ENOMEM)) { - _leave(" = NULL [nomem tag]"); - return NULL; - } - if (!tag->cache) { _leave(" = NULL [unbacked tag]"); return NULL; diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 8a850c3d0775..a772d4b6cacd 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -43,11 +43,10 @@ static void fscache_print_cookie(struct fscache_cookie *cookie, char prefix) cookie->flags, atomic_read(&cookie->n_children), atomic_read(&cookie->n_active)); - pr_err("%c-cookie d=%p{%s} n=%p\n", + pr_err("%c-cookie d=%p{%s}\n", prefix, cookie->def, - cookie->def ? cookie->def->name : "?", - cookie->netfs_data); + cookie->def ? cookie->def->name : "?"); o = READ_ONCE(cookie->backing_objects.first); if (o) { @@ -74,6 +73,7 @@ void fscache_free_cookie(struct fscache_cookie *cookie) kfree(cookie->aux); if (cookie->key_len > sizeof(cookie->inline_key)) kfree(cookie->key); + fscache_put_cache_tag(cookie->preferred_cache); kmem_cache_free(fscache_cookie_jar, cookie); } } @@ -138,9 +138,9 @@ static atomic_t fscache_cookie_debug_id = ATOMIC_INIT(1); struct fscache_cookie *fscache_alloc_cookie( struct fscache_cookie *parent, const struct fscache_cookie_def *def, + struct fscache_cache_tag *preferred_cache, const void *index_key, size_t index_key_len, const void *aux_data, size_t aux_data_len, - void *netfs_data, loff_t object_size) { struct fscache_cookie *cookie; @@ -175,7 +175,9 @@ struct fscache_cookie *fscache_alloc_cookie( cookie->def = def; cookie->parent = parent; - cookie->netfs_data = netfs_data; + + cookie->preferred_cache = fscache_get_cache_tag(preferred_cache); + cookie->flags = (1 << FSCACHE_COOKIE_NO_DATA_YET); cookie->type = def->type; spin_lock_init(&cookie->lock); @@ -240,7 +242,6 @@ struct fscache_cookie *fscache_hash_cookie(struct fscache_cookie *candidate) * - the top level index cookie for each netfs is stored in the fscache_netfs * struct upon registration * - def points to the definition - * - the netfs_data will be passed to the functions pointed to in *def * - all attached caches will be searched to see if they contain this object * - index objects aren't stored on disk until there's a dependent file that * needs storing @@ -252,9 +253,9 @@ struct fscache_cookie *fscache_hash_cookie(struct fscache_cookie *candidate) struct fscache_cookie *__fscache_acquire_cookie( struct fscache_cookie *parent, const struct fscache_cookie_def *def, + struct fscache_cache_tag *preferred_cache, const void *index_key, size_t index_key_len, const void *aux_data, size_t aux_data_len, - void *netfs_data, loff_t object_size, bool enable) { @@ -262,9 +263,9 @@ struct fscache_cookie *__fscache_acquire_cookie( BUG_ON(!def); - _enter("{%s},{%s},%p,%u", + _enter("{%s},{%s},%u", parent ? (char *) parent->def->name : "", - def->name, netfs_data, enable); + def->name, enable); if (!index_key || !index_key_len || index_key_len > 255 || aux_data_len > 255) return NULL; @@ -288,10 +289,10 @@ struct fscache_cookie *__fscache_acquire_cookie( BUG_ON(def->type == FSCACHE_COOKIE_TYPE_INDEX && parent->type != FSCACHE_COOKIE_TYPE_INDEX); - candidate = fscache_alloc_cookie(parent, def, + candidate = fscache_alloc_cookie(parent, def, preferred_cache, index_key, index_key_len, aux_data, aux_data_len, - netfs_data, object_size); + object_size); if (!candidate) { fscache_stat(&fscache_n_acquires_oom); _leave(" [ENOMEM]"); @@ -812,7 +813,6 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, __fscache_disable_cookie(cookie, aux_data, retire); /* Clear pointers back to the netfs */ - cookie->netfs_data = NULL; cookie->def = NULL; if (cookie->parent) { @@ -978,8 +978,8 @@ static int fscache_cookies_seq_show(struct seq_file *m, void *v) if (v == &fscache_cookies) { seq_puts(m, - "COOKIE PARENT USAGE CHILD ACT TY FL DEF NETFS_DATA\n" - "======== ======== ===== ===== === == === ================ ==========\n" + "COOKIE PARENT USAGE CHILD ACT TY FL DEF \n" + "======== ======== ===== ===== === == === ================\n" ); return 0; } @@ -1001,7 +1001,7 @@ static int fscache_cookies_seq_show(struct seq_file *m, void *v) } seq_printf(m, - "%08x %08x %5u %5u %3u %s %03lx %-16s %px", + "%08x %08x %5u %5u %3u %s %03lx %-16s", cookie->debug_id, cookie->parent ? cookie->parent->debug_id : 0, refcount_read(&cookie->ref), @@ -1009,8 +1009,7 @@ static int fscache_cookies_seq_show(struct seq_file *m, void *v) atomic_read(&cookie->n_active), type, cookie->flags, - cookie->def->name, - cookie->netfs_data); + cookie->def->name); keylen = cookie->key_len; auxlen = cookie->aux_len; diff --git a/fs/fscache/fsdef.c b/fs/fscache/fsdef.c index 0402673c680e..111946ba9ce1 100644 --- a/fs/fscache/fsdef.c +++ b/fs/fscache/fsdef.c @@ -9,12 +9,6 @@ #include #include "internal.h" -static -enum fscache_checkaux fscache_fsdef_netfs_check_aux(void *cookie_netfs_data, - const void *data, - uint16_t datalen, - loff_t object_size); - /* * The root index is owned by FS-Cache itself. * @@ -64,35 +58,4 @@ EXPORT_SYMBOL(fscache_fsdef_index); struct fscache_cookie_def fscache_fsdef_netfs_def = { .name = "FSDEF.netfs", .type = FSCACHE_COOKIE_TYPE_INDEX, - .check_aux = fscache_fsdef_netfs_check_aux, }; - -/* - * check that the index structure version number stored in the auxiliary data - * matches the one the netfs gave us - */ -static enum fscache_checkaux fscache_fsdef_netfs_check_aux( - void *cookie_netfs_data, - const void *data, - uint16_t datalen, - loff_t object_size) -{ - struct fscache_netfs *netfs = cookie_netfs_data; - uint32_t version; - - _enter("{%s},,%hu", netfs->name, datalen); - - if (datalen != sizeof(version)) { - _leave(" = OBSOLETE [dl=%d v=%zu]", datalen, sizeof(version)); - return FSCACHE_CHECKAUX_OBSOLETE; - } - - memcpy(&version, data, sizeof(version)); - if (version != netfs->version) { - _leave(" = OBSOLETE [ver=%x net=%x]", version, netfs->version); - return FSCACHE_CHECKAUX_OBSOLETE; - } - - _leave(" = OKAY"); - return FSCACHE_CHECKAUX_OKAY; -} diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index 6eb3f51d7275..29f21fbd5b5d 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h @@ -24,6 +24,7 @@ #define pr_fmt(fmt) "FS-Cache: " fmt +#include #include #include #include @@ -41,6 +42,20 @@ extern struct rw_semaphore fscache_addremove_sem; extern struct fscache_cache *fscache_select_cache_for_object( struct fscache_cookie *); +static inline +struct fscache_cache_tag *fscache_get_cache_tag(struct fscache_cache_tag *tag) +{ + if (tag) + refcount_inc(&tag->ref); + return tag; +} + +static inline void fscache_put_cache_tag(struct fscache_cache_tag *tag) +{ + if (tag && refcount_dec_and_test(&tag->ref)) + kfree(tag); +} + /* * cookie.c */ @@ -50,9 +65,10 @@ extern const struct seq_operations fscache_cookies_seq_ops; extern void fscache_free_cookie(struct fscache_cookie *); extern struct fscache_cookie *fscache_alloc_cookie(struct fscache_cookie *, const struct fscache_cookie_def *, + struct fscache_cache_tag *, const void *, size_t, const void *, size_t, - void *, loff_t); + loff_t); extern struct fscache_cookie *fscache_hash_cookie(struct fscache_cookie *); extern struct fscache_cookie *fscache_cookie_get(struct fscache_cookie *, enum fscache_cookie_trace); @@ -270,16 +286,9 @@ static inline void fscache_raise_event(struct fscache_object *object, static inline void fscache_update_aux(struct fscache_cookie *cookie, const void *aux_data) { - void *p; - - if (!aux_data) - return; - if (cookie->aux_len <= sizeof(cookie->inline_aux)) - p = cookie->inline_aux; - else - p = cookie->aux; + void *p = fscache_get_aux(cookie); - if (memcmp(p, aux_data, cookie->aux_len) != 0) { + if (p && memcmp(p, aux_data, cookie->aux_len) != 0) { memcpy(p, aux_data, cookie->aux_len); set_bit(FSCACHE_COOKIE_AUX_UPDATED, &cookie->flags); } diff --git a/fs/fscache/netfs.c b/fs/fscache/netfs.c index d6bdb7b5e723..b8db06804876 100644 --- a/fs/fscache/netfs.c +++ b/fs/fscache/netfs.c @@ -22,9 +22,10 @@ int __fscache_register_netfs(struct fscache_netfs *netfs) /* allocate a cookie for the primary index */ candidate = fscache_alloc_cookie(&fscache_fsdef_index, &fscache_fsdef_netfs_def, + NULL, netfs->name, strlen(netfs->name), &netfs->version, sizeof(netfs->version), - netfs, 0); + 0); if (!candidate) { _leave(" = -ENOMEM"); return -ENOMEM; diff --git a/fs/fscache/object.c b/fs/fscache/object.c index 86ad941726f7..cdcf6720d748 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c @@ -901,55 +901,6 @@ static void fscache_dequeue_object(struct fscache_object *object) _leave(""); } -/** - * fscache_check_aux - Ask the netfs whether an object on disk is still valid - * @object: The object to ask about - * @data: The auxiliary data for the object - * @datalen: The size of the auxiliary data - * @object_size: The size of the object according to the server. - * - * This function consults the netfs about the coherency state of an object. - * The caller must be holding a ref on cookie->n_active (held by - * fscache_look_up_object() on behalf of the cache backend during object lookup - * and creation). - */ -enum fscache_checkaux fscache_check_aux(struct fscache_object *object, - const void *data, uint16_t datalen, - loff_t object_size) -{ - enum fscache_checkaux result; - - if (!object->cookie->def->check_aux) { - fscache_stat(&fscache_n_checkaux_none); - return FSCACHE_CHECKAUX_OKAY; - } - - result = object->cookie->def->check_aux(object->cookie->netfs_data, - data, datalen, object_size); - switch (result) { - /* entry okay as is */ - case FSCACHE_CHECKAUX_OKAY: - fscache_stat(&fscache_n_checkaux_okay); - break; - - /* entry requires update */ - case FSCACHE_CHECKAUX_NEEDS_UPDATE: - fscache_stat(&fscache_n_checkaux_update); - break; - - /* entry requires deletion */ - case FSCACHE_CHECKAUX_OBSOLETE: - fscache_stat(&fscache_n_checkaux_obsolete); - break; - - default: - BUG(); - } - - return result; -} -EXPORT_SYMBOL(fscache_check_aux); - /* * Asynchronously invalidate an object. */ diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index 5e610f9a524c..264b94dad5be 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -45,8 +45,9 @@ struct fscache_cache_tag { struct fscache_cache *cache; /* cache referred to by this tag */ unsigned long flags; #define FSCACHE_TAG_RESERVED 0 /* T if tag is reserved for a cache */ - atomic_t usage; - char name[]; /* tag name */ + atomic_t usage; /* Number of using netfs's */ + refcount_t ref; /* Reference count on structure */ + char name[]; /* tag name */ }; /* @@ -415,11 +416,6 @@ extern void fscache_io_error(struct fscache_cache *cache); extern bool fscache_object_sleep_till_congested(signed long *timeoutp); -extern enum fscache_checkaux fscache_check_aux(struct fscache_object *object, - const void *data, - uint16_t datalen, - loff_t object_size); - extern void fscache_object_retrying_stale(struct fscache_object *object); enum fscache_why_object_killed { @@ -431,4 +427,26 @@ enum fscache_why_object_killed { extern void fscache_object_mark_killed(struct fscache_object *object, enum fscache_why_object_killed why); +/* + * Find the key on a cookie. + */ +static inline void *fscache_get_key(struct fscache_cookie *cookie) +{ + if (cookie->key_len <= sizeof(cookie->inline_key)) + return cookie->inline_key; + else + return cookie->key; +} + +/* + * Find the auxiliary data on a cookie. + */ +static inline void *fscache_get_aux(struct fscache_cookie *cookie) +{ + if (cookie->aux_len <= sizeof(cookie->inline_aux)) + return cookie->inline_aux; + else + return cookie->aux; +} + #endif /* _LINUX_FSCACHE_CACHE_H */ diff --git a/include/linux/fscache.h b/include/linux/fscache.h index ba4878b56717..cedab654dc79 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -38,13 +38,6 @@ struct fscache_cookie; struct fscache_netfs; struct netfs_read_request; -/* result of index entry consultation */ -enum fscache_checkaux { - FSCACHE_CHECKAUX_OKAY, /* entry okay as is */ - FSCACHE_CHECKAUX_NEEDS_UPDATE, /* entry requires update */ - FSCACHE_CHECKAUX_OBSOLETE, /* entry requires deletion */ -}; - /* * fscache cookie definition */ @@ -56,26 +49,6 @@ struct fscache_cookie_def { uint8_t type; #define FSCACHE_COOKIE_TYPE_INDEX 0 #define FSCACHE_COOKIE_TYPE_DATAFILE 1 - - /* select the cache into which to insert an entry in this index - * - optional - * - should return a cache identifier or NULL to cause the cache to be - * inherited from the parent if possible or the first cache picked - * for a non-index file if not - */ - struct fscache_cache_tag *(*select_cache)( - const void *parent_netfs_data, - const void *cookie_netfs_data); - - /* consult the netfs about the state of an object - * - this function can be absent if the index carries no state data - * - the netfs data from the cookie being used as the target is - * presented, as is the auxiliary data and the object size - */ - enum fscache_checkaux (*check_aux)(void *cookie_netfs_data, - const void *data, - uint16_t datalen, - loff_t object_size); }; /* @@ -105,9 +78,9 @@ struct fscache_cookie { struct hlist_head backing_objects; /* object(s) backing this file/index */ const struct fscache_cookie_def *def; /* definition */ struct fscache_cookie *parent; /* parent of this entry */ + struct fscache_cache_tag *preferred_cache; /* The preferred cache or NULL */ struct hlist_bl_node hash_link; /* Link in hash table */ struct list_head proc_link; /* Link in proc list */ - void *netfs_data; /* back pointer to netfs */ unsigned long flags; #define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */ @@ -156,9 +129,10 @@ extern void __fscache_release_cache_tag(struct fscache_cache_tag *); extern struct fscache_cookie *__fscache_acquire_cookie( struct fscache_cookie *, const struct fscache_cookie_def *, + struct fscache_cache_tag *, const void *, size_t, const void *, size_t, - void *, loff_t, bool); + loff_t, bool); extern void __fscache_relinquish_cookie(struct fscache_cookie *, const void *, bool); extern int __fscache_check_consistency(struct fscache_cookie *, const void *); extern void __fscache_update_cookie(struct fscache_cookie *, const void *); @@ -252,6 +226,7 @@ void fscache_release_cache_tag(struct fscache_cache_tag *tag) * fscache_acquire_cookie - Acquire a cookie to represent a cache object * @parent: The cookie that's to be the parent of this one * @def: A description of the cache object, including callback operations + * @preferred_cache: The cache to use (or NULL) * @index_key: The index key for this cookie * @index_key_len: Size of the index key * @aux_data: The auxiliary data for the cookie (may be NULL) @@ -272,19 +247,19 @@ static inline struct fscache_cookie *fscache_acquire_cookie( struct fscache_cookie *parent, const struct fscache_cookie_def *def, + struct fscache_cache_tag *preferred_cache, const void *index_key, size_t index_key_len, const void *aux_data, size_t aux_data_len, - void *netfs_data, loff_t object_size, bool enable) { if (fscache_cookie_valid(parent) && fscache_cookie_enabled(parent)) - return __fscache_acquire_cookie(parent, def, + return __fscache_acquire_cookie(parent, def, preferred_cache, index_key, index_key_len, aux_data, aux_data_len, - netfs_data, object_size, enable); + object_size, enable); else return NULL; } From patchwork Mon Oct 18 14:52:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566817 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3122CC433FE for ; Mon, 18 Oct 2021 14:52:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 184D361038 for ; Mon, 18 Oct 2021 14:52:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232597AbhJROzG (ORCPT ); Mon, 18 Oct 2021 10:55:06 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:49387 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232552AbhJROzE (ORCPT ); Mon, 18 Oct 2021 10:55:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568773; 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=0ZKaCE4fwSVwbGKf5RO8OE+FE/li2jRhDZ1Q5Np39cs=; b=OHJjs3cuMyBv3XNXYUYTuu1jtWPgezgjmsyo0WrhfpQbuVliNb8CgXlu6FVWvSpgKrOm/k cxeKgovB1SlfYWwI73NCTvM7WJOX8gA70/gA8Rlcr0iIxQxtEkQeS2Rk1TpMQSvNTlvku7 IpZTCRcJq3kfPXmbKcALJWYw4fcoEX0= 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-537-DRZHjiisMZWEEXRQaN02hg-1; Mon, 18 Oct 2021 10:52:49 -0400 X-MC-Unique: DRZHjiisMZWEEXRQaN02hg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 2FE5C18125C1; Mon, 18 Oct 2021 14:52:47 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id D1A2160BF4; Mon, 18 Oct 2021 14:52:40 +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 08/67] fscache: Remove struct fscache_cookie_def From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:52:39 +0100 Message-ID: <163456875996.2614702.9722290305463927351.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Remove the cookie definition structure so that there's no pointers from that back into the network filesystem. All of the method pointers that were in there have been removed anyway. Any remaining information is stashed in the cookie. Signed-off-by: David Howells --- fs/afs/cache.c | 15 ------------ fs/afs/cell.c | 4 ++- fs/afs/inode.c | 15 +++++++----- fs/afs/internal.h | 7 ----- fs/afs/volume.c | 5 ++-- fs/cachefiles/interface.c | 4 ++- fs/cachefiles/xattr.c | 6 ++--- fs/fscache/cookie.c | 51 ++++++++++++++++++---------------------- fs/fscache/fsdef.c | 17 +------------ fs/fscache/internal.h | 5 ++-- fs/fscache/io.c | 2 +- fs/fscache/netfs.c | 5 ++-- fs/fscache/object.c | 2 +- fs/fscache/page.c | 2 +- include/linux/fscache.h | 37 +++++++++++++++-------------- include/trace/events/fscache.h | 2 +- 16 files changed, 73 insertions(+), 106 deletions(-) diff --git a/fs/afs/cache.c b/fs/afs/cache.c index 9b2de3014dbf..0ee9ede6fc67 100644 --- a/fs/afs/cache.c +++ b/fs/afs/cache.c @@ -12,18 +12,3 @@ struct fscache_netfs afs_cache_netfs = { .name = "afs", .version = 2, }; - -struct fscache_cookie_def afs_cell_cache_index_def = { - .name = "AFS.cell", - .type = FSCACHE_COOKIE_TYPE_INDEX, -}; - -struct fscache_cookie_def afs_volume_cache_index_def = { - .name = "AFS.volume", - .type = FSCACHE_COOKIE_TYPE_INDEX, -}; - -struct fscache_cookie_def afs_vnode_cache_index_def = { - .name = "AFS.vnode", - .type = FSCACHE_COOKIE_TYPE_DATAFILE, -}; diff --git a/fs/afs/cell.c b/fs/afs/cell.c index 416f9bd638a5..ebf140317232 100644 --- a/fs/afs/cell.c +++ b/fs/afs/cell.c @@ -682,7 +682,9 @@ static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell) #ifdef CONFIG_AFS_FSCACHE cell->cache = fscache_acquire_cookie(afs_cache_netfs.primary_index, - &afs_cell_cache_index_def, + FSCACHE_COOKIE_TYPE_INDEX, + "AFS.cell", + 0, NULL, cell->name, strlen(cell->name), NULL, 0, diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 3b696ac7c05a..f761c9a5067f 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -430,12 +430,15 @@ static void afs_get_inode_cache(struct afs_vnode *vnode) key.vnode_id_ext[1] = vnode->fid.vnode_hi; aux.data_version = vnode->status.data_version; - vnode->cache = fscache_acquire_cookie(vnode->volume->cache, - &afs_vnode_cache_index_def, - NULL, - &key, sizeof(key), - &aux, sizeof(aux), - vnode->status.size, true); + vnode->cache = fscache_acquire_cookie( + vnode->volume->cache, + FSCACHE_COOKIE_TYPE_DATAFILE, + "AFS.vnode", + vnode->status.type == AFS_FTYPE_FILE ? 0 : FSCACHE_ADV_SINGLE_CHUNK, + NULL, + &key, sizeof(key), + &aux, sizeof(aux), + vnode->status.size, true); #endif } diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 0ad97a8fc0d4..bdcc677338fb 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -962,13 +962,6 @@ extern void afs_merge_fs_addr6(struct afs_addr_list *, __be32 *, u16); */ #ifdef CONFIG_AFS_FSCACHE extern struct fscache_netfs afs_cache_netfs; -extern struct fscache_cookie_def afs_cell_cache_index_def; -extern struct fscache_cookie_def afs_volume_cache_index_def; -extern struct fscache_cookie_def afs_vnode_cache_index_def; -#else -#define afs_cell_cache_index_def (*(struct fscache_cookie_def *) NULL) -#define afs_volume_cache_index_def (*(struct fscache_cookie_def *) NULL) -#define afs_vnode_cache_index_def (*(struct fscache_cookie_def *) NULL) #endif /* diff --git a/fs/afs/volume.c b/fs/afs/volume.c index 9ca246ab1a86..5eaaa762fbd9 100644 --- a/fs/afs/volume.c +++ b/fs/afs/volume.c @@ -272,8 +272,9 @@ void afs_activate_volume(struct afs_volume *volume) { #ifdef CONFIG_AFS_FSCACHE volume->cache = fscache_acquire_cookie(volume->cell->cache, - &afs_volume_cache_index_def, - NULL, + FSCACHE_COOKIE_TYPE_INDEX, + "AFS.vol", + 0, NULL, &volume->vid, sizeof(volume->vid), NULL, 0, 0, true); #endif diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 6c48e81deccc..4de22ab53d73 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -41,7 +41,7 @@ static struct fscache_object *cachefiles_alloc_object( fscache_object_init(&object->fscache, cookie, &cache->cache); - object->type = cookie->def->type; + object->type = cookie->type; /* get hold of the raw key * - stick the length on the front and leave space on the back for the @@ -109,7 +109,7 @@ static int cachefiles_lookup_object(struct fscache_object *_object) /* polish off by setting the attributes of non-index files */ if (ret == 0 && - object->fscache.cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) + object->fscache.cookie->type != FSCACHE_COOKIE_TYPE_INDEX) cachefiles_attr_changed(&object->fscache); if (ret < 0 && ret != -ETIMEDOUT) { diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c index c99952404932..bcc4a2dfe1e8 100644 --- a/fs/cachefiles/xattr.c +++ b/fs/cachefiles/xattr.c @@ -39,7 +39,7 @@ int cachefiles_check_object_type(struct cachefiles_object *object) if (!object->fscache.cookie) strcpy(type, "C3"); else - snprintf(type, 3, "%02x", object->fscache.cookie->def->type); + snprintf(type, 3, "%02x", object->fscache.cookie->type); _enter("%x{%s}", object->fscache.debug_id, type); @@ -119,7 +119,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object, if (!buf) return -ENOMEM; - buf->type = object->fscache.cookie->def->type; + buf->type = object->fscache.cookie->type; if (len > 0) memcpy(buf->data, fscache_get_aux(object->fscache.cookie), len); @@ -158,7 +158,7 @@ int cachefiles_check_auxdata(struct cachefiles_object *object) ret = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, buf, tlen); if (ret == tlen && - buf->type == object->fscache.cookie->def->type && + buf->type == object->fscache.cookie->type && memcmp(buf->data, p, len) == 0) ret = 0; else diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index a772d4b6cacd..63e4a7db5804 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -43,10 +43,9 @@ static void fscache_print_cookie(struct fscache_cookie *cookie, char prefix) cookie->flags, atomic_read(&cookie->n_children), atomic_read(&cookie->n_active)); - pr_err("%c-cookie d=%p{%s}\n", + pr_err("%c-cookie d=%s\n", prefix, - cookie->def, - cookie->def ? cookie->def->name : "?"); + cookie->type_name); o = READ_ONCE(cookie->backing_objects.first); if (o) { @@ -137,7 +136,9 @@ static atomic_t fscache_cookie_debug_id = ATOMIC_INIT(1); */ struct fscache_cookie *fscache_alloc_cookie( struct fscache_cookie *parent, - const struct fscache_cookie_def *def, + enum fscache_cookie_type type, + const char *type_name, + u8 advice, struct fscache_cache_tag *preferred_cache, const void *index_key, size_t index_key_len, const void *aux_data, size_t aux_data_len, @@ -150,8 +151,11 @@ struct fscache_cookie *fscache_alloc_cookie( if (!cookie) return NULL; + cookie->type = type; + cookie->advice = advice; cookie->key_len = index_key_len; cookie->aux_len = aux_data_len; + strlcpy(cookie->type_name, type_name, sizeof(cookie->type_name)); if (fscache_set_key(cookie, index_key, index_key_len) < 0) goto nomem; @@ -173,13 +177,10 @@ struct fscache_cookie *fscache_alloc_cookie( */ atomic_set(&cookie->n_active, 1); - cookie->def = def; cookie->parent = parent; - cookie->preferred_cache = fscache_get_cache_tag(preferred_cache); cookie->flags = (1 << FSCACHE_COOKIE_NO_DATA_YET); - cookie->type = def->type; spin_lock_init(&cookie->lock); INIT_HLIST_HEAD(&cookie->backing_objects); @@ -241,7 +242,6 @@ struct fscache_cookie *fscache_hash_cookie(struct fscache_cookie *candidate) * - parent specifies the parent object * - the top level index cookie for each netfs is stored in the fscache_netfs * struct upon registration - * - def points to the definition * - all attached caches will be searched to see if they contain this object * - index objects aren't stored on disk until there's a dependent file that * needs storing @@ -252,7 +252,9 @@ struct fscache_cookie *fscache_hash_cookie(struct fscache_cookie *candidate) */ struct fscache_cookie *__fscache_acquire_cookie( struct fscache_cookie *parent, - const struct fscache_cookie_def *def, + enum fscache_cookie_type type, + const char *type_name, + u8 advice, struct fscache_cache_tag *preferred_cache, const void *index_key, size_t index_key_len, const void *aux_data, size_t aux_data_len, @@ -261,11 +263,8 @@ struct fscache_cookie *__fscache_acquire_cookie( { struct fscache_cookie *candidate, *cookie; - BUG_ON(!def); - _enter("{%s},{%s},%u", - parent ? (char *) parent->def->name : "", - def->name, enable); + parent ? parent->type_name : "", type_name, enable); if (!index_key || !index_key_len || index_key_len > 255 || aux_data_len > 255) return NULL; @@ -284,12 +283,11 @@ struct fscache_cookie *__fscache_acquire_cookie( } /* validate the definition */ - BUG_ON(!def->name[0]); - - BUG_ON(def->type == FSCACHE_COOKIE_TYPE_INDEX && + BUG_ON(type == FSCACHE_COOKIE_TYPE_INDEX && parent->type != FSCACHE_COOKIE_TYPE_INDEX); - candidate = fscache_alloc_cookie(parent, def, preferred_cache, + candidate = fscache_alloc_cookie(parent, type, type_name, advice, + preferred_cache, index_key, index_key_len, aux_data, aux_data_len, object_size); @@ -483,7 +481,7 @@ static int fscache_alloc_object(struct fscache_cache *cache, struct fscache_object *object; int ret; - _enter("%s,%x{%s}", cache->tag->name, cookie->debug_id, cookie->def->name); + _enter("%s,%x{%s}", cache->tag->name, cookie->debug_id, cookie->type_name); spin_lock(&cookie->lock); hlist_for_each_entry(object, &cookie->backing_objects, @@ -510,7 +508,7 @@ static int fscache_alloc_object(struct fscache_cache *cache, object->debug_id = atomic_inc_return(&fscache_object_debug_id); _debug("ALLOC OBJ%x: %s {%lx}", - object->debug_id, cookie->def->name, object->events); + object->debug_id, cookie->type_name, object->events); ret = fscache_alloc_object(cache, cookie->parent); if (ret < 0) @@ -558,7 +556,7 @@ static int fscache_attach_object(struct fscache_cookie *cookie, struct fscache_cache *cache = object->cache; int ret; - _enter("{%s},{OBJ%x}", cookie->def->name, object->debug_id); + _enter("{%s},{OBJ%x}", cookie->type_name, object->debug_id); ASSERTCMP(object->cookie, ==, cookie); @@ -618,7 +616,7 @@ void __fscache_invalidate(struct fscache_cookie *cookie) { struct fscache_object *object; - _enter("{%s}", cookie->def->name); + _enter("{%s}", cookie->type_name); fscache_stat(&fscache_n_invalidates); @@ -683,7 +681,7 @@ void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data return; } - _enter("{%s}", cookie->def->name); + _enter("{%s}", cookie->type_name); spin_lock(&cookie->lock); @@ -722,7 +720,7 @@ void __fscache_disable_cookie(struct fscache_cookie *cookie, if (atomic_read(&cookie->n_children) != 0) { pr_err("Cookie '%s' still has children\n", - cookie->def->name); + cookie->type_name); BUG(); } @@ -801,7 +799,7 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, } _enter("%x{%s,%d},%d", - cookie->debug_id, cookie->def->name, + cookie->debug_id, cookie->type_name, atomic_read(&cookie->n_active), retire); trace_fscache_relinquish(cookie, retire); @@ -812,9 +810,6 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, __fscache_disable_cookie(cookie, aux_data, retire); - /* Clear pointers back to the netfs */ - cookie->def = NULL; - if (cookie->parent) { ASSERTCMP(refcount_read(&cookie->parent->ref), >, 0); ASSERTCMP(atomic_read(&cookie->parent->n_children), >, 0); @@ -1009,7 +1004,7 @@ static int fscache_cookies_seq_show(struct seq_file *m, void *v) atomic_read(&cookie->n_active), type, cookie->flags, - cookie->def->name); + cookie->type_name); keylen = cookie->key_len; auxlen = cookie->aux_len; diff --git a/fs/fscache/fsdef.c b/fs/fscache/fsdef.c index 111946ba9ce1..15312f15848b 100644 --- a/fs/fscache/fsdef.c +++ b/fs/fscache/fsdef.c @@ -33,29 +33,14 @@ * cache. It can create whatever objects it likes in that index, including * further indices. */ -static struct fscache_cookie_def fscache_fsdef_index_def = { - .name = ".FS-Cache", - .type = FSCACHE_COOKIE_TYPE_INDEX, -}; - struct fscache_cookie fscache_fsdef_index = { .debug_id = 1, .ref = REFCOUNT_INIT(1), .n_active = ATOMIC_INIT(1), .lock = __SPIN_LOCK_UNLOCKED(fscache_fsdef_index.lock), .backing_objects = HLIST_HEAD_INIT, - .def = &fscache_fsdef_index_def, + .type_name = ".fscach", .flags = 1 << FSCACHE_COOKIE_ENABLED, .type = FSCACHE_COOKIE_TYPE_INDEX, }; EXPORT_SYMBOL(fscache_fsdef_index); - -/* - * Definition of an entry in the root index. Each entry is an index, keyed to - * a specific netfs and only applicable to a particular version of the index - * structure used by that netfs. - */ -struct fscache_cookie_def fscache_fsdef_netfs_def = { - .name = "FSDEF.netfs", - .type = FSCACHE_COOKIE_TYPE_INDEX, -}; diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index 29f21fbd5b5d..bff83b14398b 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h @@ -64,7 +64,9 @@ extern const struct seq_operations fscache_cookies_seq_ops; extern void fscache_free_cookie(struct fscache_cookie *); extern struct fscache_cookie *fscache_alloc_cookie(struct fscache_cookie *, - const struct fscache_cookie_def *, + enum fscache_cookie_type, + const char *, + u8, struct fscache_cache_tag *, const void *, size_t, const void *, size_t, @@ -86,7 +88,6 @@ static inline void fscache_cookie_see(struct fscache_cookie *cookie, * fsdef.c */ extern struct fscache_cookie fscache_fsdef_index; -extern struct fscache_cookie_def fscache_fsdef_netfs_def; /* * main.c diff --git a/fs/fscache/io.c b/fs/fscache/io.c index e633808ba813..41f56a11b1a9 100644 --- a/fs/fscache/io.c +++ b/fs/fscache/io.c @@ -51,7 +51,7 @@ int __fscache_begin_operation(struct netfs_cache_resources *cres, return -ENOBUFS; } - ASSERTCMP(cookie->def->type, !=, FSCACHE_COOKIE_TYPE_INDEX); + ASSERTCMP(cookie->type, !=, FSCACHE_COOKIE_TYPE_INDEX); if (fscache_wait_for_deferred_lookup(cookie) < 0) return -ERESTARTSYS; diff --git a/fs/fscache/netfs.c b/fs/fscache/netfs.c index b8db06804876..8b0f303a7715 100644 --- a/fs/fscache/netfs.c +++ b/fs/fscache/netfs.c @@ -21,8 +21,9 @@ int __fscache_register_netfs(struct fscache_netfs *netfs) /* allocate a cookie for the primary index */ candidate = fscache_alloc_cookie(&fscache_fsdef_index, - &fscache_fsdef_netfs_def, - NULL, + FSCACHE_COOKIE_TYPE_INDEX, + ".netfs", + 0, NULL, netfs->name, strlen(netfs->name), &netfs->version, sizeof(netfs->version), 0); diff --git a/fs/fscache/object.c b/fs/fscache/object.c index cdcf6720d748..1a061df7cdcd 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c @@ -469,7 +469,7 @@ static const struct fscache_state *fscache_look_up_object(struct fscache_object } _debug("LOOKUP \"%s\" in \"%s\"", - cookie->def->name, object->cache->tag->name); + cookie->type_name, object->cache->tag->name); fscache_stat(&fscache_n_object_lookups); fscache_stat(&fscache_n_cop_lookup_object); diff --git a/fs/fscache/page.c b/fs/fscache/page.c index 3fd6a2b45fed..2883d661f972 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c @@ -50,7 +50,7 @@ int __fscache_attr_changed(struct fscache_cookie *cookie) _enter("%p", cookie); - ASSERTCMP(cookie->def->type, !=, FSCACHE_COOKIE_TYPE_INDEX); + ASSERTCMP(cookie->type, !=, FSCACHE_COOKIE_TYPE_INDEX); fscache_stat(&fscache_n_attr_changed); diff --git a/include/linux/fscache.h b/include/linux/fscache.h index cedab654dc79..166e0f0a6e44 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -32,25 +32,18 @@ #define fscache_resources_valid(cres) (false) #endif -struct pagevec; struct fscache_cache_tag; struct fscache_cookie; struct fscache_netfs; struct netfs_read_request; -/* - * fscache cookie definition - */ -struct fscache_cookie_def { - /* name of cookie type */ - char name[16]; - - /* cookie type */ - uint8_t type; -#define FSCACHE_COOKIE_TYPE_INDEX 0 -#define FSCACHE_COOKIE_TYPE_DATAFILE 1 +enum fscache_cookie_type { + FSCACHE_COOKIE_TYPE_INDEX, + FSCACHE_COOKIE_TYPE_DATAFILE, }; +#define FSCACHE_ADV_SINGLE_CHUNK 0x01 /* The object is a single chunk of data */ + /* * fscache cached network filesystem type * - name, version and ops must be filled in before registration @@ -76,11 +69,11 @@ struct fscache_cookie { unsigned int debug_id; spinlock_t lock; struct hlist_head backing_objects; /* object(s) backing this file/index */ - const struct fscache_cookie_def *def; /* definition */ struct fscache_cookie *parent; /* parent of this entry */ struct fscache_cache_tag *preferred_cache; /* The preferred cache or NULL */ struct hlist_bl_node hash_link; /* Link in hash table */ struct list_head proc_link; /* Link in proc list */ + char type_name[8]; /* Cookie type name */ unsigned long flags; #define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */ @@ -94,7 +87,8 @@ struct fscache_cookie { #define FSCACHE_COOKIE_ACQUIRED 9 /* T if cookie is in use */ #define FSCACHE_COOKIE_RELINQUISHING 10 /* T if cookie is being relinquished */ - u8 type; /* Type of object */ + enum fscache_cookie_type type:8; + u8 advice; /* FSCACHE_COOKIE_ADV_* */ u8 key_len; /* Length of index key */ u8 aux_len; /* Length of auxiliary data */ u32 key_hash; /* Hash of parent, type, key, len */ @@ -128,7 +122,9 @@ extern void __fscache_release_cache_tag(struct fscache_cache_tag *); extern struct fscache_cookie *__fscache_acquire_cookie( struct fscache_cookie *, - const struct fscache_cookie_def *, + enum fscache_cookie_type, + const char *, + u8, struct fscache_cache_tag *, const void *, size_t, const void *, size_t, @@ -225,7 +221,9 @@ void fscache_release_cache_tag(struct fscache_cache_tag *tag) /** * fscache_acquire_cookie - Acquire a cookie to represent a cache object * @parent: The cookie that's to be the parent of this one - * @def: A description of the cache object, including callback operations + * @type: Type of the cookie + * @type_name: Name of cookie type (max 7 chars) + * @advice: Advice flags (FSCACHE_COOKIE_ADV_*) * @preferred_cache: The cache to use (or NULL) * @index_key: The index key for this cookie * @index_key_len: Size of the index key @@ -246,7 +244,9 @@ void fscache_release_cache_tag(struct fscache_cache_tag *tag) static inline struct fscache_cookie *fscache_acquire_cookie( struct fscache_cookie *parent, - const struct fscache_cookie_def *def, + enum fscache_cookie_type type, + const char *type_name, + u8 advice, struct fscache_cache_tag *preferred_cache, const void *index_key, size_t index_key_len, @@ -256,7 +256,8 @@ struct fscache_cookie *fscache_acquire_cookie( bool enable) { if (fscache_cookie_valid(parent) && fscache_cookie_enabled(parent)) - return __fscache_acquire_cookie(parent, def, preferred_cache, + return __fscache_acquire_cookie(parent, type, type_name, advice, + preferred_cache, index_key, index_key_len, aux_data, aux_data_len, object_size, enable); diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h index 446392f5ba83..ccff379db5e0 100644 --- a/include/trace/events/fscache.h +++ b/include/trace/events/fscache.h @@ -223,7 +223,7 @@ TRACE_EVENT(fscache_acquire, __entry->p_ref = refcount_read(&cookie->parent->ref); __entry->p_n_children = atomic_read(&cookie->parent->n_children); __entry->p_flags = cookie->parent->flags; - memcpy(__entry->name, cookie->def->name, 8); + memcpy(__entry->name, cookie->type_name, 8); __entry->name[7] = 0; ), From patchwork Mon Oct 18 14:52:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566819 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 12C81C433F5 for ; Mon, 18 Oct 2021 14:53:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EDD4E60E0B for ; Mon, 18 Oct 2021 14:53:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232303AbhJROzh (ORCPT ); Mon, 18 Oct 2021 10:55:37 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:57827 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232067AbhJROzZ (ORCPT ); Mon, 18 Oct 2021 10:55:25 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568793; 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=viMP4Q5Mj49sav8msJ4gVGQODCKNTPV/cZ3WnqxeUXM=; b=iZsmScIo6fbXmfJt5ZBp24XD1u6EvnD4CWbC5FcoZfK6ZALRcXlPjOPEe7VNtS/UYHMCCR Od3RTf1c+ak8JsHppkRN+9PwEx/sXsB9l+ld2wl4JQmVEW1Cbv0wVVRmPKGOFRqjXVtvNk uay23/ndofTtti7esEs9VpRoWn/15EM= 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-7-eRyuCs1RPgavA0PtqXU2yA-1; Mon, 18 Oct 2021 10:53:10 -0400 X-MC-Unique: eRyuCs1RPgavA0PtqXU2yA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D1D93801FCE; Mon, 18 Oct 2021 14:53:07 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2D27957CA5; Mon, 18 Oct 2021 14:52:53 +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 09/67] fscache: Remove store_limit* from struct fscache_object From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:52:52 +0100 Message-ID: <163456877241.2614702.1528585669988229916.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Remove the store_limit values from struct fscache_object and store the object size in the cookie. The netfs can update this at will, and we don't want to call back into the netfs to fetch it. Signed-off-by: David Howells --- fs/cachefiles/interface.c | 10 ++-------- fs/fscache/cookie.c | 14 ++++++-------- fs/fscache/object.c | 2 -- include/linux/fscache-cache.h | 22 ---------------------- include/linux/fscache.h | 1 + 5 files changed, 9 insertions(+), 40 deletions(-) diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 4de22ab53d73..48f7de947a16 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -359,7 +359,7 @@ static int cachefiles_attr_changed(struct fscache_object *_object) loff_t oi_size; int ret; - ni_size = _object->store_limit_l; + ni_size = _object->cookie->object_size; _enter("{OBJ%x},[%llu]", _object->debug_id, (unsigned long long) ni_size); @@ -376,8 +376,6 @@ static int cachefiles_attr_changed(struct fscache_object *_object) ASSERT(d_is_reg(object->backer)); - fscache_set_store_limit(&object->fscache, ni_size); - oi_size = i_size_read(d_backing_inode(object->backer)); if (oi_size == ni_size) return 0; @@ -406,7 +404,6 @@ static int cachefiles_attr_changed(struct fscache_object *_object) cachefiles_end_secure(cache, saved_cred); if (ret == -EIO) { - fscache_set_store_limit(&object->fscache, 0); cachefiles_io_error_obj(object, "Size set failed"); ret = -ENOBUFS; } @@ -431,7 +428,7 @@ static void cachefiles_invalidate_object(struct fscache_operation *op) cache = container_of(object->fscache.cache, struct cachefiles_cache, cache); - ni_size = op->object->store_limit_l; + ni_size = op->object->cookie->object_size; _enter("{OBJ%x},[%llu]", op->object->debug_id, (unsigned long long)ni_size); @@ -439,8 +436,6 @@ static void cachefiles_invalidate_object(struct fscache_operation *op) if (object->backer) { ASSERT(d_is_reg(object->backer)); - fscache_set_store_limit(&object->fscache, ni_size); - path.dentry = object->backer; path.mnt = cache->mnt; @@ -451,7 +446,6 @@ static void cachefiles_invalidate_object(struct fscache_operation *op) cachefiles_end_secure(cache, saved_cred); if (ret != 0) { - fscache_set_store_limit(&object->fscache, 0); if (ret == -EIO) cachefiles_io_error_obj(object, "Invalidate failed"); diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 63e4a7db5804..02998ec9f7c9 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -22,8 +22,7 @@ static struct hlist_bl_head fscache_cookie_hash[1 << fscache_cookie_hash_shift]; static LIST_HEAD(fscache_cookies); static DEFINE_RWLOCK(fscache_cookies_lock); -static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie, - loff_t object_size); +static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie); static int fscache_alloc_object(struct fscache_cache *cache, struct fscache_cookie *cookie); static int fscache_attach_object(struct fscache_cookie *cookie, @@ -155,6 +154,7 @@ struct fscache_cookie *fscache_alloc_cookie( cookie->advice = advice; cookie->key_len = index_key_len; cookie->aux_len = aux_data_len; + cookie->object_size = object_size; strlcpy(cookie->type_name, type_name, sizeof(cookie->type_name)); if (fscache_set_key(cookie, index_key, index_key_len) < 0) @@ -326,7 +326,7 @@ struct fscache_cookie *__fscache_acquire_cookie( * - we create indices on disk when we need them as an index * may exist in multiple caches */ if (cookie->type != FSCACHE_COOKIE_TYPE_INDEX) { - if (fscache_acquire_non_index_cookie(cookie, object_size) == 0) { + if (fscache_acquire_non_index_cookie(cookie) == 0) { set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); } else { atomic_dec(&parent->n_children); @@ -365,6 +365,7 @@ void __fscache_enable_cookie(struct fscache_cookie *cookie, wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK, TASK_UNINTERRUPTIBLE); + cookie->object_size = object_size; fscache_update_aux(cookie, aux_data); if (test_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags)) @@ -376,7 +377,7 @@ void __fscache_enable_cookie(struct fscache_cookie *cookie, /* Wait for outstanding disablement to complete */ __fscache_wait_on_invalidate(cookie); - if (fscache_acquire_non_index_cookie(cookie, object_size) == 0) + if (fscache_acquire_non_index_cookie(cookie) == 0) set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); } else { set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); @@ -393,8 +394,7 @@ EXPORT_SYMBOL(__fscache_enable_cookie); * - this must make sure the index chain is instantiated and instantiate the * object representation too */ -static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie, - loff_t object_size) +static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie) { struct fscache_object *object; struct fscache_cache *cache; @@ -445,8 +445,6 @@ static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie, object = hlist_entry(cookie->backing_objects.first, struct fscache_object, cookie_link); - fscache_set_store_limit(object, object_size); - /* initiate the process of looking up all the objects in the chain * (done by fscache_initialise_object()) */ fscache_raise_event(object, FSCACHE_OBJECT_EV_NEW_CHILD); diff --git a/fs/fscache/object.c b/fs/fscache/object.c index 1a061df7cdcd..3fb5a1a6c131 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c @@ -315,8 +315,6 @@ void fscache_object_init(struct fscache_object *object, object->n_children = 0; object->n_ops = object->n_in_progress = object->n_exclusive = 0; object->events = 0; - object->store_limit = 0; - object->store_limit_l = 0; object->cache = cache; object->cookie = cookie; fscache_cookie_get(cookie, fscache_cookie_get_attach_object); diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index 264b94dad5be..15cd2f04c9e6 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -275,8 +275,6 @@ struct fscache_object { struct list_head dependents; /* FIFO of dependent objects */ struct list_head dep_link; /* link in parent's dependents list */ struct list_head pending_ops; /* unstarted operations on this object */ - pgoff_t store_limit; /* current storage limit */ - loff_t store_limit_l; /* current storage limit */ }; extern void fscache_object_init(struct fscache_object *, struct fscache_cookie *, @@ -337,26 +335,6 @@ static inline void fscache_object_lookup_error(struct fscache_object *object) set_bit(FSCACHE_OBJECT_EV_ERROR, &object->events); } -/** - * fscache_set_store_limit - Set the maximum size to be stored in an object - * @object: The object to set the maximum on - * @i_size: The limit to set in bytes - * - * Set the maximum size an object is permitted to reach, implying the highest - * byte that may be written. Intended to be called by the attr_changed() op. - * - * See Documentation/filesystems/caching/backend-api.rst for a complete - * description. - */ -static inline -void fscache_set_store_limit(struct fscache_object *object, loff_t i_size) -{ - object->store_limit_l = i_size; - object->store_limit = i_size >> PAGE_SHIFT; - if (i_size & ~PAGE_MASK) - object->store_limit++; -} - static inline void __fscache_use_cookie(struct fscache_cookie *cookie) { atomic_inc(&cookie->n_active); diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 166e0f0a6e44..98685bd7204b 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -74,6 +74,7 @@ struct fscache_cookie { struct hlist_bl_node hash_link; /* Link in hash table */ struct list_head proc_link; /* Link in proc list */ char type_name[8]; /* Cookie type name */ + loff_t object_size; /* Size of the netfs object */ unsigned long flags; #define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */ From patchwork Mon Oct 18 14:53:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566945 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A5CD5C433EF for ; Mon, 18 Oct 2021 14:53:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8D09B60E0B for ; Mon, 18 Oct 2021 14:53:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232360AbhJROzz (ORCPT ); Mon, 18 Oct 2021 10:55:55 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:45799 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232200AbhJROzy (ORCPT ); Mon, 18 Oct 2021 10:55:54 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568822; 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=53rHR2JQiSk7mdrXzJPxTn/iYK4ompTtsc4UWiHJO7g=; b=bq2gVwz69RiNva3yPV+HWshxrfCYKgyrR8JvDFXNXotRooiyzYXSn4DNeoP8XdeYs1Vmyu Ly8JdIStYmqpxSZShDtrgfADlDgZePbUQeQGVS1J5iXeAuWNf2Jbk3CTobnsSCiX4TERHv yiVy9F8ZWpi1jf5sxgDAvyBNumOebcs= 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-421-MZmnuUFDMhOdBcqw9K4VFA-1; Mon, 18 Oct 2021 10:53:39 -0400 X-MC-Unique: MZmnuUFDMhOdBcqw9K4VFA-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 2029A362FA; Mon, 18 Oct 2021 14:53:37 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id EFEE35BB06; Mon, 18 Oct 2021 14:53:13 +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 10/67] fscache: Remove fscache_check_consistency() From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:53:13 +0100 Message-ID: <163456879308.2614702.3008093259379620191.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Remove fscache_check_consistency() as that allows the netfs to pry into the inner working of the cache - and what's in the cookie should be taken as consistent with the disk (possibly lazily). Signed-off-by: David Howells --- fs/cachefiles/interface.c | 26 ------------- fs/fscache/cookie.c | 79 ----------------------------------------- include/linux/fscache-cache.h | 4 -- include/linux/fscache.h | 23 ------------ 4 files changed, 132 deletions(-) diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 48f7de947a16..460dd190dad5 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -320,31 +320,6 @@ static void cachefiles_sync_cache(struct fscache_cache *_cache) ret); } -/* - * check if the backing cache is updated to FS-Cache - * - called by FS-Cache when evaluates if need to invalidate the cache - */ -static int cachefiles_check_consistency(struct fscache_operation *op) -{ - struct cachefiles_object *object; - struct cachefiles_cache *cache; - const struct cred *saved_cred; - int ret; - - _enter("{OBJ%x}", op->object->debug_id); - - object = container_of(op->object, struct cachefiles_object, fscache); - cache = container_of(object->fscache.cache, - struct cachefiles_cache, cache); - - cachefiles_begin_secure(cache, &saved_cred); - ret = cachefiles_check_auxdata(object); - cachefiles_end_secure(cache, saved_cred); - - _leave(" = %d", ret); - return ret; -} - /* * notification the attributes on an object have changed * - called with reads/writes excluded by FS-Cache @@ -468,6 +443,5 @@ const struct fscache_cache_ops cachefiles_cache_ops = { .put_object = cachefiles_put_object, .sync_cache = cachefiles_sync_cache, .attr_changed = cachefiles_attr_changed, - .check_consistency = cachefiles_check_consistency, .begin_operation = cachefiles_begin_operation, }; diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 02998ec9f7c9..78938ea6ad1a 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -880,85 +880,6 @@ struct fscache_cookie *fscache_cookie_get(struct fscache_cookie *cookie, return cookie; } -/* - * check the consistency between the netfs inode and the backing cache - * - * NOTE: it only serves no-index type - */ -int __fscache_check_consistency(struct fscache_cookie *cookie, - const void *aux_data) -{ - struct fscache_operation *op; - struct fscache_object *object; - bool wake_cookie = false; - int ret; - - _enter("%p,", cookie); - - ASSERTCMP(cookie->type, ==, FSCACHE_COOKIE_TYPE_DATAFILE); - - if (fscache_wait_for_deferred_lookup(cookie) < 0) - return -ERESTARTSYS; - - if (hlist_empty(&cookie->backing_objects)) - return 0; - - op = kzalloc(sizeof(*op), GFP_NOIO | __GFP_NOMEMALLOC | __GFP_NORETRY); - if (!op) - return -ENOMEM; - - fscache_operation_init(cookie, op, NULL, NULL, NULL); - op->flags = FSCACHE_OP_MYTHREAD | - (1 << FSCACHE_OP_WAITING) | - (1 << FSCACHE_OP_UNUSE_COOKIE); - trace_fscache_page_op(cookie, NULL, op, fscache_page_op_check_consistency); - - spin_lock(&cookie->lock); - - fscache_update_aux(cookie, aux_data); - - if (!fscache_cookie_enabled(cookie) || - hlist_empty(&cookie->backing_objects)) - goto inconsistent; - object = hlist_entry(cookie->backing_objects.first, - struct fscache_object, cookie_link); - if (test_bit(FSCACHE_IOERROR, &object->cache->flags)) - goto inconsistent; - - op->debug_id = atomic_inc_return(&fscache_op_debug_id); - - __fscache_use_cookie(cookie); - if (fscache_submit_op(object, op) < 0) - goto submit_failed; - - /* the work queue now carries its own ref on the object */ - spin_unlock(&cookie->lock); - - ret = fscache_wait_for_operation_activation(object, op, NULL, NULL); - if (ret == 0) { - /* ask the cache to honour the operation */ - ret = object->cache->ops->check_consistency(op); - fscache_op_complete(op, false); - } else if (ret == -ENOBUFS) { - ret = 0; - } - - fscache_put_operation(op); - _leave(" = %d", ret); - return ret; - -submit_failed: - wake_cookie = __fscache_unuse_cookie(cookie); -inconsistent: - spin_unlock(&cookie->lock); - if (wake_cookie) - __fscache_wake_unused_cookie(cookie); - kfree(op); - _leave(" = -ESTALE"); - return -ESTALE; -} -EXPORT_SYMBOL(__fscache_check_consistency); - /* * Generate a list of extant cookies in /proc/fs/fscache/cookies */ diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index 15cd2f04c9e6..15683b7876ff 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -167,10 +167,6 @@ struct fscache_cache_ops { /* unpin an object in the cache */ void (*unpin_object)(struct fscache_object *object); - /* check the consistency between the backing cache and the FS-Cache - * cookie */ - int (*check_consistency)(struct fscache_operation *op); - /* store the updated auxiliary data on an object */ void (*update_object)(struct fscache_object *object); diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 98685bd7204b..75ca4fda93d5 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -131,7 +131,6 @@ extern struct fscache_cookie *__fscache_acquire_cookie( const void *, size_t, loff_t, bool); extern void __fscache_relinquish_cookie(struct fscache_cookie *, const void *, bool); -extern int __fscache_check_consistency(struct fscache_cookie *, const void *); extern void __fscache_update_cookie(struct fscache_cookie *, const void *); extern int __fscache_attr_changed(struct fscache_cookie *); extern void __fscache_invalidate(struct fscache_cookie *); @@ -290,28 +289,6 @@ void fscache_relinquish_cookie(struct fscache_cookie *cookie, __fscache_relinquish_cookie(cookie, aux_data, retire); } -/** - * fscache_check_consistency - Request validation of a cache's auxiliary data - * @cookie: The cookie representing the cache object - * @aux_data: The updated auxiliary data for the cookie (may be NULL) - * - * Request an consistency check from fscache, which passes the request to the - * backing cache. The auxiliary data on the cookie will be updated first if - * @aux_data is set. - * - * Returns 0 if consistent and -ESTALE if inconsistent. May also - * return -ENOMEM and -ERESTARTSYS. - */ -static inline -int fscache_check_consistency(struct fscache_cookie *cookie, - const void *aux_data) -{ - if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) - return __fscache_check_consistency(cookie, aux_data); - else - return 0; -} - /** * fscache_update_cookie - Request that a cache object be updated * @cookie: The cookie representing the cache object From patchwork Mon Oct 18 14:53:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566947 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B6D32C433EF for ; Mon, 18 Oct 2021 14:54:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9CF4761038 for ; Mon, 18 Oct 2021 14:54:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232303AbhJRO4W (ORCPT ); Mon, 18 Oct 2021 10:56:22 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:20126 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232099AbhJRO4W (ORCPT ); Mon, 18 Oct 2021 10:56:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568851; 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=yhjrXcMJ61+jv4encCReJ2B1wbDIxHE4Ygch5kqp1lw=; b=QKdKd/DLvravztBzgsWbnLTJ2g/GQoPTFqnZGZkmgiwGqTU12foDtm4i3CxQPWvzr+OpU7 IY3yW6NLL7tMra6PAr/iFIqgBwrHmN78cJMuA8lqQs6C4bvYn/UYRkKnLBxyRxu0QWtrRs 7wAwNgf3nmmfkKuHiyhPrsr+NZwIx4c= 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-387-0ouMmq1iMYOr3H1rYz3eUQ-1; Mon, 18 Oct 2021 10:54:07 -0400 X-MC-Unique: 0ouMmq1iMYOr3H1rYz3eUQ-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 393191006AA3; Mon, 18 Oct 2021 14:54:03 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 38867100EBBF; Mon, 18 Oct 2021 14:53:43 +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 11/67] fscache: Remove fscache_attr_changed() From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:53:42 +0100 Message-ID: <163456882235.2614702.16403136063544166351.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Remove fscache_attr_changed() as it's unused. Signed-off-by: David Howells --- fs/cachefiles/interface.c | 13 ++---- fs/fscache/page.c | 84 ----------------------------------------- include/linux/fscache-cache.h | 4 -- include/linux/fscache.h | 21 ---------- 4 files changed, 5 insertions(+), 117 deletions(-) diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 460dd190dad5..4a813a490ffe 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -10,7 +10,7 @@ #include #include "internal.h" -static int cachefiles_attr_changed(struct fscache_object *_object); +static int cachefiles_attr_changed(struct cachefiles_object *object); /* * allocate an object record for a cookie lookup and prepare the lookup data @@ -110,7 +110,7 @@ static int cachefiles_lookup_object(struct fscache_object *_object) /* polish off by setting the attributes of non-index files */ if (ret == 0 && object->fscache.cookie->type != FSCACHE_COOKIE_TYPE_INDEX) - cachefiles_attr_changed(&object->fscache); + cachefiles_attr_changed(object); if (ret < 0 && ret != -ETIMEDOUT) { if (ret != -ENOBUFS) @@ -324,9 +324,8 @@ static void cachefiles_sync_cache(struct fscache_cache *_cache) * notification the attributes on an object have changed * - called with reads/writes excluded by FS-Cache */ -static int cachefiles_attr_changed(struct fscache_object *_object) +static int cachefiles_attr_changed(struct cachefiles_object *object) { - struct cachefiles_object *object; struct cachefiles_cache *cache; const struct cred *saved_cred; struct iattr newattrs; @@ -334,12 +333,11 @@ static int cachefiles_attr_changed(struct fscache_object *_object) loff_t oi_size; int ret; - ni_size = _object->cookie->object_size; + ni_size = object->fscache.cookie->object_size; _enter("{OBJ%x},[%llu]", - _object->debug_id, (unsigned long long) ni_size); + object->fscache.debug_id, (unsigned long long) ni_size); - object = container_of(_object, struct cachefiles_object, fscache); cache = container_of(object->fscache.cache, struct cachefiles_cache, cache); @@ -442,6 +440,5 @@ const struct fscache_cache_ops cachefiles_cache_ops = { .drop_object = cachefiles_drop_object, .put_object = cachefiles_put_object, .sync_cache = cachefiles_sync_cache, - .attr_changed = cachefiles_attr_changed, .begin_operation = cachefiles_begin_operation, }; diff --git a/fs/fscache/page.c b/fs/fscache/page.c index 2883d661f972..1d86c8a2a8c4 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c @@ -13,90 +13,6 @@ #include #include "internal.h" -/* - * actually apply the changed attributes to a cache object - */ -static void fscache_attr_changed_op(struct fscache_operation *op) -{ - struct fscache_object *object = op->object; - int ret; - - _enter("{OBJ%x OP%x}", object->debug_id, op->debug_id); - - fscache_stat(&fscache_n_attr_changed_calls); - - if (fscache_object_is_active(object)) { - fscache_stat(&fscache_n_cop_attr_changed); - ret = object->cache->ops->attr_changed(object); - fscache_stat_d(&fscache_n_cop_attr_changed); - if (ret < 0) - fscache_abort_object(object); - fscache_op_complete(op, ret < 0); - } else { - fscache_op_complete(op, true); - } - - _leave(""); -} - -/* - * notification that the attributes on an object have changed - */ -int __fscache_attr_changed(struct fscache_cookie *cookie) -{ - struct fscache_operation *op; - struct fscache_object *object; - bool wake_cookie = false; - - _enter("%p", cookie); - - ASSERTCMP(cookie->type, !=, FSCACHE_COOKIE_TYPE_INDEX); - - fscache_stat(&fscache_n_attr_changed); - - op = kzalloc(sizeof(*op), GFP_KERNEL); - if (!op) { - fscache_stat(&fscache_n_attr_changed_nomem); - _leave(" = -ENOMEM"); - return -ENOMEM; - } - - fscache_operation_init(cookie, op, fscache_attr_changed_op, NULL, NULL); - trace_fscache_page_op(cookie, NULL, op, fscache_page_op_attr_changed); - op->flags = FSCACHE_OP_ASYNC | - (1 << FSCACHE_OP_EXCLUSIVE) | - (1 << FSCACHE_OP_UNUSE_COOKIE); - - spin_lock(&cookie->lock); - - if (!fscache_cookie_enabled(cookie) || - hlist_empty(&cookie->backing_objects)) - goto nobufs; - object = hlist_entry(cookie->backing_objects.first, - struct fscache_object, cookie_link); - - __fscache_use_cookie(cookie); - if (fscache_submit_exclusive_op(object, op) < 0) - goto nobufs_dec; - spin_unlock(&cookie->lock); - fscache_stat(&fscache_n_attr_changed_ok); - fscache_put_operation(op); - _leave(" = 0"); - return 0; - -nobufs_dec: - wake_cookie = __fscache_unuse_cookie(cookie); -nobufs: - spin_unlock(&cookie->lock); - fscache_put_operation(op); - if (wake_cookie) - __fscache_wake_unused_cookie(cookie); - fscache_stat(&fscache_n_attr_changed_nobufs); - _leave(" = %d", -ENOBUFS); - return -ENOBUFS; -} -EXPORT_SYMBOL(__fscache_attr_changed); - /* * wait for a deferred lookup to complete */ diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index 15683b7876ff..d0c6c09bb5a1 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -184,10 +184,6 @@ struct fscache_cache_ops { /* sync a cache */ void (*sync_cache)(struct fscache_cache *cache); - /* notification that the attributes of a non-index object (such as - * i_size) have changed */ - int (*attr_changed)(struct fscache_object *object); - /* reserve space for an object's data and associated metadata */ int (*reserve_space)(struct fscache_object *object, loff_t i_size); diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 75ca4fda93d5..1dba014e848f 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -132,7 +132,6 @@ extern struct fscache_cookie *__fscache_acquire_cookie( loff_t, bool); extern void __fscache_relinquish_cookie(struct fscache_cookie *, const void *, bool); extern void __fscache_update_cookie(struct fscache_cookie *, const void *); -extern int __fscache_attr_changed(struct fscache_cookie *); extern void __fscache_invalidate(struct fscache_cookie *); extern void __fscache_wait_on_invalidate(struct fscache_cookie *); #ifdef FSCACHE_USE_NEW_IO_API @@ -337,26 +336,6 @@ void fscache_unpin_cookie(struct fscache_cookie *cookie) { } -/** - * fscache_attr_changed - Notify cache that an object's attributes changed - * @cookie: The cookie representing the cache object - * - * Send a notification to the cache indicating that an object's attributes have - * changed. This includes the data size. These attributes will be obtained - * through the get_attr() cookie definition op. - * - * See Documentation/filesystems/caching/netfs-api.rst for a complete - * description. - */ -static inline -int fscache_attr_changed(struct fscache_cookie *cookie) -{ - if (fscache_cookie_valid(cookie) && fscache_cookie_enabled(cookie)) - return __fscache_attr_changed(cookie); - else - return -ENOBUFS; -} - /** * fscache_invalidate - Notify cache that an object needs invalidation * @cookie: The cookie representing the cache object From patchwork Mon Oct 18 14:54:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566949 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B00ECC433EF for ; Mon, 18 Oct 2021 14:54:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9C48461002 for ; Mon, 18 Oct 2021 14:54:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232458AbhJRO4b (ORCPT ); Mon, 18 Oct 2021 10:56:31 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:37623 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232619AbhJRO4a (ORCPT ); Mon, 18 Oct 2021 10:56:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568858; 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=mzB7OAnJKprSVoxpFAUwZvdXiYSDNu4qAmCk5+4Btxs=; b=Yrvc/t5eNmwxQg1JDfP+n7tPKU4+FecWLeribDPM6Uxa34jsuy+ZGkxj7umAb49SS7MisN zDxB8Bml4GiYqun0uvqKKc+1hFHvEcUqpFJm6wqxZKeXUd80t/z6WcYPT6bTWx1n7vN32t ADZUDhX1Zli2a8sRYOLl9kuUEhxxkAY= 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-230-VbMiCPwZN36vAGz3LVvPeQ-1; Mon, 18 Oct 2021 10:54:17 -0400 X-MC-Unique: VbMiCPwZN36vAGz3LVvPeQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 509A01006AD3; Mon, 18 Oct 2021 14:54:15 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 52A135D6D7; Mon, 18 Oct 2021 14:54:09 +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 12/67] fscache: Remove obsolete stats From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:54:08 +0100 Message-ID: <163456884845.2614702.5758884460753061615.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Remove a bunch of now-unused fscache stats counters that were obsoleted by the removal of the old I/O routines. Signed-off-by: David Howells --- fs/fscache/internal.h | 15 --------------- fs/fscache/stats.c | 27 +-------------------------- 2 files changed, 1 insertion(+), 41 deletions(-) diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index bff83b14398b..43d64f6bbf8b 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h @@ -149,9 +149,6 @@ extern void fscache_proc_cleanup(void); * stats.c */ #ifdef CONFIG_FSCACHE_STATS -extern atomic_t fscache_n_ops_processed[FSCACHE_MAX_THREADS]; -extern atomic_t fscache_n_objs_processed[FSCACHE_MAX_THREADS]; - extern atomic_t fscache_n_op_pend; extern atomic_t fscache_n_op_run; extern atomic_t fscache_n_op_enqueue; @@ -162,12 +159,6 @@ extern atomic_t fscache_n_op_gc; extern atomic_t fscache_n_op_cancelled; extern atomic_t fscache_n_op_rejected; -extern atomic_t fscache_n_attr_changed; -extern atomic_t fscache_n_attr_changed_ok; -extern atomic_t fscache_n_attr_changed_nobufs; -extern atomic_t fscache_n_attr_changed_nomem; -extern atomic_t fscache_n_attr_changed_calls; - extern atomic_t fscache_n_retrievals; extern atomic_t fscache_n_retrievals_ok; extern atomic_t fscache_n_retrievals_wait; @@ -205,7 +196,6 @@ extern atomic_t fscache_n_updates_run; extern atomic_t fscache_n_relinquishes; extern atomic_t fscache_n_relinquishes_null; -extern atomic_t fscache_n_relinquishes_waitcrt; extern atomic_t fscache_n_relinquishes_retire; extern atomic_t fscache_n_cookie_index; @@ -222,11 +212,6 @@ extern atomic_t fscache_n_object_created; extern atomic_t fscache_n_object_avail; extern atomic_t fscache_n_object_dead; -extern atomic_t fscache_n_checkaux_none; -extern atomic_t fscache_n_checkaux_okay; -extern atomic_t fscache_n_checkaux_update; -extern atomic_t fscache_n_checkaux_obsolete; - extern atomic_t fscache_n_cop_alloc_object; extern atomic_t fscache_n_cop_lookup_object; extern atomic_t fscache_n_cop_lookup_complete; diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c index 2449aa459140..cb9dd0a93e0d 100644 --- a/fs/fscache/stats.c +++ b/fs/fscache/stats.c @@ -24,12 +24,6 @@ atomic_t fscache_n_op_gc; atomic_t fscache_n_op_cancelled; atomic_t fscache_n_op_rejected; -atomic_t fscache_n_attr_changed; -atomic_t fscache_n_attr_changed_ok; -atomic_t fscache_n_attr_changed_nobufs; -atomic_t fscache_n_attr_changed_nomem; -atomic_t fscache_n_attr_changed_calls; - atomic_t fscache_n_retrievals; atomic_t fscache_n_retrievals_ok; atomic_t fscache_n_retrievals_wait; @@ -67,7 +61,6 @@ atomic_t fscache_n_updates_run; atomic_t fscache_n_relinquishes; atomic_t fscache_n_relinquishes_null; -atomic_t fscache_n_relinquishes_waitcrt; atomic_t fscache_n_relinquishes_retire; atomic_t fscache_n_cookie_index; @@ -84,11 +77,6 @@ atomic_t fscache_n_object_created; atomic_t fscache_n_object_avail; atomic_t fscache_n_object_dead; -atomic_t fscache_n_checkaux_none; -atomic_t fscache_n_checkaux_okay; -atomic_t fscache_n_checkaux_update; -atomic_t fscache_n_checkaux_obsolete; - atomic_t fscache_n_cop_alloc_object; atomic_t fscache_n_cop_lookup_object; atomic_t fscache_n_cop_lookup_complete; @@ -122,11 +110,6 @@ int fscache_stats_show(struct seq_file *m, void *v) atomic_read(&fscache_n_object_no_alloc), atomic_read(&fscache_n_object_avail), atomic_read(&fscache_n_object_dead)); - seq_printf(m, "ChkAux : non=%u ok=%u upd=%u obs=%u\n", - atomic_read(&fscache_n_checkaux_none), - atomic_read(&fscache_n_checkaux_okay), - atomic_read(&fscache_n_checkaux_update), - atomic_read(&fscache_n_checkaux_obsolete)); seq_printf(m, "Acquire: n=%u nul=%u noc=%u ok=%u nbf=%u" " oom=%u\n", @@ -153,19 +136,11 @@ int fscache_stats_show(struct seq_file *m, void *v) atomic_read(&fscache_n_updates_null), atomic_read(&fscache_n_updates_run)); - seq_printf(m, "Relinqs: n=%u nul=%u wcr=%u rtr=%u\n", + seq_printf(m, "Relinqs: n=%u nul=%u rtr=%u\n", atomic_read(&fscache_n_relinquishes), atomic_read(&fscache_n_relinquishes_null), - atomic_read(&fscache_n_relinquishes_waitcrt), atomic_read(&fscache_n_relinquishes_retire)); - seq_printf(m, "AttrChg: n=%u ok=%u nbf=%u oom=%u run=%u\n", - atomic_read(&fscache_n_attr_changed), - atomic_read(&fscache_n_attr_changed_ok), - atomic_read(&fscache_n_attr_changed_nobufs), - atomic_read(&fscache_n_attr_changed_nomem), - atomic_read(&fscache_n_attr_changed_calls)); - seq_printf(m, "Retrvls: n=%u ok=%u wt=%u nod=%u nbf=%u" " int=%u oom=%u\n", atomic_read(&fscache_n_retrievals), From patchwork Mon Oct 18 14:54:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566951 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1E65EC433EF for ; Mon, 18 Oct 2021 14:54:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0601660E0B for ; Mon, 18 Oct 2021 14:54:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232730AbhJRO4m (ORCPT ); Mon, 18 Oct 2021 10:56:42 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:41429 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232579AbhJRO4l (ORCPT ); Mon, 18 Oct 2021 10:56:41 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568869; 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=fVnS0fi9lWxxlJUjXe0viqe5hOzqMikhwWObx1OO6EA=; b=dN4N2KiD+fnFc8VYKTgP1m7SqYlbmuxQ/xim8F2QqVpmAXJ6MMrmJ+WT57kLJFOzmj0eK1 Gvvlk5SShVGunHxrIPuN4pPuoUsFdcoR5TWZiWyIlQeLmzGfo5DPvwLotc1ILdRtulObbr nRJXPNf9ov2oG8etvcrPAfiT093nEJM= 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-284-LHkY9FAGP-2j9ZRgrW43jg-1; Mon, 18 Oct 2021 10:54:26 -0400 X-MC-Unique: LHkY9FAGP-2j9ZRgrW43jg-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id A2642804B6C; Mon, 18 Oct 2021 14:54:24 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5236C62A44; Mon, 18 Oct 2021 14:54:21 +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 13/67] fscache: Remove old I/O tracepoints From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:54:20 +0100 Message-ID: <163456886045.2614702.17032971991288240935.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Remove now-(mostly)-unused fscache tracepoints that have been obsoleted by the removal of the old I/O code. Signed-off-by: David Howells --- fs/fscache/io.c | 2 fs/fscache/object.c | 1 include/trace/events/fscache.h | 195 ---------------------------------------- 3 files changed, 198 deletions(-) diff --git a/fs/fscache/io.c b/fs/fscache/io.c index 41f56a11b1a9..7ac34c2e45fe 100644 --- a/fs/fscache/io.c +++ b/fs/fscache/io.c @@ -65,8 +65,6 @@ int __fscache_begin_operation(struct netfs_cache_resources *cres, (1UL << FSCACHE_OP_WAITING) | (1UL << FSCACHE_OP_UNUSE_COOKIE); - trace_fscache_page_op(cookie, NULL, op, fscache_page_op_retr_multi); - spin_lock(&cookie->lock); if (!fscache_cookie_enabled(cookie) || diff --git a/fs/fscache/object.c b/fs/fscache/object.c index 3fb5a1a6c131..7aa1f90d978b 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c @@ -933,7 +933,6 @@ static const struct fscache_state *_fscache_invalidate_object(struct fscache_obj op->flags = FSCACHE_OP_ASYNC | (1 << FSCACHE_OP_EXCLUSIVE) | (1 << FSCACHE_OP_UNUSE_COOKIE); - trace_fscache_page_op(cookie, NULL, op, fscache_page_op_invalidate); spin_lock(&cookie->lock); if (fscache_submit_exclusive_op(object, op) < 0) diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h index ccff379db5e0..90d956ef1c6e 100644 --- a/include/trace/events/fscache.h +++ b/include/trace/events/fscache.h @@ -33,24 +33,6 @@ enum fscache_cookie_trace { fscache_cookie_put_parent, }; -enum fscache_page_trace { - fscache_page_cached, - fscache_page_inval, - fscache_page_maybe_release, - fscache_page_radix_clear_store, - fscache_page_radix_delete, - fscache_page_radix_insert, - fscache_page_radix_pend2store, - fscache_page_radix_set_pend, - fscache_page_uncache, - fscache_page_write, - fscache_page_write_end, - fscache_page_write_end_pend, - fscache_page_write_end_noc, - fscache_page_write_wait, - fscache_page_trace__nr -}; - enum fscache_op_trace { fscache_op_cancel, fscache_op_cancel_all, @@ -69,17 +51,6 @@ enum fscache_op_trace { fscache_op_trace__nr }; -enum fscache_page_op_trace { - fscache_page_op_alloc_one, - fscache_page_op_attr_changed, - fscache_page_op_check_consistency, - fscache_page_op_invalidate, - fscache_page_op_retr_multi, - fscache_page_op_retr_one, - fscache_page_op_write_one, - fscache_page_op_trace__nr -}; - #endif /* @@ -98,22 +69,6 @@ enum fscache_page_op_trace { EM(fscache_cookie_put_object, "PUT obj") \ E_(fscache_cookie_put_parent, "PUT prn") -#define fscache_page_traces \ - EM(fscache_page_cached, "Cached ") \ - EM(fscache_page_inval, "InvalPg") \ - EM(fscache_page_maybe_release, "MayRels") \ - EM(fscache_page_uncache, "Uncache") \ - EM(fscache_page_radix_clear_store, "RxCStr ") \ - EM(fscache_page_radix_delete, "RxDel ") \ - EM(fscache_page_radix_insert, "RxIns ") \ - EM(fscache_page_radix_pend2store, "RxP2S ") \ - EM(fscache_page_radix_set_pend, "RxSPend ") \ - EM(fscache_page_write, "WritePg") \ - EM(fscache_page_write_end, "EndPgWr") \ - EM(fscache_page_write_end_pend, "EndPgWP") \ - EM(fscache_page_write_end_noc, "EndPgNC") \ - E_(fscache_page_write_wait, "WtOnWrt") - #define fscache_op_traces \ EM(fscache_op_cancel, "Cancel1") \ EM(fscache_op_cancel_all, "CancelA") \ @@ -130,15 +85,6 @@ enum fscache_page_op_trace { EM(fscache_op_submit_ex, "SubmitX") \ E_(fscache_op_work, "Work ") -#define fscache_page_op_traces \ - EM(fscache_page_op_alloc_one, "Alloc1 ") \ - EM(fscache_page_op_attr_changed, "AttrChg") \ - EM(fscache_page_op_check_consistency, "CheckCn") \ - EM(fscache_page_op_invalidate, "Inval ") \ - EM(fscache_page_op_retr_multi, "RetrMul") \ - EM(fscache_page_op_retr_one, "Retr1 ") \ - E_(fscache_page_op_write_one, "Write1 ") - /* * Export enum symbols via userspace. */ @@ -353,70 +299,6 @@ TRACE_EVENT(fscache_osm, __entry->event_num) ); -TRACE_EVENT(fscache_page, - TP_PROTO(struct fscache_cookie *cookie, struct page *page, - enum fscache_page_trace why), - - TP_ARGS(cookie, page, why), - - TP_STRUCT__entry( - __field(unsigned int, cookie ) - __field(pgoff_t, page ) - __field(enum fscache_page_trace, why ) - ), - - TP_fast_assign( - __entry->cookie = cookie->debug_id; - __entry->page = page->index; - __entry->why = why; - ), - - TP_printk("c=%08x %s pg=%lx", - __entry->cookie, - __print_symbolic(__entry->why, fscache_page_traces), - __entry->page) - ); - -TRACE_EVENT(fscache_check_page, - TP_PROTO(struct fscache_cookie *cookie, struct page *page, - void *val, int n), - - TP_ARGS(cookie, page, val, n), - - TP_STRUCT__entry( - __field(unsigned int, cookie ) - __field(void *, page ) - __field(void *, val ) - __field(int, n ) - ), - - TP_fast_assign( - __entry->cookie = cookie->debug_id; - __entry->page = page; - __entry->val = val; - __entry->n = n; - ), - - TP_printk("c=%08x pg=%p val=%p n=%d", - __entry->cookie, __entry->page, __entry->val, __entry->n) - ); - -TRACE_EVENT(fscache_wake_cookie, - TP_PROTO(struct fscache_cookie *cookie), - - TP_ARGS(cookie), - - TP_STRUCT__entry( - __field(unsigned int, cookie ) - ), - - TP_fast_assign( - __entry->cookie = cookie->debug_id; - ), - - TP_printk("c=%08x", __entry->cookie) - ); - TRACE_EVENT(fscache_op, TP_PROTO(struct fscache_cookie *cookie, struct fscache_operation *op, enum fscache_op_trace why), @@ -440,83 +322,6 @@ TRACE_EVENT(fscache_op, __print_symbolic(__entry->why, fscache_op_traces)) ); -TRACE_EVENT(fscache_page_op, - TP_PROTO(struct fscache_cookie *cookie, struct page *page, - struct fscache_operation *op, enum fscache_page_op_trace what), - - TP_ARGS(cookie, page, op, what), - - TP_STRUCT__entry( - __field(unsigned int, cookie ) - __field(unsigned int, op ) - __field(pgoff_t, page ) - __field(enum fscache_page_op_trace, what ) - ), - - TP_fast_assign( - __entry->cookie = cookie->debug_id; - __entry->page = page ? page->index : 0; - __entry->op = op->debug_id; - __entry->what = what; - ), - - TP_printk("c=%08x %s pg=%lx op=%08x", - __entry->cookie, - __print_symbolic(__entry->what, fscache_page_op_traces), - __entry->page, __entry->op) - ); - -TRACE_EVENT(fscache_wrote_page, - TP_PROTO(struct fscache_cookie *cookie, struct page *page, - struct fscache_operation *op, int ret), - - TP_ARGS(cookie, page, op, ret), - - TP_STRUCT__entry( - __field(unsigned int, cookie ) - __field(unsigned int, op ) - __field(pgoff_t, page ) - __field(int, ret ) - ), - - TP_fast_assign( - __entry->cookie = cookie->debug_id; - __entry->page = page->index; - __entry->op = op->debug_id; - __entry->ret = ret; - ), - - TP_printk("c=%08x pg=%lx op=%08x ret=%d", - __entry->cookie, __entry->page, __entry->op, __entry->ret) - ); - -TRACE_EVENT(fscache_gang_lookup, - TP_PROTO(struct fscache_cookie *cookie, struct fscache_operation *op, - void **results, int n, pgoff_t store_limit), - - TP_ARGS(cookie, op, results, n, store_limit), - - TP_STRUCT__entry( - __field(unsigned int, cookie ) - __field(unsigned int, op ) - __field(pgoff_t, results0 ) - __field(int, n ) - __field(pgoff_t, store_limit ) - ), - - TP_fast_assign( - __entry->cookie = cookie->debug_id; - __entry->op = op->debug_id; - __entry->results0 = results[0] ? ((struct page *)results[0])->index : (pgoff_t)-1; - __entry->n = n; - __entry->store_limit = store_limit; - ), - - TP_printk("c=%08x op=%08x r0=%lx n=%d sl=%lx", - __entry->cookie, __entry->op, __entry->results0, __entry->n, - __entry->store_limit) - ); - #endif /* _TRACE_FSCACHE_H */ /* This part must be outside protection */ From patchwork Mon Oct 18 14:54:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566953 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A914CC433FE for ; Mon, 18 Oct 2021 14:54:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4CCBD60E0B for ; Mon, 18 Oct 2021 14:54:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232757AbhJRO4v (ORCPT ); Mon, 18 Oct 2021 10:56:51 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:22158 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232067AbhJRO4u (ORCPT ); Mon, 18 Oct 2021 10:56:50 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568879; 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=DdgLG/mjrbJRCYjiH5dWoD7UAqMfjeoEF8psWJ0FG/g=; b=BfkQlIem3NX5d7YJAe9wNjEgvTfZLvgAj+73WRP/fWuaanXvUskyf/jD66QU7/kiyrF994 UPcRif1OCopvkuvM2gb/2oBvanSP6NqHHgsz/yBxlXhQsP8IbBlrAhCdrkx/le4HS+H3XN MkxBubC9pLYQdeimTRseUqoXoeSeJ20= 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-164-hSrl2m95O5GPDAqgvMLhpA-1; Mon, 18 Oct 2021 10:54:36 -0400 X-MC-Unique: hSrl2m95O5GPDAqgvMLhpA-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id F39E180A5C5; Mon, 18 Oct 2021 14:54:33 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id BCB12ADCD; Mon, 18 Oct 2021 14:54:30 +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 14/67] fscache: Temporarily disable fscache_invalidate() From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:54:29 +0100 Message-ID: <163456886987.2614702.639114612962029576.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Temporarily disable the fscache side of fscache_invalidate() so that the operation managing code can be removed. Signed-off-by: David Howells --- fs/cachefiles/interface.c | 9 ++--- fs/fscache/cookie.c | 23 +----------- fs/fscache/object.c | 78 +---------------------------------------- include/linux/fscache-cache.h | 2 + 4 files changed, 7 insertions(+), 105 deletions(-) diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 4a813a490ffe..a84adf638737 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -388,7 +388,7 @@ static int cachefiles_attr_changed(struct cachefiles_object *object) /* * Invalidate an object */ -static void cachefiles_invalidate_object(struct fscache_operation *op) +static void cachefiles_invalidate_object(struct fscache_object *_object) { struct cachefiles_object *object; struct cachefiles_cache *cache; @@ -397,14 +397,14 @@ static void cachefiles_invalidate_object(struct fscache_operation *op) uint64_t ni_size; int ret; - object = container_of(op->object, struct cachefiles_object, fscache); + object = container_of(_object, struct cachefiles_object, fscache); cache = container_of(object->fscache.cache, struct cachefiles_cache, cache); - ni_size = op->object->cookie->object_size; + ni_size = object->fscache.cookie->object_size; _enter("{OBJ%x},[%llu]", - op->object->debug_id, (unsigned long long)ni_size); + object->fscache.debug_id, (unsigned long long)ni_size); if (object->backer) { ASSERT(d_is_reg(object->backer)); @@ -425,7 +425,6 @@ static void cachefiles_invalidate_object(struct fscache_operation *op) } } - fscache_op_complete(op, true); _leave(""); } diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 78938ea6ad1a..1a7372a1d1aa 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -612,8 +612,6 @@ static int fscache_attach_object(struct fscache_cookie *cookie, */ void __fscache_invalidate(struct fscache_cookie *cookie) { - struct fscache_object *object; - _enter("{%s}", cookie->type_name); fscache_stat(&fscache_n_invalidates); @@ -625,26 +623,7 @@ void __fscache_invalidate(struct fscache_cookie *cookie) */ ASSERTCMP(cookie->type, ==, FSCACHE_COOKIE_TYPE_DATAFILE); - /* If there's an object, we tell the object state machine to handle the - * invalidation on our behalf, otherwise there's nothing to do. - */ - if (!hlist_empty(&cookie->backing_objects)) { - spin_lock(&cookie->lock); - - if (fscache_cookie_enabled(cookie) && - !hlist_empty(&cookie->backing_objects) && - !test_and_set_bit(FSCACHE_COOKIE_INVALIDATING, - &cookie->flags)) { - object = hlist_entry(cookie->backing_objects.first, - struct fscache_object, - cookie_link); - if (fscache_object_is_live(object)) - fscache_raise_event( - object, FSCACHE_OBJECT_EV_INVALIDATE); - } - - spin_unlock(&cookie->lock); - } + /* TODO: Do invalidation */ _leave(""); } diff --git a/fs/fscache/object.c b/fs/fscache/object.c index 7aa1f90d978b..4941b961c079 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c @@ -899,86 +899,10 @@ static void fscache_dequeue_object(struct fscache_object *object) _leave(""); } -/* - * Asynchronously invalidate an object. - */ -static const struct fscache_state *_fscache_invalidate_object(struct fscache_object *object, - int event) -{ - struct fscache_operation *op; - struct fscache_cookie *cookie = object->cookie; - - _enter("{OBJ%x},%d", object->debug_id, event); - - /* We're going to need the cookie. If the cookie is not available then - * retire the object instead. - */ - if (!fscache_use_cookie(object)) { - set_bit(FSCACHE_OBJECT_RETIRED, &object->flags); - _leave(" [no cookie]"); - return transit_to(KILL_OBJECT); - } - - /* Reject any new read/write ops and abort any that are pending. */ - clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); - fscache_cancel_all_ops(object); - - /* Now we have to wait for in-progress reads and writes */ - op = kzalloc(sizeof(*op), GFP_KERNEL); - if (!op) - goto nomem; - - fscache_operation_init(cookie, op, object->cache->ops->invalidate_object, - NULL, NULL); - op->flags = FSCACHE_OP_ASYNC | - (1 << FSCACHE_OP_EXCLUSIVE) | - (1 << FSCACHE_OP_UNUSE_COOKIE); - - spin_lock(&cookie->lock); - if (fscache_submit_exclusive_op(object, op) < 0) - goto submit_op_failed; - spin_unlock(&cookie->lock); - fscache_put_operation(op); - - /* Once we've completed the invalidation, we know there will be no data - * stored in the cache and thus we can reinstate the data-check-skip - * optimisation. - */ - set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags); - - /* We can allow read and write requests to come in once again. They'll - * queue up behind our exclusive invalidation operation. - */ - if (test_and_clear_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags)) - wake_up_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING); - _leave(" [ok]"); - return transit_to(UPDATE_OBJECT); - -nomem: - fscache_mark_object_dead(object); - fscache_unuse_cookie(object); - _leave(" [ENOMEM]"); - return transit_to(KILL_OBJECT); - -submit_op_failed: - fscache_mark_object_dead(object); - spin_unlock(&cookie->lock); - fscache_unuse_cookie(object); - kfree(op); - _leave(" [EIO]"); - return transit_to(KILL_OBJECT); -} - static const struct fscache_state *fscache_invalidate_object(struct fscache_object *object, int event) { - const struct fscache_state *s; - - fscache_stat(&fscache_n_invalidates_run); - fscache_stat(&fscache_n_cop_invalidate_object); - s = _fscache_invalidate_object(object, event); - fscache_stat_d(&fscache_n_cop_invalidate_object); - return s; + return transit_to(UPDATE_OBJECT); } /* diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index d0c6c09bb5a1..436456d4ff64 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -171,7 +171,7 @@ struct fscache_cache_ops { void (*update_object)(struct fscache_object *object); /* Invalidate an object */ - void (*invalidate_object)(struct fscache_operation *op); + void (*invalidate_object)(struct fscache_object *object); /* discard the resources pinned by an object and effect retirement if * necessary */ From patchwork Mon Oct 18 14:54:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566955 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C1E01C43217 for ; Mon, 18 Oct 2021 14:54:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AC54761038 for ; Mon, 18 Oct 2021 14:54:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232471AbhJRO5F (ORCPT ); Mon, 18 Oct 2021 10:57:05 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:25570 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232527AbhJRO5C (ORCPT ); Mon, 18 Oct 2021 10:57:02 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568890; 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=HLyJpHLHgdEk/dLhjAzTgQqnW46fpcyamO0/BfGexg0=; b=OdSCD+Ucp/Y3/VN1/zpZcZKDO0L0LNDMzeopXUN4QCYKFu9uI9Uz+3A0ELIc2y/14WJ5Zg 4arQqlzukYZYIVP4A+c851wwouPlHSBdtDOenV7oAGo6Wsd/YlUuo46gwic1GjtT0C5J/Z lu7VKqxmaQPWfa4jHjs3h+S2qn/JOn0= 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-490-4SBX_taHOHi2d4qgCr4dFg-1; Mon, 18 Oct 2021 10:54:45 -0400 X-MC-Unique: 4SBX_taHOHi2d4qgCr4dFg-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3F116800685; Mon, 18 Oct 2021 14:54:43 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id F03675DF21; Mon, 18 Oct 2021 14:54:39 +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 15/67] fscache: Disable fscache_begin_operation() From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:54:39 +0100 Message-ID: <163456887921.2614702.840718814028578881.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Disable fscache_begin_operation() so that the operation manager can be removed and replaced. Signed-off-by: David Howells --- fs/cachefiles/io.c | 13 ++++++++++++- fs/fscache/io.c | 2 ++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index 5ead97de4bb7..4cc57be88f37 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -271,6 +271,7 @@ static int cachefiles_write(struct netfs_cache_resources *cres, static enum netfs_read_source cachefiles_prepare_read(struct netfs_read_subrequest *subreq, loff_t i_size) { +#if 0 struct fscache_operation *op = subreq->rreq->cache_resources.cache_priv; struct cachefiles_object *object; struct cachefiles_cache *cache; @@ -335,6 +336,9 @@ static enum netfs_read_source cachefiles_prepare_read(struct netfs_read_subreque out: cachefiles_end_secure(cache, saved_cred); return ret; +#endif + return subreq->start >= i_size ? + NETFS_FILL_WITH_ZEROES : NETFS_DOWNLOAD_FROM_SERVER; } /* @@ -359,6 +363,7 @@ static int cachefiles_prepare_write(struct netfs_cache_resources *cres, static int cachefiles_prepare_fallback_write(struct netfs_cache_resources *cres, pgoff_t index) { +#if 0 struct fscache_operation *op = cres->cache_priv; struct cachefiles_object *object; struct cachefiles_cache *cache; @@ -369,6 +374,8 @@ static int cachefiles_prepare_fallback_write(struct netfs_cache_resources *cres, cache = container_of(object->fscache.cache, struct cachefiles_cache, cache); return cachefiles_has_space(cache, 0, 1); +#endif + return -ENOBUFS; } /* @@ -376,6 +383,7 @@ static int cachefiles_prepare_fallback_write(struct netfs_cache_resources *cres, */ static void cachefiles_end_operation(struct netfs_cache_resources *cres) { +#if 0 struct fscache_operation *op = cres->cache_priv; struct file *file = cres->cache_priv2; @@ -387,8 +395,8 @@ static void cachefiles_end_operation(struct netfs_cache_resources *cres) fscache_op_complete(op, false); fscache_put_operation(op); } - _leave(""); +#endif } static const struct netfs_cache_ops cachefiles_netfs_cache_ops = { @@ -406,6 +414,7 @@ static const struct netfs_cache_ops cachefiles_netfs_cache_ops = { int cachefiles_begin_operation(struct netfs_cache_resources *cres, struct fscache_operation *op) { +#if 0 struct cachefiles_object *object; struct cachefiles_cache *cache; struct path path; @@ -441,5 +450,7 @@ int cachefiles_begin_operation(struct netfs_cache_resources *cres, error_file: fput(file); +#endif + cres->ops = &cachefiles_netfs_cache_ops; return -EIO; } diff --git a/fs/fscache/io.c b/fs/fscache/io.c index 7ac34c2e45fe..2547892a6064 100644 --- a/fs/fscache/io.c +++ b/fs/fscache/io.c @@ -31,6 +31,7 @@ int __fscache_begin_operation(struct netfs_cache_resources *cres, struct fscache_cookie *cookie, bool for_write) { +#if 0 struct fscache_operation *op; struct fscache_object *object; bool wake_cookie = false; @@ -144,6 +145,7 @@ int __fscache_begin_operation(struct netfs_cache_resources *cres, fscache_stat(&fscache_n_stores_nobufs); else fscache_stat(&fscache_n_retrievals_nobufs); +#endif _leave(" = -ENOBUFS"); return -ENOBUFS; } From patchwork Mon Oct 18 14:54:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566957 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5102BC433F5 for ; Mon, 18 Oct 2021 14:55:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2D1C360E0B for ; Mon, 18 Oct 2021 14:55:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232531AbhJRO5W (ORCPT ); Mon, 18 Oct 2021 10:57:22 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:25911 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232528AbhJRO5T (ORCPT ); Mon, 18 Oct 2021 10:57:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568908; 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=UiKELG3MEArxFoSfeVD5KyMYYvMx0wd18LN1ojcWqAg=; b=Ek7usJ6aBWB9INoRBaKDRjxkv3wRYbzTZyHfSnseL+iPXpKaUI6pzbvf/95wMgceeuijv6 y4ysRAZpgbmIzf7MxugHLMbMw1itf6sMvLa9A4RGhqJOYyfiHPpWM6MwJ/gMngHQUEqyZh vplKIUrRYt+bpmn86T9hVELnYgWkCCE= 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-500-JNxIKxsqMteFIDvxhySZPQ-1; Mon, 18 Oct 2021 10:55:04 -0400 X-MC-Unique: JNxIKxsqMteFIDvxhySZPQ-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C1E775A095; Mon, 18 Oct 2021 14:55:02 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 72BC2E2D0; Mon, 18 Oct 2021 14:54:49 +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 16/67] fscache: Remove the I/O operation manager From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:54:48 +0100 Message-ID: <163456888847.2614702.13600092451979671015.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Remove the fscache I/O operation manager. Getting operation-operation interactions and object-operation interactions correct has proven really difficult; furthermore, the operations are being replaced with kiocb-driven stuff on the cache front. Signed-off-by: David Howells --- fs/cachefiles/internal.h | 3 fs/cachefiles/io.c | 3 fs/cachefiles/namei.c | 5 fs/fscache/Makefile | 4 fs/fscache/cache.c | 3 fs/fscache/cookie.c | 1 fs/fscache/internal.h | 22 - fs/fscache/object.c | 24 -- fs/fscache/operation.c | 633 ---------------------------------------- include/linux/fscache-cache.h | 74 ----- include/trace/events/fscache.h | 57 ---- 11 files changed, 7 insertions(+), 822 deletions(-) delete mode 100644 fs/fscache/operation.c diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index f6b85c370935..fbe43e1aa517 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -150,8 +150,7 @@ extern int cachefiles_check_in_use(struct cachefiles_cache *cache, /* * rdwr2.c */ -extern int cachefiles_begin_operation(struct netfs_cache_resources *, - struct fscache_operation *); +extern int cachefiles_begin_operation(struct netfs_cache_resources *); /* * security.c diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index 4cc57be88f37..534c81a05918 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -411,8 +411,7 @@ static const struct netfs_cache_ops cachefiles_netfs_cache_ops = { /* * Open the cache file when beginning a cache operation. */ -int cachefiles_begin_operation(struct netfs_cache_resources *cres, - struct fscache_operation *op) +int cachefiles_begin_operation(struct netfs_cache_resources *cres) { #if 0 struct cachefiles_object *object; diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index dc5e1e48c0a8..548aac544293 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -36,9 +36,8 @@ void __cachefiles_printk_object(struct cachefiles_object *object, prefix, object->fscache.state->name, object->fscache.flags, work_busy(&object->fscache.work), object->fscache.events, object->fscache.event_mask); - pr_err("%sops=%u inp=%u exc=%u\n", - prefix, object->fscache.n_ops, object->fscache.n_in_progress, - object->fscache.n_exclusive); + pr_err("%sops=%u\n", + prefix, object->fscache.n_ops); pr_err("%sparent=%x\n", prefix, object->fscache.parent ? object->fscache.parent->debug_id : 0); diff --git a/fs/fscache/Makefile b/fs/fscache/Makefile index 03a871d689bb..14dfdce1c045 100644 --- a/fs/fscache/Makefile +++ b/fs/fscache/Makefile @@ -10,9 +10,7 @@ fscache-y := \ io.o \ main.o \ netfs.o \ - object.o \ - operation.o \ - page.o + object.o fscache-$(CONFIG_PROC_FS) += proc.o fscache-$(CONFIG_FSCACHE_STATS) += stats.o diff --git a/fs/fscache/cache.c b/fs/fscache/cache.c index efcdb40267d6..efcd834d6279 100644 --- a/fs/fscache/cache.c +++ b/fs/fscache/cache.c @@ -182,12 +182,9 @@ void fscache_init_cache(struct fscache_cache *cache, vsnprintf(cache->identifier, sizeof(cache->identifier), idfmt, va); va_end(va); - INIT_WORK(&cache->op_gc, fscache_operation_gc); INIT_LIST_HEAD(&cache->link); INIT_LIST_HEAD(&cache->object_list); - INIT_LIST_HEAD(&cache->op_gc_list); spin_lock_init(&cache->object_list_lock); - spin_lock_init(&cache->op_gc_list_lock); } EXPORT_SYMBOL(fscache_init_cache); diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 1a7372a1d1aa..62f3a4f75bad 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -722,7 +722,6 @@ void __fscache_disable_cookie(struct fscache_cookie *cookie, hlist_for_each_entry(object, &cookie->backing_objects, cookie_link) { if (invalidate) set_bit(FSCACHE_OBJECT_RETIRED, &object->flags); - clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); fscache_raise_event(object, FSCACHE_OBJECT_EV_KILL); } } else { diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index 43d64f6bbf8b..b8da3fe2d6f1 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h @@ -112,28 +112,6 @@ static inline bool fscache_object_congested(void) */ extern void fscache_enqueue_object(struct fscache_object *); -/* - * operation.c - */ -extern int fscache_submit_exclusive_op(struct fscache_object *, - struct fscache_operation *); -extern int fscache_submit_op(struct fscache_object *, - struct fscache_operation *); -extern int fscache_cancel_op(struct fscache_operation *, bool); -extern void fscache_cancel_all_ops(struct fscache_object *); -extern void fscache_abort_object(struct fscache_object *); -extern void fscache_start_operations(struct fscache_object *); -extern void fscache_operation_gc(struct work_struct *); - -/* - * page.c - */ -extern int fscache_wait_for_deferred_lookup(struct fscache_cookie *); -extern int fscache_wait_for_operation_activation(struct fscache_object *, - struct fscache_operation *, - atomic_t *, - atomic_t *); - /* * proc.c */ diff --git a/fs/fscache/object.c b/fs/fscache/object.c index 4941b961c079..c7fbdcf3e987 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c @@ -311,9 +311,8 @@ void fscache_object_init(struct fscache_object *object, INIT_WORK(&object->work, fscache_object_work_func); INIT_LIST_HEAD(&object->dependents); INIT_LIST_HEAD(&object->dep_link); - INIT_LIST_HEAD(&object->pending_ops); object->n_children = 0; - object->n_ops = object->n_in_progress = object->n_exclusive = 0; + object->n_ops = 0; object->events = 0; object->cache = cache; object->cookie = cookie; @@ -574,14 +573,6 @@ static const struct fscache_state *fscache_object_available(struct fscache_objec spin_lock(&object->lock); fscache_done_parent_op(object); - if (object->n_in_progress == 0) { - if (object->n_ops > 0) { - ASSERTCMP(object->n_ops, >=, object->n_obj_ops); - fscache_start_operations(object); - } else { - ASSERT(list_empty(&object->pending_ops)); - } - } spin_unlock(&object->lock); fscache_stat(&fscache_n_cop_lookup_complete); @@ -647,24 +638,11 @@ static const struct fscache_state *fscache_kill_object(struct fscache_object *ob fscache_mark_object_dead(object); object->oob_event_mask = 0; - if (test_bit(FSCACHE_OBJECT_RETIRED, &object->flags)) { - /* Reject any new read/write ops and abort any that are pending. */ - clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); - fscache_cancel_all_ops(object); - } - if (list_empty(&object->dependents) && object->n_ops == 0 && object->n_children == 0) return transit_to(DROP_OBJECT); - if (object->n_in_progress == 0) { - spin_lock(&object->lock); - if (object->n_ops > 0 && object->n_in_progress == 0) - fscache_start_operations(object); - spin_unlock(&object->lock); - } - if (!list_empty(&object->dependents)) return transit_to(KILL_DEPENDENTS); diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c deleted file mode 100644 index e002cdfaf3cc..000000000000 --- a/fs/fscache/operation.c +++ /dev/null @@ -1,633 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* FS-Cache worker operation management routines - * - * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * See Documentation/filesystems/caching/operations.rst - */ - -#define FSCACHE_DEBUG_LEVEL OPERATION -#include -#include -#include -#include "internal.h" - -atomic_t fscache_op_debug_id; -EXPORT_SYMBOL(fscache_op_debug_id); - -static void fscache_operation_dummy_cancel(struct fscache_operation *op) -{ -} - -/** - * fscache_operation_init - Do basic initialisation of an operation - * @cookie: The cookie to operate on - * @op: The operation to initialise - * @processor: The function to perform the operation - * @cancel: A function to handle operation cancellation - * @release: The release function to assign - * - * Do basic initialisation of an operation. The caller must still set flags, - * object and processor if needed. - */ -void fscache_operation_init(struct fscache_cookie *cookie, - struct fscache_operation *op, - fscache_operation_processor_t processor, - fscache_operation_cancel_t cancel, - fscache_operation_release_t release) -{ - INIT_WORK(&op->work, fscache_op_work_func); - atomic_set(&op->usage, 1); - op->state = FSCACHE_OP_ST_INITIALISED; - op->debug_id = atomic_inc_return(&fscache_op_debug_id); - op->processor = processor; - op->cancel = cancel ?: fscache_operation_dummy_cancel; - op->release = release; - INIT_LIST_HEAD(&op->pend_link); - fscache_stat(&fscache_n_op_initialised); - trace_fscache_op(cookie, op, fscache_op_init); -} -EXPORT_SYMBOL(fscache_operation_init); - -/** - * fscache_enqueue_operation - Enqueue an operation for processing - * @op: The operation to enqueue - * - * Enqueue an operation for processing by the FS-Cache thread pool. - * - * This will get its own ref on the object. - */ -void fscache_enqueue_operation(struct fscache_operation *op) -{ - struct fscache_cookie *cookie = op->object->cookie; - - _enter("{OBJ%x OP%x,%u}", - op->object->debug_id, op->debug_id, atomic_read(&op->usage)); - - ASSERT(list_empty(&op->pend_link)); - ASSERT(op->processor != NULL); - ASSERT(fscache_object_is_available(op->object)); - ASSERTCMP(atomic_read(&op->usage), >, 0); - ASSERTIFCMP(op->state != FSCACHE_OP_ST_IN_PROGRESS, - op->state, ==, FSCACHE_OP_ST_CANCELLED); - - fscache_stat(&fscache_n_op_enqueue); - switch (op->flags & FSCACHE_OP_TYPE) { - case FSCACHE_OP_ASYNC: - trace_fscache_op(cookie, op, fscache_op_enqueue_async); - _debug("queue async"); - atomic_inc(&op->usage); - if (!queue_work(fscache_op_wq, &op->work)) - fscache_put_operation(op); - break; - case FSCACHE_OP_MYTHREAD: - trace_fscache_op(cookie, op, fscache_op_enqueue_mythread); - _debug("queue for caller's attention"); - break; - default: - pr_err("Unexpected op type %lx", op->flags); - BUG(); - break; - } -} -EXPORT_SYMBOL(fscache_enqueue_operation); - -/* - * start an op running - */ -static void fscache_run_op(struct fscache_object *object, - struct fscache_operation *op) -{ - ASSERTCMP(op->state, ==, FSCACHE_OP_ST_PENDING); - - op->state = FSCACHE_OP_ST_IN_PROGRESS; - object->n_in_progress++; - if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) - wake_up_bit(&op->flags, FSCACHE_OP_WAITING); - if (op->processor) - fscache_enqueue_operation(op); - else - trace_fscache_op(object->cookie, op, fscache_op_run); - fscache_stat(&fscache_n_op_run); -} - -/* - * report an unexpected submission - */ -static void fscache_report_unexpected_submission(struct fscache_object *object, - struct fscache_operation *op, - const struct fscache_state *ostate) -{ - static bool once_only; - struct fscache_operation *p; - unsigned n; - - if (once_only) - return; - once_only = true; - - kdebug("unexpected submission OP%x [OBJ%x %s]", - op->debug_id, object->debug_id, object->state->name); - kdebug("objstate=%s [%s]", object->state->name, ostate->name); - kdebug("objflags=%lx", object->flags); - kdebug("objevent=%lx [%lx]", object->events, object->event_mask); - kdebug("ops=%u inp=%u exc=%u", - object->n_ops, object->n_in_progress, object->n_exclusive); - - if (!list_empty(&object->pending_ops)) { - n = 0; - list_for_each_entry(p, &object->pending_ops, pend_link) { - ASSERTCMP(p->object, ==, object); - kdebug("%p %p", op->processor, op->release); - n++; - } - - kdebug("n=%u", n); - } - - dump_stack(); -} - -/* - * submit an exclusive operation for an object - * - other ops are excluded from running simultaneously with this one - * - this gets any extra refs it needs on an op - */ -int fscache_submit_exclusive_op(struct fscache_object *object, - struct fscache_operation *op) -{ - const struct fscache_state *ostate; - unsigned long flags; - int ret; - - _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id); - - trace_fscache_op(object->cookie, op, fscache_op_submit_ex); - - ASSERTCMP(op->state, ==, FSCACHE_OP_ST_INITIALISED); - ASSERTCMP(atomic_read(&op->usage), >, 0); - - spin_lock(&object->lock); - ASSERTCMP(object->n_ops, >=, object->n_in_progress); - ASSERTCMP(object->n_ops, >=, object->n_exclusive); - ASSERT(list_empty(&op->pend_link)); - - ostate = object->state; - smp_rmb(); - - op->state = FSCACHE_OP_ST_PENDING; - flags = READ_ONCE(object->flags); - if (unlikely(!(flags & BIT(FSCACHE_OBJECT_IS_LIVE)))) { - fscache_stat(&fscache_n_op_rejected); - op->cancel(op); - op->state = FSCACHE_OP_ST_CANCELLED; - ret = -ENOBUFS; - } else if (unlikely(fscache_cache_is_broken(object))) { - op->cancel(op); - op->state = FSCACHE_OP_ST_CANCELLED; - ret = -EIO; - } else if (flags & BIT(FSCACHE_OBJECT_IS_AVAILABLE)) { - op->object = object; - object->n_ops++; - object->n_exclusive++; /* reads and writes must wait */ - - if (object->n_in_progress > 0) { - atomic_inc(&op->usage); - list_add_tail(&op->pend_link, &object->pending_ops); - fscache_stat(&fscache_n_op_pend); - } else if (!list_empty(&object->pending_ops)) { - atomic_inc(&op->usage); - list_add_tail(&op->pend_link, &object->pending_ops); - fscache_stat(&fscache_n_op_pend); - fscache_start_operations(object); - } else { - ASSERTCMP(object->n_in_progress, ==, 0); - fscache_run_op(object, op); - } - - /* need to issue a new write op after this */ - clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); - ret = 0; - } else if (flags & BIT(FSCACHE_OBJECT_IS_LOOKED_UP)) { - op->object = object; - object->n_ops++; - object->n_exclusive++; /* reads and writes must wait */ - atomic_inc(&op->usage); - list_add_tail(&op->pend_link, &object->pending_ops); - fscache_stat(&fscache_n_op_pend); - ret = 0; - } else if (flags & BIT(FSCACHE_OBJECT_KILLED_BY_CACHE)) { - op->cancel(op); - op->state = FSCACHE_OP_ST_CANCELLED; - ret = -ENOBUFS; - } else { - fscache_report_unexpected_submission(object, op, ostate); - op->cancel(op); - op->state = FSCACHE_OP_ST_CANCELLED; - ret = -ENOBUFS; - } - - spin_unlock(&object->lock); - return ret; -} - -/* - * submit an operation for an object - * - objects may be submitted only in the following states: - * - during object creation (write ops may be submitted) - * - whilst the object is active - * - after an I/O error incurred in one of the two above states (op rejected) - * - this gets any extra refs it needs on an op - */ -int fscache_submit_op(struct fscache_object *object, - struct fscache_operation *op) -{ - const struct fscache_state *ostate; - unsigned long flags; - int ret; - - _enter("{OBJ%x OP%x},{%u}", - object->debug_id, op->debug_id, atomic_read(&op->usage)); - - trace_fscache_op(object->cookie, op, fscache_op_submit); - - ASSERTCMP(op->state, ==, FSCACHE_OP_ST_INITIALISED); - ASSERTCMP(atomic_read(&op->usage), >, 0); - - spin_lock(&object->lock); - ASSERTCMP(object->n_ops, >=, object->n_in_progress); - ASSERTCMP(object->n_ops, >=, object->n_exclusive); - ASSERT(list_empty(&op->pend_link)); - - ostate = object->state; - smp_rmb(); - - op->state = FSCACHE_OP_ST_PENDING; - flags = READ_ONCE(object->flags); - if (unlikely(!(flags & BIT(FSCACHE_OBJECT_IS_LIVE)))) { - fscache_stat(&fscache_n_op_rejected); - op->cancel(op); - op->state = FSCACHE_OP_ST_CANCELLED; - ret = -ENOBUFS; - } else if (unlikely(fscache_cache_is_broken(object))) { - op->cancel(op); - op->state = FSCACHE_OP_ST_CANCELLED; - ret = -EIO; - } else if (flags & BIT(FSCACHE_OBJECT_IS_AVAILABLE)) { - op->object = object; - object->n_ops++; - - if (object->n_exclusive > 0) { - atomic_inc(&op->usage); - list_add_tail(&op->pend_link, &object->pending_ops); - fscache_stat(&fscache_n_op_pend); - } else if (!list_empty(&object->pending_ops)) { - atomic_inc(&op->usage); - list_add_tail(&op->pend_link, &object->pending_ops); - fscache_stat(&fscache_n_op_pend); - fscache_start_operations(object); - } else { - ASSERTCMP(object->n_exclusive, ==, 0); - fscache_run_op(object, op); - } - ret = 0; - } else if (flags & BIT(FSCACHE_OBJECT_IS_LOOKED_UP)) { - op->object = object; - object->n_ops++; - atomic_inc(&op->usage); - list_add_tail(&op->pend_link, &object->pending_ops); - fscache_stat(&fscache_n_op_pend); - ret = 0; - } else if (flags & BIT(FSCACHE_OBJECT_KILLED_BY_CACHE)) { - op->cancel(op); - op->state = FSCACHE_OP_ST_CANCELLED; - ret = -ENOBUFS; - } else { - fscache_report_unexpected_submission(object, op, ostate); - ASSERT(!fscache_object_is_active(object)); - op->cancel(op); - op->state = FSCACHE_OP_ST_CANCELLED; - ret = -ENOBUFS; - } - - spin_unlock(&object->lock); - return ret; -} - -/* - * queue an object for withdrawal on error, aborting all following asynchronous - * operations - */ -void fscache_abort_object(struct fscache_object *object) -{ - _enter("{OBJ%x}", object->debug_id); - - fscache_raise_event(object, FSCACHE_OBJECT_EV_ERROR); -} - -/* - * Jump start the operation processing on an object. The caller must hold - * object->lock. - */ -void fscache_start_operations(struct fscache_object *object) -{ - struct fscache_operation *op; - bool stop = false; - - while (!list_empty(&object->pending_ops) && !stop) { - op = list_entry(object->pending_ops.next, - struct fscache_operation, pend_link); - - if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) { - if (object->n_in_progress > 0) - break; - stop = true; - } - list_del_init(&op->pend_link); - fscache_run_op(object, op); - - /* the pending queue was holding a ref on the object */ - fscache_put_operation(op); - } - - ASSERTCMP(object->n_in_progress, <=, object->n_ops); - - _debug("woke %d ops on OBJ%x", - object->n_in_progress, object->debug_id); -} - -/* - * cancel an operation that's pending on an object - */ -int fscache_cancel_op(struct fscache_operation *op, - bool cancel_in_progress_op) -{ - struct fscache_object *object = op->object; - bool put = false; - int ret; - - _enter("OBJ%x OP%x}", op->object->debug_id, op->debug_id); - - trace_fscache_op(object->cookie, op, fscache_op_cancel); - - ASSERTCMP(op->state, >=, FSCACHE_OP_ST_PENDING); - ASSERTCMP(op->state, !=, FSCACHE_OP_ST_CANCELLED); - ASSERTCMP(atomic_read(&op->usage), >, 0); - - spin_lock(&object->lock); - - ret = -EBUSY; - if (op->state == FSCACHE_OP_ST_PENDING) { - ASSERT(!list_empty(&op->pend_link)); - list_del_init(&op->pend_link); - put = true; - - fscache_stat(&fscache_n_op_cancelled); - op->cancel(op); - op->state = FSCACHE_OP_ST_CANCELLED; - if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) - object->n_exclusive--; - if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) - wake_up_bit(&op->flags, FSCACHE_OP_WAITING); - ret = 0; - } else if (op->state == FSCACHE_OP_ST_IN_PROGRESS && cancel_in_progress_op) { - ASSERTCMP(object->n_in_progress, >, 0); - if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) - object->n_exclusive--; - object->n_in_progress--; - if (object->n_in_progress == 0) - fscache_start_operations(object); - - fscache_stat(&fscache_n_op_cancelled); - op->cancel(op); - op->state = FSCACHE_OP_ST_CANCELLED; - if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) - object->n_exclusive--; - if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) - wake_up_bit(&op->flags, FSCACHE_OP_WAITING); - ret = 0; - } - - if (put) - fscache_put_operation(op); - spin_unlock(&object->lock); - _leave(" = %d", ret); - return ret; -} - -/* - * Cancel all pending operations on an object - */ -void fscache_cancel_all_ops(struct fscache_object *object) -{ - struct fscache_operation *op; - - _enter("OBJ%x", object->debug_id); - - spin_lock(&object->lock); - - while (!list_empty(&object->pending_ops)) { - op = list_entry(object->pending_ops.next, - struct fscache_operation, pend_link); - fscache_stat(&fscache_n_op_cancelled); - list_del_init(&op->pend_link); - - trace_fscache_op(object->cookie, op, fscache_op_cancel_all); - - ASSERTCMP(op->state, ==, FSCACHE_OP_ST_PENDING); - op->cancel(op); - op->state = FSCACHE_OP_ST_CANCELLED; - - if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) - object->n_exclusive--; - if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) - wake_up_bit(&op->flags, FSCACHE_OP_WAITING); - fscache_put_operation(op); - cond_resched_lock(&object->lock); - } - - spin_unlock(&object->lock); - _leave(""); -} - -/* - * Record the completion or cancellation of an in-progress operation. - */ -void fscache_op_complete(struct fscache_operation *op, bool cancelled) -{ - struct fscache_object *object = op->object; - - _enter("OBJ%x", object->debug_id); - - ASSERTCMP(op->state, ==, FSCACHE_OP_ST_IN_PROGRESS); - ASSERTCMP(object->n_in_progress, >, 0); - ASSERTIFCMP(test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags), - object->n_exclusive, >, 0); - ASSERTIFCMP(test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags), - object->n_in_progress, ==, 1); - - spin_lock(&object->lock); - - if (!cancelled) { - trace_fscache_op(object->cookie, op, fscache_op_completed); - op->state = FSCACHE_OP_ST_COMPLETE; - } else { - op->cancel(op); - trace_fscache_op(object->cookie, op, fscache_op_cancelled); - op->state = FSCACHE_OP_ST_CANCELLED; - } - - if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) - object->n_exclusive--; - object->n_in_progress--; - if (object->n_in_progress == 0) - fscache_start_operations(object); - - spin_unlock(&object->lock); - _leave(""); -} -EXPORT_SYMBOL(fscache_op_complete); - -/* - * release an operation - * - queues pending ops if this is the last in-progress op - */ -void fscache_put_operation(struct fscache_operation *op) -{ - struct fscache_object *object; - struct fscache_cache *cache; - - _enter("{OBJ%x OP%x,%d}", - op->object ? op->object->debug_id : 0, - op->debug_id, atomic_read(&op->usage)); - - ASSERTCMP(atomic_read(&op->usage), >, 0); - - if (!atomic_dec_and_test(&op->usage)) - return; - - trace_fscache_op(op->object ? op->object->cookie : NULL, op, fscache_op_put); - - _debug("PUT OP"); - ASSERTIFCMP(op->state != FSCACHE_OP_ST_INITIALISED && - op->state != FSCACHE_OP_ST_COMPLETE, - op->state, ==, FSCACHE_OP_ST_CANCELLED); - - fscache_stat(&fscache_n_op_release); - - if (op->release) { - op->release(op); - op->release = NULL; - } - op->state = FSCACHE_OP_ST_DEAD; - - object = op->object; - if (likely(object)) { - if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags)) - atomic_dec(&object->n_reads); - if (test_bit(FSCACHE_OP_UNUSE_COOKIE, &op->flags)) - fscache_unuse_cookie(object); - - /* now... we may get called with the object spinlock held, so we - * complete the cleanup here only if we can immediately acquire the - * lock, and defer it otherwise */ - if (!spin_trylock(&object->lock)) { - _debug("defer put"); - fscache_stat(&fscache_n_op_deferred_release); - - cache = object->cache; - spin_lock(&cache->op_gc_list_lock); - list_add_tail(&op->pend_link, &cache->op_gc_list); - spin_unlock(&cache->op_gc_list_lock); - schedule_work(&cache->op_gc); - _leave(" [defer]"); - return; - } - - ASSERTCMP(object->n_ops, >, 0); - object->n_ops--; - if (object->n_ops == 0) - fscache_raise_event(object, FSCACHE_OBJECT_EV_CLEARED); - - spin_unlock(&object->lock); - } - - kfree(op); - _leave(" [done]"); -} -EXPORT_SYMBOL(fscache_put_operation); - -/* - * garbage collect operations that have had their release deferred - */ -void fscache_operation_gc(struct work_struct *work) -{ - struct fscache_operation *op; - struct fscache_object *object; - struct fscache_cache *cache = - container_of(work, struct fscache_cache, op_gc); - int count = 0; - - _enter(""); - - do { - spin_lock(&cache->op_gc_list_lock); - if (list_empty(&cache->op_gc_list)) { - spin_unlock(&cache->op_gc_list_lock); - break; - } - - op = list_entry(cache->op_gc_list.next, - struct fscache_operation, pend_link); - list_del(&op->pend_link); - spin_unlock(&cache->op_gc_list_lock); - - object = op->object; - trace_fscache_op(object->cookie, op, fscache_op_gc); - - spin_lock(&object->lock); - - _debug("GC DEFERRED REL OBJ%x OP%x", - object->debug_id, op->debug_id); - fscache_stat(&fscache_n_op_gc); - - ASSERTCMP(atomic_read(&op->usage), ==, 0); - ASSERTCMP(op->state, ==, FSCACHE_OP_ST_DEAD); - - ASSERTCMP(object->n_ops, >, 0); - object->n_ops--; - if (object->n_ops == 0) - fscache_raise_event(object, FSCACHE_OBJECT_EV_CLEARED); - - spin_unlock(&object->lock); - kfree(op); - - } while (count++ < 20); - - if (!list_empty(&cache->op_gc_list)) - schedule_work(&cache->op_gc); - - _leave(""); -} - -/* - * execute an operation using fs_op_wq to provide processing context - - * the caller holds a ref to this object, so we don't need to hold one - */ -void fscache_op_work_func(struct work_struct *work) -{ - struct fscache_operation *op = - container_of(work, struct fscache_operation, work); - - _enter("{OBJ%x OP%x,%d}", - op->object->debug_id, op->debug_id, atomic_read(&op->usage)); - - trace_fscache_op(op->object->cookie, op, fscache_op_work); - - ASSERT(op->processor != NULL); - op->processor(op); - fscache_put_operation(op); - - _leave(""); -} diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index 436456d4ff64..c5d454f340c6 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -23,7 +23,6 @@ struct fscache_cache; struct fscache_cache_ops; struct fscache_object; -struct fscache_operation; enum fscache_obj_ref_trace { fscache_obj_get_add_to_deps, @@ -62,11 +61,8 @@ struct fscache_cache { char identifier[36]; /* cache label */ /* node management */ - struct work_struct op_gc; /* operation garbage collector */ struct list_head object_list; /* list of data/index objects */ - struct list_head op_gc_list; /* list of ops to be deleted */ spinlock_t object_list_lock; - spinlock_t op_gc_list_lock; atomic_t object_count; /* no. of live objects in this cache */ struct fscache_object *fsdef; /* object for the fsdef index */ unsigned long flags; @@ -76,68 +72,6 @@ struct fscache_cache { extern wait_queue_head_t fscache_cache_cleared_wq; -/* - * operation to be applied to a cache object - * - retrieval initiation operations are done in the context of the process - * that issued them, and not in an async thread pool - */ -typedef void (*fscache_operation_release_t)(struct fscache_operation *op); -typedef void (*fscache_operation_processor_t)(struct fscache_operation *op); -typedef void (*fscache_operation_cancel_t)(struct fscache_operation *op); - -enum fscache_operation_state { - FSCACHE_OP_ST_BLANK, /* Op is not yet submitted */ - FSCACHE_OP_ST_INITIALISED, /* Op is initialised */ - FSCACHE_OP_ST_PENDING, /* Op is blocked from running */ - FSCACHE_OP_ST_IN_PROGRESS, /* Op is in progress */ - FSCACHE_OP_ST_COMPLETE, /* Op is complete */ - FSCACHE_OP_ST_CANCELLED, /* Op has been cancelled */ - FSCACHE_OP_ST_DEAD /* Op is now dead */ -}; - -struct fscache_operation { - struct work_struct work; /* record for async ops */ - struct list_head pend_link; /* link in object->pending_ops */ - struct fscache_object *object; /* object to be operated upon */ - - unsigned long flags; -#define FSCACHE_OP_TYPE 0x000f /* operation type */ -#define FSCACHE_OP_ASYNC 0x0001 /* - async op, processor may sleep for disk */ -#define FSCACHE_OP_MYTHREAD 0x0002 /* - processing is done be issuing thread, not pool */ -#define FSCACHE_OP_WAITING 4 /* cleared when op is woken */ -#define FSCACHE_OP_EXCLUSIVE 5 /* exclusive op, other ops must wait */ -#define FSCACHE_OP_DEC_READ_CNT 6 /* decrement object->n_reads on destruction */ -#define FSCACHE_OP_UNUSE_COOKIE 7 /* call fscache_unuse_cookie() on completion */ -#define FSCACHE_OP_KEEP_FLAGS 0x00f0 /* flags to keep when repurposing an op */ - - enum fscache_operation_state state; - atomic_t usage; - unsigned debug_id; /* debugging ID */ - - /* operation processor callback - * - can be NULL if FSCACHE_OP_WAITING is going to be used to perform - * the op in a non-pool thread */ - fscache_operation_processor_t processor; - - /* Operation cancellation cleanup (optional) */ - fscache_operation_cancel_t cancel; - - /* operation releaser */ - fscache_operation_release_t release; -}; - -extern atomic_t fscache_op_debug_id; -extern void fscache_op_work_func(struct work_struct *work); - -extern void fscache_enqueue_operation(struct fscache_operation *); -extern void fscache_op_complete(struct fscache_operation *, bool); -extern void fscache_put_operation(struct fscache_operation *); -extern void fscache_operation_init(struct fscache_cookie *, - struct fscache_operation *, - fscache_operation_processor_t, - fscache_operation_cancel_t, - fscache_operation_release_t); - /* * cache operations */ @@ -188,8 +122,7 @@ struct fscache_cache_ops { int (*reserve_space)(struct fscache_object *object, loff_t i_size); /* Begin an operation for the netfs lib */ - int (*begin_operation)(struct netfs_cache_resources *cres, - struct fscache_operation *op); + int (*begin_operation)(struct netfs_cache_resources *cres); }; extern struct fscache_cookie fscache_fsdef_index; @@ -236,9 +169,6 @@ struct fscache_object { int n_children; /* number of child objects */ int n_ops; /* number of extant ops on object */ int n_obj_ops; /* number of object ops outstanding on object */ - int n_in_progress; /* number of ops in progress */ - int n_exclusive; /* number of exclusive ops queued or in progress */ - atomic_t n_reads; /* number of read ops in progress */ spinlock_t lock; /* state and operations lock */ unsigned long lookup_jif; /* time at which lookup started */ @@ -249,7 +179,6 @@ struct fscache_object { unsigned long flags; #define FSCACHE_OBJECT_LOCK 0 /* T if object is busy being processed */ -#define FSCACHE_OBJECT_PENDING_WRITE 1 /* T if object has pending write */ #define FSCACHE_OBJECT_WAITING 2 /* T if object is waiting on its parent */ #define FSCACHE_OBJECT_IS_LIVE 3 /* T if object is not withdrawn or relinquished */ #define FSCACHE_OBJECT_IS_LOOKED_UP 4 /* T if object has been looked up */ @@ -266,7 +195,6 @@ struct fscache_object { struct work_struct work; /* attention scheduling record */ struct list_head dependents; /* FIFO of dependent objects */ struct list_head dep_link; /* link in parent's dependents list */ - struct list_head pending_ops; /* unstarted operations on this object */ }; extern void fscache_object_init(struct fscache_object *, struct fscache_cookie *, diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h index 90d956ef1c6e..eac561d3ac51 100644 --- a/include/trace/events/fscache.h +++ b/include/trace/events/fscache.h @@ -33,24 +33,6 @@ enum fscache_cookie_trace { fscache_cookie_put_parent, }; -enum fscache_op_trace { - fscache_op_cancel, - fscache_op_cancel_all, - fscache_op_cancelled, - fscache_op_completed, - fscache_op_enqueue_async, - fscache_op_enqueue_mythread, - fscache_op_gc, - fscache_op_init, - fscache_op_put, - fscache_op_run, - fscache_op_signal, - fscache_op_submit, - fscache_op_submit_ex, - fscache_op_work, - fscache_op_trace__nr -}; - #endif /* @@ -69,22 +51,6 @@ enum fscache_op_trace { EM(fscache_cookie_put_object, "PUT obj") \ E_(fscache_cookie_put_parent, "PUT prn") -#define fscache_op_traces \ - EM(fscache_op_cancel, "Cancel1") \ - EM(fscache_op_cancel_all, "CancelA") \ - EM(fscache_op_cancelled, "Canclld") \ - EM(fscache_op_completed, "Complet") \ - EM(fscache_op_enqueue_async, "EnqAsyn") \ - EM(fscache_op_enqueue_mythread, "EnqMyTh") \ - EM(fscache_op_gc, "GC ") \ - EM(fscache_op_init, "Init ") \ - EM(fscache_op_put, "Put ") \ - EM(fscache_op_run, "Run ") \ - EM(fscache_op_signal, "Signal ") \ - EM(fscache_op_submit, "Submit ") \ - EM(fscache_op_submit_ex, "SubmitX") \ - E_(fscache_op_work, "Work ") - /* * Export enum symbols via userspace. */ @@ -299,29 +265,6 @@ TRACE_EVENT(fscache_osm, __entry->event_num) ); -TRACE_EVENT(fscache_op, - TP_PROTO(struct fscache_cookie *cookie, struct fscache_operation *op, - enum fscache_op_trace why), - - TP_ARGS(cookie, op, why), - - TP_STRUCT__entry( - __field(unsigned int, cookie ) - __field(unsigned int, op ) - __field(enum fscache_op_trace, why ) - ), - - TP_fast_assign( - __entry->cookie = cookie ? cookie->debug_id : 0; - __entry->op = op->debug_id; - __entry->why = why; - ), - - TP_printk("c=%08x op=%08x %s", - __entry->cookie, __entry->op, - __print_symbolic(__entry->why, fscache_op_traces)) - ); - #endif /* _TRACE_FSCACHE_H */ /* This part must be outside protection */ From patchwork Mon Oct 18 14:55:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566959 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 37D3FC433F5 for ; Mon, 18 Oct 2021 14:55:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 22D3361002 for ; Mon, 18 Oct 2021 14:55:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232713AbhJRO52 (ORCPT ); Mon, 18 Oct 2021 10:57:28 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:29557 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232483AbhJRO51 (ORCPT ); Mon, 18 Oct 2021 10:57:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568916; 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=o6nfl69kMmp16EeJpH9ZZQJrBuBcmVbCxcE6sm4V4PM=; b=RNIQhDI9HJ07tJOxRO4zqRT1HQXMookvuWMjN3uGtIEBUAw7tGEBG4AwCv+xX7GyxwoP+s b7zqRKcmlqVO65sOOxU1Cs9WdJV18WjjBGkf2zm6GwSlcLXVYFpDuLiZKTz+5YT0puZkwU zm3vzXR8a191OP+gO1DBhfVGCqS8gBM= 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-13-ThBoDkBXP1ukbU5pQpZ9Ww-1; Mon, 18 Oct 2021 10:55:14 -0400 X-MC-Unique: ThBoDkBXP1ukbU5pQpZ9Ww-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id AE7BE10A8E03; Mon, 18 Oct 2021 14:55:12 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4F1CC5F93B; Mon, 18 Oct 2021 14:55:09 +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 17/67] fscache: Rename fscache_cookie_{get,put,see}() From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:55:08 +0100 Message-ID: <163456890801.2614702.13204479150064313791.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Rename fscache_cookie_{get,put,see}() to fscache_{get,put,see}_cookie() and make them available to cache backend modules. Signed-off-by: David Howells --- fs/fscache/cookie.c | 14 ++++++++------ fs/fscache/internal.h | 6 +----- fs/fscache/netfs.c | 4 ++-- fs/fscache/object.c | 4 ++-- include/linux/fscache-cache.h | 6 ++++++ 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 62f3a4f75bad..0dc27f82e910 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -215,7 +215,7 @@ struct fscache_cookie *fscache_hash_cookie(struct fscache_cookie *candidate) } __set_bit(FSCACHE_COOKIE_ACQUIRED, &candidate->flags); - fscache_cookie_get(candidate->parent, fscache_cookie_get_acquire_parent); + fscache_get_cookie(candidate->parent, fscache_cookie_get_acquire_parent); atomic_inc(&candidate->parent->n_children); hlist_bl_add_head(&candidate->hash_link, h); hlist_bl_unlock(h); @@ -232,7 +232,7 @@ struct fscache_cookie *fscache_hash_cookie(struct fscache_cookie *candidate) return NULL; } - fscache_cookie_get(cursor, fscache_cookie_get_reacquire); + fscache_get_cookie(cursor, fscache_cookie_get_reacquire); hlist_bl_unlock(h); return cursor; } @@ -330,7 +330,7 @@ struct fscache_cookie *__fscache_acquire_cookie( set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); } else { atomic_dec(&parent->n_children); - fscache_cookie_put(cookie, + fscache_put_cookie(cookie, fscache_cookie_put_acquire_nobufs); fscache_stat(&fscache_n_acquires_nobufs); _leave(" = NULL"); @@ -793,7 +793,7 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, } /* Dispose of the netfs's link to the cookie */ - fscache_cookie_put(cookie, fscache_cookie_put_relinquish); + fscache_put_cookie(cookie, fscache_cookie_put_relinquish); _leave(""); } @@ -818,7 +818,7 @@ static void fscache_unhash_cookie(struct fscache_cookie *cookie) /* * Drop a reference to a cookie. */ -void fscache_cookie_put(struct fscache_cookie *cookie, +void fscache_put_cookie(struct fscache_cookie *cookie, enum fscache_cookie_trace where) { struct fscache_cookie *parent; @@ -844,11 +844,12 @@ void fscache_cookie_put(struct fscache_cookie *cookie, _leave(""); } +EXPORT_SYMBOL(fscache_put_cookie); /* * Get a reference to a cookie. */ -struct fscache_cookie *fscache_cookie_get(struct fscache_cookie *cookie, +struct fscache_cookie *fscache_get_cookie(struct fscache_cookie *cookie, enum fscache_cookie_trace where) { int ref; @@ -857,6 +858,7 @@ struct fscache_cookie *fscache_cookie_get(struct fscache_cookie *cookie, trace_fscache_cookie(cookie->debug_id, ref + 1, where); return cookie; } +EXPORT_SYMBOL(fscache_get_cookie); /* * Generate a list of extant cookies in /proc/fs/fscache/cookies diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index b8da3fe2d6f1..e78ca3151e41 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h @@ -72,12 +72,8 @@ extern struct fscache_cookie *fscache_alloc_cookie(struct fscache_cookie *, const void *, size_t, loff_t); extern struct fscache_cookie *fscache_hash_cookie(struct fscache_cookie *); -extern struct fscache_cookie *fscache_cookie_get(struct fscache_cookie *, - enum fscache_cookie_trace); -extern void fscache_cookie_put(struct fscache_cookie *, - enum fscache_cookie_trace); -static inline void fscache_cookie_see(struct fscache_cookie *cookie, +static inline void fscache_see_cookie(struct fscache_cookie *cookie, enum fscache_cookie_trace where) { trace_fscache_cookie(cookie->debug_id, refcount_read(&cookie->ref), diff --git a/fs/fscache/netfs.c b/fs/fscache/netfs.c index 8b0f303a7715..d746365f1daf 100644 --- a/fs/fscache/netfs.c +++ b/fs/fscache/netfs.c @@ -43,7 +43,7 @@ int __fscache_register_netfs(struct fscache_netfs *netfs) fscache_free_cookie(candidate); } - fscache_cookie_get(cookie->parent, fscache_cookie_get_register_netfs); + fscache_get_cookie(cookie->parent, fscache_cookie_get_register_netfs); atomic_inc(&cookie->parent->n_children); netfs->primary_index = cookie; @@ -54,7 +54,7 @@ int __fscache_register_netfs(struct fscache_netfs *netfs) return 0; already_registered: - fscache_cookie_put(candidate, fscache_cookie_put_dup_netfs); + fscache_put_cookie(candidate, fscache_cookie_put_dup_netfs); _leave(" = -EEXIST"); return -EEXIST; } diff --git a/fs/fscache/object.c b/fs/fscache/object.c index c7fbdcf3e987..761d6dc4aa0f 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c @@ -316,7 +316,7 @@ void fscache_object_init(struct fscache_object *object, object->events = 0; object->cache = cache; object->cookie = cookie; - fscache_cookie_get(cookie, fscache_cookie_get_attach_object); + fscache_get_cookie(cookie, fscache_cookie_get_attach_object); object->parent = NULL; #ifdef CONFIG_FSCACHE_OBJECT_LIST RB_CLEAR_NODE(&object->objlist_link); @@ -769,7 +769,7 @@ static void fscache_put_object(struct fscache_object *object, void fscache_object_destroy(struct fscache_object *object) { /* We can get rid of the cookie now */ - fscache_cookie_put(object->cookie, fscache_cookie_put_object); + fscache_put_cookie(object->cookie, fscache_cookie_put_object); object->cookie = NULL; } EXPORT_SYMBOL(fscache_object_destroy); diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index c5d454f340c6..0439dc3021c7 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -23,6 +23,7 @@ struct fscache_cache; struct fscache_cache_ops; struct fscache_object; +enum fscache_cookie_trace; enum fscache_obj_ref_trace { fscache_obj_get_add_to_deps, @@ -325,6 +326,11 @@ enum fscache_why_object_killed { extern void fscache_object_mark_killed(struct fscache_object *object, enum fscache_why_object_killed why); +extern struct fscache_cookie *fscache_get_cookie(struct fscache_cookie *cookie, + enum fscache_cookie_trace where); +extern void fscache_put_cookie(struct fscache_cookie *cookie, + enum fscache_cookie_trace where); + /* * Find the key on a cookie. */ From patchwork Mon Oct 18 14:55:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566961 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F3CC5C433F5 for ; Mon, 18 Oct 2021 14:55:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DA0D760E0B for ; Mon, 18 Oct 2021 14:55:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232860AbhJRO5t (ORCPT ); Mon, 18 Oct 2021 10:57:49 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:56121 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232622AbhJRO5p (ORCPT ); Mon, 18 Oct 2021 10:57:45 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568934; 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=JqgYGDuTnf8GeLzlHmEdTwiVOyQgHTjFebjq7V6hTO0=; b=XV6it9WD2jjRDEXefj8dlodKfMHbru6FuU0qU7Mhff4W6VmqWSQzBkmZE3oc9/jnMsAwHR 2GyHTs27nGdQtMjHrTrXEygkl/HGpA5hbdXA9vOroANFcUqBopHC2Elf8yaRYECibhTvE3 ox6nBWF3AwjJY5l3Sb6rPOPZwQerayU= 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-261-qD6k7E2OMbmQ2YKre93mdA-1; Mon, 18 Oct 2021 10:55:30 -0400 X-MC-Unique: qD6k7E2OMbmQ2YKre93mdA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 81BB8806688; Mon, 18 Oct 2021 14:55:28 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id DB2D56A25B; Mon, 18 Oct 2021 14:55:18 +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 18/67] cachefiles: Remove tree of active files and use S_CACHE_FILE inode flag From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:55:17 +0100 Message-ID: <163456891793.2614702.13065255063917891238.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Remove the tree of active dentries from the cachefiles_cache struct and instead set a flag, S_CACHE_FILE, on the backing inode to indicate that this file is in use by the kernel so as to ward off other kernel users. This simplifies the code a lot and also prevents two overlain caches from fighting with each other. Signed-off-by: David Howells --- fs/cachefiles/daemon.c | 4 fs/cachefiles/interface.c | 20 -- fs/cachefiles/internal.h | 10 - fs/cachefiles/namei.c | 378 +++++++------------------------------ include/trace/events/cachefiles.h | 54 ----- 5 files changed, 79 insertions(+), 387 deletions(-) diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c index 752c1e43416f..8a937d6d5e22 100644 --- a/fs/cachefiles/daemon.c +++ b/fs/cachefiles/daemon.c @@ -102,8 +102,6 @@ static int cachefiles_daemon_open(struct inode *inode, struct file *file) } mutex_init(&cache->daemon_mutex); - cache->active_nodes = RB_ROOT; - rwlock_init(&cache->active_lock); init_waitqueue_head(&cache->daemon_pollwq); /* set default caching limits @@ -138,8 +136,6 @@ static int cachefiles_daemon_release(struct inode *inode, struct file *file) cachefiles_daemon_unbind(cache); - ASSERT(!cache->active_nodes.rb_node); - /* clean up the control file interface */ cache->cachefilesd = NULL; file->private_data = NULL; diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index a84adf638737..bc28bb6c7ef5 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -36,7 +36,6 @@ static struct fscache_object *cachefiles_alloc_object( ASSERTCMP(object->backer, ==, NULL); - BUG_ON(test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)); atomic_set(&object->usage, 1); fscache_object_init(&object->fscache, cookie, &cache->cache); @@ -74,7 +73,6 @@ static struct fscache_object *cachefiles_alloc_object( nomem_key: kfree(buffer); nomem_buffer: - BUG_ON(test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)); kmem_cache_free(cachefiles_object_jar, object); fscache_object_destroyed(&cache->cache); nomem_object: @@ -190,8 +188,6 @@ static void cachefiles_drop_object(struct fscache_object *_object) struct cachefiles_object *object; struct cachefiles_cache *cache; const struct cred *saved_cred; - struct inode *inode; - blkcnt_t i_blocks = 0; ASSERT(_object); @@ -218,10 +214,6 @@ static void cachefiles_drop_object(struct fscache_object *_object) _object != cache->cache.fsdef ) { _debug("- retire object OBJ%x", object->fscache.debug_id); - inode = d_backing_inode(object->dentry); - if (inode) - i_blocks = inode->i_blocks; - cachefiles_begin_secure(cache, &saved_cred); cachefiles_delete_object(cache, object); cachefiles_end_secure(cache, saved_cred); @@ -231,14 +223,11 @@ static void cachefiles_drop_object(struct fscache_object *_object) if (object->backer != object->dentry) dput(object->backer); object->backer = NULL; - } - /* note that the object is now inactive */ - if (test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) - cachefiles_mark_object_inactive(cache, object, i_blocks); - - dput(object->dentry); - object->dentry = NULL; + cachefiles_unmark_inode_in_use(object, object->dentry); + dput(object->dentry); + object->dentry = NULL; + } _leave(""); } @@ -274,7 +263,6 @@ void cachefiles_put_object(struct fscache_object *_object, if (u == 0) { _debug("- kill object OBJ%x", object->fscache.debug_id); - ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)); ASSERTCMP(object->fscache.parent, ==, NULL); ASSERTCMP(object->backer, ==, NULL); ASSERTCMP(object->dentry, ==, NULL); diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index fbe43e1aa517..0515add2b7e8 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -38,12 +38,9 @@ struct cachefiles_object { struct dentry *dentry; /* the file/dir representing this object */ struct dentry *backer; /* backing file */ loff_t i_size; /* object size */ - unsigned long flags; -#define CACHEFILES_OBJECT_ACTIVE 0 /* T if marked active */ atomic_t usage; /* object usage count */ uint8_t type; /* object type */ uint8_t new; /* T if object new */ - struct rb_node active_node; /* link in active tree (dentry is key) */ }; extern struct kmem_cache *cachefiles_object_jar; @@ -59,8 +56,6 @@ struct cachefiles_cache { const struct cred *cache_cred; /* security override for accessing cache */ struct mutex daemon_mutex; /* command serialisation mutex */ wait_queue_head_t daemon_pollwq; /* poll waitqueue for daemon */ - struct rb_root active_nodes; /* active nodes (can't be culled) */ - rwlock_t active_lock; /* lock for active_nodes */ atomic_t gravecounter; /* graveyard uniquifier */ atomic_t f_released; /* number of objects released lately */ atomic_long_t b_released; /* number of blocks released lately */ @@ -129,9 +124,8 @@ extern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type); /* * namei.c */ -extern void cachefiles_mark_object_inactive(struct cachefiles_cache *cache, - struct cachefiles_object *object, - blkcnt_t i_blocks); +extern void cachefiles_unmark_inode_in_use(struct cachefiles_object *object, + struct dentry *dentry); extern int cachefiles_delete_object(struct cachefiles_cache *cache, struct cachefiles_object *object); extern int cachefiles_walk_to_object(struct cachefiles_object *parent, diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 548aac544293..4bd31be3be30 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -21,251 +21,51 @@ #define CACHEFILES_KEYBUF_SIZE 512 /* - * dump debugging info about an object + * Mark the backing file as being a cache file if it's not already in use so. */ -static noinline -void __cachefiles_printk_object(struct cachefiles_object *object, - const char *prefix) +static bool cachefiles_mark_inode_in_use(struct cachefiles_object *object, + struct dentry *dentry) { - struct fscache_cookie *cookie; - const u8 *k; - unsigned loop; - - pr_err("%sobject: OBJ%x\n", prefix, object->fscache.debug_id); - pr_err("%sobjstate=%s fl=%lx wbusy=%x ev=%lx[%lx]\n", - prefix, object->fscache.state->name, - object->fscache.flags, work_busy(&object->fscache.work), - object->fscache.events, object->fscache.event_mask); - pr_err("%sops=%u\n", - prefix, object->fscache.n_ops); - pr_err("%sparent=%x\n", - prefix, object->fscache.parent ? object->fscache.parent->debug_id : 0); - - spin_lock(&object->fscache.lock); - cookie = object->fscache.cookie; - if (cookie) { - pr_err("%scookie=%x [pr=%x fl=%lx]\n", - prefix, - cookie->debug_id, - cookie->parent ? cookie->parent->debug_id : 0, - cookie->flags); - pr_err("%skey=[%u] '", prefix, cookie->key_len); - k = (cookie->key_len <= sizeof(cookie->inline_key)) ? - cookie->inline_key : cookie->key; - for (loop = 0; loop < cookie->key_len; loop++) - pr_cont("%02x", k[loop]); - pr_cont("'\n"); - } else { - pr_err("%scookie=NULL\n", prefix); - } - spin_unlock(&object->fscache.lock); -} - -/* - * dump debugging info about a pair of objects - */ -static noinline void cachefiles_printk_object(struct cachefiles_object *object, - struct cachefiles_object *xobject) -{ - if (object) - __cachefiles_printk_object(object, ""); - if (xobject) - __cachefiles_printk_object(xobject, "x"); -} - -/* - * mark the owner of a dentry, if there is one, to indicate that that dentry - * has been preemptively deleted - * - the caller must hold the i_mutex on the dentry's parent as required to - * call vfs_unlink(), vfs_rmdir() or vfs_rename() - */ -static void cachefiles_mark_object_buried(struct cachefiles_cache *cache, - struct dentry *dentry, - enum fscache_why_object_killed why) -{ - struct cachefiles_object *object; - struct rb_node *p; - - _enter(",'%pd'", dentry); - - write_lock(&cache->active_lock); - - p = cache->active_nodes.rb_node; - while (p) { - object = rb_entry(p, struct cachefiles_object, active_node); - if (object->dentry > dentry) - p = p->rb_left; - else if (object->dentry < dentry) - p = p->rb_right; - else - goto found_dentry; - } - - write_unlock(&cache->active_lock); - trace_cachefiles_mark_buried(NULL, dentry, why); - _leave(" [no owner]"); - return; + struct inode *inode = d_backing_inode(dentry); + bool can_use = false; - /* found the dentry for */ -found_dentry: - kdebug("preemptive burial: OBJ%x [%s] %pd", - object->fscache.debug_id, - object->fscache.state->name, - dentry); + _enter(",%x", object->fscache.debug_id); - trace_cachefiles_mark_buried(object, dentry, why); + inode_lock(inode); - if (fscache_object_is_live(&object->fscache)) { - pr_err("\n"); - pr_err("Error: Can't preemptively bury live object\n"); - cachefiles_printk_object(object, NULL); + if (!(inode->i_flags & S_KERNEL_FILE)) { + inode->i_flags |= S_KERNEL_FILE; + trace_cachefiles_mark_active(object, dentry); + can_use = true; } else { - if (why != FSCACHE_OBJECT_IS_STALE) - fscache_object_mark_killed(&object->fscache, why); + pr_notice("cachefiles: Inode already in use: %pd\n", dentry); } - write_unlock(&cache->active_lock); - _leave(" [owner marked]"); + inode_unlock(inode); + return can_use; } /* - * record the fact that an object is now active + * Unmark a backing inode. */ -static int cachefiles_mark_object_active(struct cachefiles_cache *cache, - struct cachefiles_object *object) +void cachefiles_unmark_inode_in_use(struct cachefiles_object *object, + struct dentry *dentry) { - struct cachefiles_object *xobject; - struct rb_node **_p, *_parent = NULL; - struct dentry *dentry; - - _enter(",%x", object->fscache.debug_id); - -try_again: - write_lock(&cache->active_lock); - - dentry = object->dentry; - trace_cachefiles_mark_active(object, dentry); - - if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) { - pr_err("Error: Object already active\n"); - cachefiles_printk_object(object, NULL); - BUG(); - } - - _p = &cache->active_nodes.rb_node; - while (*_p) { - _parent = *_p; - xobject = rb_entry(_parent, - struct cachefiles_object, active_node); - - ASSERT(xobject != object); - - if (xobject->dentry > dentry) - _p = &(*_p)->rb_left; - else if (xobject->dentry < dentry) - _p = &(*_p)->rb_right; - else - goto wait_for_old_object; - } - - rb_link_node(&object->active_node, _parent, _p); - rb_insert_color(&object->active_node, &cache->active_nodes); - - write_unlock(&cache->active_lock); - _leave(" = 0"); - return 0; - - /* an old object from a previous incarnation is hogging the slot - we - * need to wait for it to be destroyed */ -wait_for_old_object: - trace_cachefiles_wait_active(object, dentry, xobject); - clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); - - if (fscache_object_is_live(&xobject->fscache)) { - pr_err("\n"); - pr_err("Error: Unexpected object collision\n"); - cachefiles_printk_object(object, xobject); - } - atomic_inc(&xobject->usage); - write_unlock(&cache->active_lock); - - if (test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) { - wait_queue_head_t *wq; - - signed long timeout = 60 * HZ; - wait_queue_entry_t wait; - bool requeue; - - /* if the object we're waiting for is queued for processing, - * then just put ourselves on the queue behind it */ - if (work_pending(&xobject->fscache.work)) { - _debug("queue OBJ%x behind OBJ%x immediately", - object->fscache.debug_id, - xobject->fscache.debug_id); - goto requeue; - } - - /* otherwise we sleep until either the object we're waiting for - * is done, or the fscache_object is congested */ - wq = bit_waitqueue(&xobject->flags, CACHEFILES_OBJECT_ACTIVE); - init_wait(&wait); - requeue = false; - do { - prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); - if (!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) - break; - - requeue = fscache_object_sleep_till_congested(&timeout); - } while (timeout > 0 && !requeue); - finish_wait(wq, &wait); - - if (requeue && - test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) { - _debug("queue OBJ%x behind OBJ%x after wait", - object->fscache.debug_id, - xobject->fscache.debug_id); - goto requeue; - } - - if (timeout <= 0) { - pr_err("\n"); - pr_err("Error: Overlong wait for old active object to go away\n"); - cachefiles_printk_object(object, xobject); - goto requeue; - } - } - - ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)); - - cache->cache.ops->put_object(&xobject->fscache, - (enum fscache_obj_ref_trace)cachefiles_obj_put_wait_retry); - goto try_again; + struct inode *inode = d_backing_inode(dentry); -requeue: - cache->cache.ops->put_object(&xobject->fscache, - (enum fscache_obj_ref_trace)cachefiles_obj_put_wait_timeo); - _leave(" = -ETIMEDOUT"); - return -ETIMEDOUT; + inode_lock(inode); + inode->i_flags &= ~S_KERNEL_FILE; + inode_unlock(inode); + trace_cachefiles_mark_inactive(object, dentry, inode); } /* * Mark an object as being inactive. */ -void cachefiles_mark_object_inactive(struct cachefiles_cache *cache, - struct cachefiles_object *object, - blkcnt_t i_blocks) +static void cachefiles_mark_object_inactive(struct cachefiles_cache *cache, + struct cachefiles_object *object) { - struct dentry *dentry = object->dentry; - struct inode *inode = d_backing_inode(dentry); - - trace_cachefiles_mark_inactive(object, dentry, inode); - - write_lock(&cache->active_lock); - rb_erase(&object->active_node, &cache->active_nodes); - clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); - write_unlock(&cache->active_lock); - - wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE); + blkcnt_t i_blocks = d_backing_inode(object->dentry)->i_blocks; /* This object can now be culled, so we need to let the daemon know * that there is something it can remove if it needs to. @@ -286,7 +86,6 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, struct cachefiles_object *object, struct dentry *dir, struct dentry *rep, - bool preemptive, enum fscache_why_object_killed why) { struct dentry *grave, *trap; @@ -307,11 +106,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, cachefiles_io_error(cache, "Unlink security error"); } else { trace_cachefiles_unlink(object, rep, why); - ret = vfs_unlink(&init_user_ns, d_inode(dir), rep, - NULL); - - if (preemptive) - cachefiles_mark_object_buried(cache, rep, why); + ret = vfs_unlink(&init_user_ns, d_inode(dir), rep, NULL); } inode_unlock(d_inode(dir)); @@ -372,8 +167,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, return -ENOMEM; } - cachefiles_io_error(cache, "Lookup error %ld", - PTR_ERR(grave)); + cachefiles_io_error(cache, "Lookup error %ld", PTR_ERR(grave)); return -EIO; } @@ -422,9 +216,6 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, if (ret != 0 && ret != -ENOMEM) cachefiles_io_error(cache, "Rename failed with error %d", ret); - - if (preemptive) - cachefiles_mark_object_buried(cache, rep, why); } unlock_rename(cache->graveyard, dir); @@ -452,26 +243,18 @@ int cachefiles_delete_object(struct cachefiles_cache *cache, inode_lock_nested(d_inode(dir), I_MUTEX_PARENT); - if (test_bit(FSCACHE_OBJECT_KILLED_BY_CACHE, &object->fscache.flags)) { - /* object allocation for the same key preemptively deleted this - * object's file so that it could create its own file */ - _debug("object preemptively buried"); + /* We need to check that our parent is _still_ our parent - it may have + * been renamed. + */ + if (dir == object->dentry->d_parent) { + ret = cachefiles_bury_object(cache, object, dir, object->dentry, + FSCACHE_OBJECT_WAS_RETIRED); + } else { + /* It got moved, presumably by cachefilesd culling it, so it's + * no longer in the key path and we can ignore it. + */ inode_unlock(d_inode(dir)); ret = 0; - } else { - /* we need to check that our parent is _still_ our parent - it - * may have been renamed */ - if (dir == object->dentry->d_parent) { - ret = cachefiles_bury_object(cache, object, dir, - object->dentry, false, - FSCACHE_OBJECT_WAS_RETIRED); - } else { - /* it got moved, presumably by cachefilesd culling it, - * so it's no longer in the key path and we can ignore - * it */ - inode_unlock(d_inode(dir)); - ret = 0; - } } dput(dir); @@ -492,6 +275,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, struct inode *inode; struct path path; const char *name; + bool marked = false; int ret, nlen; _enter("OBJ%x{%pd},OBJ%x,%s,", @@ -532,6 +316,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, next = lookup_one_len(name, dir, nlen); if (IS_ERR(next)) { trace_cachefiles_lookup(object, next, NULL); + ret = PTR_ERR(next); goto lookup_error; } @@ -628,6 +413,13 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, /* we've found the object we were looking for */ object->dentry = next; + /* note that we're now using this object */ + if (!cachefiles_mark_inode_in_use(object, object->dentry)) { + ret = -EBUSY; + goto check_error_unlock; + } + marked = true; + /* if we've found that the terminal object exists, then we need to * check its attributes and delete it if it's out of date */ if (!object->new) { @@ -640,13 +432,12 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, object->dentry = NULL; ret = cachefiles_bury_object(cache, object, dir, next, - true, FSCACHE_OBJECT_IS_STALE); dput(next); next = NULL; if (ret < 0) - goto delete_error; + goto error_out2; _debug("redo lookup"); fscache_object_retrying_stale(&object->fscache); @@ -654,16 +445,10 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, } } - /* note that we're now using this object */ - ret = cachefiles_mark_object_active(cache, object); - inode_unlock(d_inode(dir)); dput(dir); dir = NULL; - if (ret == -ETIMEDOUT) - goto mark_active_timed_out; - _debug("=== OBTAINED_OBJECT ==="); if (object->new) { @@ -712,26 +497,19 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, cachefiles_io_error(cache, "Create/mkdir failed"); goto error; -mark_active_timed_out: - _debug("mark active timed out"); - goto release_dentry; - +check_error_unlock: + inode_unlock(d_inode(dir)); + dput(dir); check_error: - _debug("check error %d", ret); - cachefiles_mark_object_inactive( - cache, object, d_backing_inode(object->dentry)->i_blocks); -release_dentry: + if (marked) + cachefiles_unmark_inode_in_use(object, object->dentry); + cachefiles_mark_object_inactive(cache, object); dput(object->dentry); object->dentry = NULL; goto error_out; -delete_error: - _debug("delete error %d", ret); - goto error_out2; - lookup_error: - _debug("lookup error %ld", PTR_ERR(next)); - ret = PTR_ERR(next); + _debug("lookup error %d", ret); if (ret == -EIO) cachefiles_io_error(cache, "Lookup failed"); next = NULL; @@ -856,8 +634,6 @@ static struct dentry *cachefiles_check_active(struct cachefiles_cache *cache, struct dentry *dir, char *filename) { - struct cachefiles_object *object; - struct rb_node *_n; struct dentry *victim; int ret; @@ -884,34 +660,9 @@ static struct dentry *cachefiles_check_active(struct cachefiles_cache *cache, return ERR_PTR(-ENOENT); } - /* check to see if we're using this object */ - read_lock(&cache->active_lock); - - _n = cache->active_nodes.rb_node; - - while (_n) { - object = rb_entry(_n, struct cachefiles_object, active_node); - - if (object->dentry > victim) - _n = _n->rb_left; - else if (object->dentry < victim) - _n = _n->rb_right; - else - goto object_in_use; - } - - read_unlock(&cache->active_lock); - //_leave(" = %pd", victim); return victim; -object_in_use: - read_unlock(&cache->active_lock); - inode_unlock(d_inode(dir)); - dput(victim); - //_leave(" = -EBUSY [in use]"); - return ERR_PTR(-EBUSY); - lookup_error: inode_unlock(d_inode(dir)); ret = PTR_ERR(victim); @@ -940,6 +691,7 @@ int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir, char *filename) { struct dentry *victim; + struct inode *inode; int ret; _enter(",%pd/,%s", dir, filename); @@ -948,6 +700,19 @@ int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir, if (IS_ERR(victim)) return PTR_ERR(victim); + /* check to see if someone is using this object */ + inode = d_inode(victim); + inode_lock(inode); + if (inode->i_flags & S_KERNEL_FILE) { + ret = -EBUSY; + } else { + inode->i_flags |= S_KERNEL_FILE; + ret = 0; + } + inode_unlock(inode); + if (ret < 0) + goto error_unlock; + _debug("victim -> %pd %s", victim, d_backing_inode(victim) ? "positive" : "negative"); @@ -963,7 +728,7 @@ int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir, /* actually remove the victim (drops the dir mutex) */ _debug("bury"); - ret = cachefiles_bury_object(cache, NULL, dir, victim, false, + ret = cachefiles_bury_object(cache, NULL, dir, victim, FSCACHE_OBJECT_WAS_CULLED); if (ret < 0) goto error; @@ -1000,6 +765,7 @@ int cachefiles_check_in_use(struct cachefiles_cache *cache, struct dentry *dir, char *filename) { struct dentry *victim; + int ret = 0; //_enter(",%pd/,%s", // dir, filename); @@ -1009,7 +775,9 @@ int cachefiles_check_in_use(struct cachefiles_cache *cache, struct dentry *dir, return PTR_ERR(victim); inode_unlock(d_inode(dir)); + if (d_inode(victim)->i_flags & S_KERNEL_FILE) + ret = -EBUSY; dput(victim); //_leave(" = 0"); - return 0; + return ret; } diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h index 920b6a303d60..57d811718953 100644 --- a/include/trace/events/cachefiles.h +++ b/include/trace/events/cachefiles.h @@ -237,35 +237,6 @@ TRACE_EVENT(cachefiles_mark_active, __entry->obj, __entry->de) ); -TRACE_EVENT(cachefiles_wait_active, - TP_PROTO(struct cachefiles_object *obj, - struct dentry *de, - struct cachefiles_object *xobj), - - TP_ARGS(obj, de, xobj), - - /* Note that obj may be NULL */ - TP_STRUCT__entry( - __field(unsigned int, obj ) - __field(unsigned int, xobj ) - __field(struct dentry *, de ) - __field(u16, flags ) - __field(u16, fsc_flags ) - ), - - TP_fast_assign( - __entry->obj = obj->fscache.debug_id; - __entry->de = de; - __entry->xobj = xobj->fscache.debug_id; - __entry->flags = xobj->flags; - __entry->fsc_flags = xobj->fscache.flags; - ), - - TP_printk("o=%08x d=%p wo=%08x wf=%x wff=%x", - __entry->obj, __entry->de, __entry->xobj, - __entry->flags, __entry->fsc_flags) - ); - TRACE_EVENT(cachefiles_mark_inactive, TP_PROTO(struct cachefiles_object *obj, struct dentry *de, @@ -290,31 +261,6 @@ TRACE_EVENT(cachefiles_mark_inactive, __entry->obj, __entry->de, __entry->inode) ); -TRACE_EVENT(cachefiles_mark_buried, - TP_PROTO(struct cachefiles_object *obj, - struct dentry *de, - enum fscache_why_object_killed why), - - TP_ARGS(obj, de, why), - - /* Note that obj may be NULL */ - TP_STRUCT__entry( - __field(unsigned int, obj ) - __field(struct dentry *, de ) - __field(enum fscache_why_object_killed, why ) - ), - - TP_fast_assign( - __entry->obj = obj ? obj->fscache.debug_id : UINT_MAX; - __entry->de = de; - __entry->why = why; - ), - - TP_printk("o=%08x d=%p w=%s", - __entry->obj, __entry->de, - __print_symbolic(__entry->why, cachefiles_obj_kill_traces)) - ); - #endif /* _TRACE_CACHEFILES_H */ /* This part must be outside protection */ From patchwork Mon Oct 18 14:55:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566963 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8ED3EC433EF for ; Mon, 18 Oct 2021 14:55:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 71B3E61002 for ; Mon, 18 Oct 2021 14:55:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232960AbhJRO6A (ORCPT ); Mon, 18 Oct 2021 10:58:00 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:58541 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232925AbhJRO5z (ORCPT ); Mon, 18 Oct 2021 10:57:55 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568944; 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=vWJr+o5XEJdul/wxaFN3vlOPvUxwAzrbc+cKwab9/Mo=; b=hP/Sy2ly7sANAMeH0NBpVD55+EXzw4RS9uBraZu1lDdP7WfTGogLzARiBXH0aogyR0s3Gw QG3DuO3agj7AkXYz+A2Ds1Pt28NpNPA4f0refctCJhnp9w07fatwqrnEngNrq4kuW7d398 x47UNz3dyb3UesgJuKftvYc+h8wMU8U= 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-155-Fg7w_fGOOiS33-k-QeKtrg-1; Mon, 18 Oct 2021 10:55:42 -0400 X-MC-Unique: Fg7w_fGOOiS33-k-QeKtrg-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7541E806668; Mon, 18 Oct 2021 14:55:40 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 97EE85D6D7; Mon, 18 Oct 2021 14:55:34 +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 19/67] cachefiles: Don't set an xattr on the root of the cache From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:55:33 +0100 Message-ID: <163456893374.2614702.11747731163000539462.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org cachefiles_check_object_type() sets an xattr on the root of the cache, but it's pointless because it never conveys any useful information, so don't do that. Signed-off-by: David Howells --- fs/cachefiles/bind.c | 4 -- fs/cachefiles/internal.h | 1 - fs/cachefiles/xattr.c | 76 ---------------------------------------------- 3 files changed, 81 deletions(-) diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c index d463d89f5db8..6720c07f3d85 100644 --- a/fs/cachefiles/bind.c +++ b/fs/cachefiles/bind.c @@ -199,10 +199,6 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) fsdef->dentry = cachedir; fsdef->fscache.cookie = NULL; - ret = cachefiles_check_object_type(fsdef); - if (ret < 0) - goto error_unsupported; - /* get the graveyard directory */ graveyard = cachefiles_get_directory(cache, root, "graveyard"); if (IS_ERR(graveyard)) { diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index 0515add2b7e8..6464a6821bfb 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -169,7 +169,6 @@ static inline void cachefiles_end_secure(struct cachefiles_cache *cache, /* * xattr.c */ -extern int cachefiles_check_object_type(struct cachefiles_object *object); extern int cachefiles_set_object_xattr(struct cachefiles_object *object, unsigned int xattr_flags); extern int cachefiles_check_auxdata(struct cachefiles_object *object); diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c index bcc4a2dfe1e8..8b9f30f9ce21 100644 --- a/fs/cachefiles/xattr.c +++ b/fs/cachefiles/xattr.c @@ -23,82 +23,6 @@ struct cachefiles_xattr { static const char cachefiles_xattr_cache[] = XATTR_USER_PREFIX "CacheFiles.cache"; -/* - * check the type label on an object - * - done using xattrs - */ -int cachefiles_check_object_type(struct cachefiles_object *object) -{ - struct dentry *dentry = object->dentry; - char type[3], xtype[3]; - int ret; - - ASSERT(dentry); - ASSERT(d_backing_inode(dentry)); - - if (!object->fscache.cookie) - strcpy(type, "C3"); - else - snprintf(type, 3, "%02x", object->fscache.cookie->type); - - _enter("%x{%s}", object->fscache.debug_id, type); - - /* attempt to install a type label directly */ - ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache, type, - 2, XATTR_CREATE); - if (ret == 0) { - _debug("SET"); /* we succeeded */ - goto error; - } - - if (ret != -EEXIST) { - pr_err("Can't set xattr on %pd [%lu] (err %d)\n", - dentry, d_backing_inode(dentry)->i_ino, - -ret); - goto error; - } - - /* read the current type label */ - ret = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, xtype, - 3); - if (ret < 0) { - if (ret == -ERANGE) - goto bad_type_length; - - pr_err("Can't read xattr on %pd [%lu] (err %d)\n", - dentry, d_backing_inode(dentry)->i_ino, - -ret); - goto error; - } - - /* check the type is what we're expecting */ - if (ret != 2) - goto bad_type_length; - - if (xtype[0] != type[0] || xtype[1] != type[1]) - goto bad_type; - - ret = 0; - -error: - _leave(" = %d", ret); - return ret; - -bad_type_length: - pr_err("Cache object %lu type xattr length incorrect\n", - d_backing_inode(dentry)->i_ino); - ret = -EIO; - goto error; - -bad_type: - xtype[2] = 0; - pr_err("Cache object %pd [%lu] type %s not %s\n", - dentry, d_backing_inode(dentry)->i_ino, - xtype, type); - ret = -EIO; - goto error; -} - /* * set the state xattr on a cache file */ From patchwork Mon Oct 18 14:55:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566965 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9BB24C433EF for ; Mon, 18 Oct 2021 14:56:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7A32761002 for ; Mon, 18 Oct 2021 14:56:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232636AbhJRO6T (ORCPT ); Mon, 18 Oct 2021 10:58:19 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:24690 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232983AbhJRO6N (ORCPT ); Mon, 18 Oct 2021 10:58:13 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568961; 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=fXsphGfG84x/qU401g1UBOIjGC8E9APA4ba1XbVairo=; b=JNiHB9hVH+zW9sJPUSehxcOei+lH8tmB72SW9vyrLvSN+eKxyx3LpnWYXToLt5VRpcJxpG TXz55pOcb3o8XO4vWY/IpATCFzHHjplxweRyswj6pZN9Vt+yESUIAI+GRBFdWDM5aSwyN3 MONevtZR/kFiWjzya6epHpP/K/Pj2aI= 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-119-TDMc0zyxOESI0WALvBsKvQ-1; Mon, 18 Oct 2021 10:55:58 -0400 X-MC-Unique: TDMc0zyxOESI0WALvBsKvQ-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1ED1A1006AB3; Mon, 18 Oct 2021 14:55:56 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7A7005DF21; Mon, 18 Oct 2021 14:55:46 +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 20/67] cachefiles: Remove some redundant checks on unsigned values From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:55:45 +0100 Message-ID: <163456894569.2614702.11582768897048471845.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Remove some redundant checks for unsigned values being >= 0. Signed-off-by: David Howells --- fs/cachefiles/bind.c | 6 ++---- fs/cachefiles/daemon.c | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c index 6720c07f3d85..0bc748081f59 100644 --- a/fs/cachefiles/bind.c +++ b/fs/cachefiles/bind.c @@ -36,13 +36,11 @@ int cachefiles_daemon_bind(struct cachefiles_cache *cache, char *args) args); /* start by checking things over */ - ASSERT(cache->fstop_percent >= 0 && - cache->fstop_percent < cache->fcull_percent && + ASSERT(cache->fstop_percent < cache->fcull_percent && cache->fcull_percent < cache->frun_percent && cache->frun_percent < 100); - ASSERT(cache->bstop_percent >= 0 && - cache->bstop_percent < cache->bcull_percent && + ASSERT(cache->bstop_percent < cache->bcull_percent && cache->bcull_percent < cache->brun_percent && cache->brun_percent < 100); diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c index 8a937d6d5e22..e8ab3ab57147 100644 --- a/fs/cachefiles/daemon.c +++ b/fs/cachefiles/daemon.c @@ -221,7 +221,7 @@ static ssize_t cachefiles_daemon_write(struct file *file, if (test_bit(CACHEFILES_DEAD, &cache->flags)) return -EIO; - if (datalen < 0 || datalen > PAGE_SIZE - 1) + if (datalen > PAGE_SIZE - 1) return -EOPNOTSUPP; /* drag the command string into the kernel so we can parse it */ @@ -378,7 +378,7 @@ static int cachefiles_daemon_fstop(struct cachefiles_cache *cache, char *args) if (args[0] != '%' || args[1] != '\0') return -EINVAL; - if (fstop < 0 || fstop >= cache->fcull_percent) + if (fstop >= cache->fcull_percent) return cachefiles_daemon_range_error(cache, args); cache->fstop_percent = fstop; @@ -450,7 +450,7 @@ static int cachefiles_daemon_bstop(struct cachefiles_cache *cache, char *args) if (args[0] != '%' || args[1] != '\0') return -EINVAL; - if (bstop < 0 || bstop >= cache->bcull_percent) + if (bstop >= cache->bcull_percent) return cachefiles_daemon_range_error(cache, args); cache->bstop_percent = bstop; From patchwork Mon Oct 18 14:56:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566967 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6F1CBC433EF for ; Mon, 18 Oct 2021 14:56:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5312560E0B for ; Mon, 18 Oct 2021 14:56:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232631AbhJRO62 (ORCPT ); Mon, 18 Oct 2021 10:58:28 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:38129 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232938AbhJRO61 (ORCPT ); Mon, 18 Oct 2021 10:58:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634568976; 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=SB5Ii7xfPTM4p2eEWvijuPkly8hQ6NZB0idEsu0sEO8=; b=cPJmdwkBsy33nEuPfLa0HSBQEldRf1E1Qccx4Pe6hdxw0ksT027zt2wPyLOjYSzNCbm40e OzRPdErvPnKpZvaqZYWHyaEBqINDNZh0yDsO8HwNS7HUfPsNSmePuTYROhrqU3kcENLJUh IOmeCh+hj/aq1Wy8iuWfNtscMbKnwfA= 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-135-WzAoXm61Pnm4_oBBDiJ4qA-1; Mon, 18 Oct 2021 10:56:12 -0400 X-MC-Unique: WzAoXm61Pnm4_oBBDiJ4qA-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 A73701006AA2; Mon, 18 Oct 2021 14:56:10 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 388E85BB12; Mon, 18 Oct 2021 14:56:02 +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 21/67] cachefiles: Prevent inode from going away when burying a dentry From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:56:01 +0100 Message-ID: <163456896131.2614702.10188463290568833365.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org When deleting a file, we want to make sure that the inode doesn't get detached from it (leading to ->d_inode being cleared) as we may still want to touch the inode afterwards (we want to clear the belongs-to-kernel flag and we may have the dentry referred to by a file struct). Do this by getting an extra ref on the dentry around the vfs_unlink() call so that d_delete() doesn't see the refcount == 1. Signed-off-by: David Howells --- fs/cachefiles/namei.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 4bd31be3be30..04c767624e3d 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -106,7 +106,9 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, cachefiles_io_error(cache, "Unlink security error"); } else { trace_cachefiles_unlink(object, rep, why); + dget(rep); ret = vfs_unlink(&init_user_ns, d_inode(dir), rep, NULL); + dput(rep); } inode_unlock(d_inode(dir)); From patchwork Mon Oct 18 14:56:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566969 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 429C3C433EF for ; Mon, 18 Oct 2021 14:56:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 25E6D60E0B for ; Mon, 18 Oct 2021 14:56:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232371AbhJRO67 (ORCPT ); Mon, 18 Oct 2021 10:58:59 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:49720 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232464AbhJRO66 (ORCPT ); Mon, 18 Oct 2021 10:58:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569007; 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=3wB94hRxoMsUUmAQY8enc2qloPgpN4ISb3zVuHp6Vs0=; b=I+EZxVusEK6Qdqkd2NG/ufui0jnm/drf/bFItFQQuLlmsunBV7E1Mtmde4D8hCSX8GU7Lm AigldF6qbh3dv7zHN0Mh/DArVhF7nDiFZfn4EyCzO+Qv7ntVr59Toy8CvtFFo6bRC+avdx SB09B0581uLj22RALGp4MweGvZEjpq4= 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-199-xpI-AF4UMTCEDfiNkQix0Q-1; Mon, 18 Oct 2021 10:56:42 -0400 X-MC-Unique: xpI-AF4UMTCEDfiNkQix0Q-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 80C4779EDC; Mon, 18 Oct 2021 14:56:40 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id C7B7078B20; Mon, 18 Oct 2021 14:56:16 +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 22/67] cachefiles: Simplify the pathwalk and save the filename for an object From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:56:15 +0100 Message-ID: <163456897591.2614702.16753183518371622819.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org In the future, I want to move to an invalidation model where invalidation on a live cache object is achieved by opening a tmpfile, changing the pointer to cut over I/O and then linking it into place in the parent directory later rather than by truncating the file on the spot. To this make this work, however, I need the filename to pass to vfs_link()[*]. I can either copy it from the outgoing dentry (which I then need to unlink) or [*] Unless I can pass a flag to vfs_link() to tell it to replace the file at that dentry. The filename concocted by cook key is a path relative to the parent index, and may contain multiple components if the object key gets rendered to a size larger than NAME_MAX. However, apart from one exception, none of the filesystems have a key that's anywhere near that large - even NFS filehandles top out at about 128 bytes, which encoded in base64 increase by a quarter to 192 plus a few extra chars of markup. The exception is the AFS cell name, which is a domain name and can be up to 255 chars in size. Restricting this allows simplification of the pathwalk. So, to this end, the following changes are made: (1) Restrict keys to those that can be rendered in NAME_MAX size. (2) Simplify the filename generation to store the fanout selection separately from the key filename and put the key filename alone into the filename string. As before, if suitable, the key is rendered directly, prefixed by I/D/S and an encoded length. Otherwise, it has the length prepended and the whole lot is rendered into base64 and then prefixed with J/E/T. (The lengths are at least partially redundant, but a later patch is going to fully overhaul the encodings anyway). Allocating a temporary buffer to expand the key is only necessary when rendering to base64. (3) cachefiles_cook_key() now returns a bool and attaches the name string and key hash (fanout selection) directly to the object. The name is freed when the object is freed. (4) Simplify the pathwalk to assume there are exactly two steps in looking up an object: one fanout dir and then one directory or file representing the object itself. The fanout filename is rendered on the fly. (5) Assume that data objects are always going to be files and not a directory with further structure therein. Signed-off-by: David Howells --- fs/cachefiles/bind.c | 4 fs/cachefiles/interface.c | 41 +--- fs/cachefiles/internal.h | 17 +- fs/cachefiles/key.c | 179 +++++++--------- fs/cachefiles/namei.c | 403 +++++++++++++++++-------------------- include/trace/events/cachefiles.h | 22 -- 6 files changed, 279 insertions(+), 387 deletions(-) diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c index 0bc748081f59..fbc8577477c1 100644 --- a/fs/cachefiles/bind.c +++ b/fs/cachefiles/bind.c @@ -188,7 +188,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) (unsigned long long) cache->bstop); /* get the cache directory and check its type */ - cachedir = cachefiles_get_directory(cache, root, "cache"); + cachedir = cachefiles_get_directory(cache, root, "cache", NULL); if (IS_ERR(cachedir)) { ret = PTR_ERR(cachedir); goto error_unsupported; @@ -198,7 +198,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) fsdef->fscache.cookie = NULL; /* get the graveyard directory */ - graveyard = cachefiles_get_directory(cache, root, "graveyard"); + graveyard = cachefiles_get_directory(cache, root, "graveyard", NULL); if (IS_ERR(graveyard)) { ret = PTR_ERR(graveyard); goto error_unsupported; diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index bc28bb6c7ef5..2083aca6bd0c 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -21,9 +21,6 @@ static struct fscache_object *cachefiles_alloc_object( { struct cachefiles_object *object; struct cachefiles_cache *cache; - unsigned keylen; - void *buffer, *p; - char *key; cache = container_of(_cache, struct cachefiles_cache, cache); @@ -42,37 +39,14 @@ static struct fscache_object *cachefiles_alloc_object( object->type = cookie->type; - /* get hold of the raw key - * - stick the length on the front and leave space on the back for the - * encoder - */ - buffer = kmalloc((2 + 512) + 3, cachefiles_gfp); - if (!buffer) - goto nomem_buffer; - - keylen = cookie->key_len; - p = fscache_get_key(cookie); - memcpy(buffer + 2, p, keylen); - - *(uint16_t *)buffer = keylen; - ((char *)buffer)[keylen + 2] = 0; - ((char *)buffer)[keylen + 3] = 0; - ((char *)buffer)[keylen + 4] = 0; - /* turn the raw key into something that can work with as a filename */ - key = cachefiles_cook_key(buffer, keylen + 2, object->type); - kfree(buffer); - if (!key) + if (!cachefiles_cook_key(object)) goto nomem_key; - object->lookup_key = key; - - _leave(" = %x [%s]", object->fscache.debug_id, key); + _leave(" = %x [%s]", object->fscache.debug_id, object->d_name); return &object->fscache; nomem_key: - kfree(buffer); -nomem_buffer: kmem_cache_free(cachefiles_object_jar, object); fscache_object_destroyed(&cache->cache); nomem_object: @@ -98,11 +72,11 @@ static int cachefiles_lookup_object(struct fscache_object *_object) struct cachefiles_object, fscache); object = container_of(_object, struct cachefiles_object, fscache); - ASSERTCMP(object->lookup_key, !=, NULL); + ASSERT(object->d_name); /* look up the key, creating any missing bits */ cachefiles_begin_secure(cache, &saved_cred); - ret = cachefiles_walk_to_object(parent, object, object->lookup_key); + ret = cachefiles_walk_to_object(parent, object); cachefiles_end_secure(cache, saved_cred); /* polish off by setting the attributes of non-index files */ @@ -130,9 +104,6 @@ static void cachefiles_lookup_complete(struct fscache_object *_object) object = container_of(_object, struct cachefiles_object, fscache); _enter("{OBJ%x}", object->fscache.debug_id); - - kfree(object->lookup_key); - object->lookup_key = NULL; } /* @@ -224,7 +195,7 @@ static void cachefiles_drop_object(struct fscache_object *_object) dput(object->backer); object->backer = NULL; - cachefiles_unmark_inode_in_use(object, object->dentry); + cachefiles_unmark_inode_in_use(object); dput(object->dentry); object->dentry = NULL; } @@ -269,7 +240,7 @@ void cachefiles_put_object(struct fscache_object *_object, ASSERTCMP(object->fscache.n_ops, ==, 0); ASSERTCMP(object->fscache.n_children, ==, 0); - kfree(object->lookup_key); + kfree(object->d_name); cache = object->fscache.cache; fscache_object_destroy(&object->fscache); diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index 6464a6821bfb..83911cf24769 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -34,13 +34,15 @@ extern unsigned cachefiles_debug; */ struct cachefiles_object { struct fscache_object fscache; /* fscache handle */ - char *lookup_key; /* key to look up */ + char *d_name; /* Filename */ struct dentry *dentry; /* the file/dir representing this object */ struct dentry *backer; /* backing file */ loff_t i_size; /* object size */ atomic_t usage; /* object usage count */ uint8_t type; /* object type */ - uint8_t new; /* T if object new */ + bool new; /* T if object new */ + u8 d_name_len; /* Length of filename */ + u8 key_hash; }; extern struct kmem_cache *cachefiles_object_jar; @@ -119,21 +121,20 @@ void cachefiles_put_object(struct fscache_object *_object, /* * key.c */ -extern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type); +extern bool cachefiles_cook_key(struct cachefiles_object *object); /* * namei.c */ -extern void cachefiles_unmark_inode_in_use(struct cachefiles_object *object, - struct dentry *dentry); +extern void cachefiles_unmark_inode_in_use(struct cachefiles_object *object); extern int cachefiles_delete_object(struct cachefiles_cache *cache, struct cachefiles_object *object); extern int cachefiles_walk_to_object(struct cachefiles_object *parent, - struct cachefiles_object *object, - const char *key); + struct cachefiles_object *object); extern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, struct dentry *dir, - const char *name); + const char *name, + struct cachefiles_object *object); extern int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir, char *filename); diff --git a/fs/cachefiles/key.c b/fs/cachefiles/key.c index 7f94efc97e23..56a9b3201b41 100644 --- a/fs/cachefiles/key.c +++ b/fs/cachefiles/key.c @@ -24,132 +24,107 @@ static const char cachefiles_filecharmap[256] = { /* * turn the raw key into something cooked - * - the raw key should include the length in the two bytes at the front - * - the key may be up to 514 bytes in length (including the length word) + * - the key may be up to NAME_MAX in length (including the length word) * - "base64" encode the strange keys, mapping 3 bytes of raw to four of * cooked * - need to cut the cooked key into 252 char lengths (189 raw bytes) */ -char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type) +bool cachefiles_cook_key(struct cachefiles_object *object) { - unsigned char csum, ch; - unsigned int acc; - char *key; - int loop, len, max, seg, mark, print; + const u8 *key = fscache_get_key(object->fscache.cookie); + unsigned int acc, sum, keylen = object->fscache.cookie->key_len; + char *name; + u8 *buffer, *p; + int i, len, elem3, print; + u8 type; _enter(",%d", keylen); - BUG_ON(keylen < 2 || keylen > 514); + BUG_ON(keylen > NAME_MAX - 3); - csum = raw[0] + raw[1]; + sum = 0; print = 1; - for (loop = 2; loop < keylen; loop++) { - ch = raw[loop]; - csum += ch; + for (i = 0; i < keylen; i++) { + u8 ch = key[i]; + sum += ch; print &= cachefiles_filecharmap[ch]; } + object->key_hash = sum; + /* If the path is usable ASCII, then we render it directly */ if (print) { - /* if the path is usable ASCII, then we render it directly */ - max = keylen - 2; - max += 2; /* two base64'd length chars on the front */ - max += 5; /* @checksum/M */ - max += 3 * 2; /* maximum number of segment dividers (".../M") - * is ((514 + 251) / 252) = 3 - */ - max += 1; /* NUL on end */ - } else { - /* calculate the maximum length of the cooked key */ - keylen = (keylen + 2) / 3; - - max = keylen * 4; - max += 5; /* @checksum/M */ - max += 3 * 2; /* maximum number of segment dividers (".../M") - * is ((514 + 188) / 189) = 3 - */ - max += 1; /* NUL on end */ - } + name = kmalloc(3 + keylen + 1, cachefiles_gfp); + if (!name) + return false; - max += 1; /* 2nd NUL on end */ + switch (object->fscache.cookie->type) { + case FSCACHE_COOKIE_TYPE_INDEX: type = 'I'; break; + case FSCACHE_COOKIE_TYPE_DATAFILE: type = 'D'; break; + default: type = 'S'; break; + } - _debug("max: %d", max); + name[0] = type; + name[1] = cachefiles_charmap[(keylen >> 6) & 63]; + name[2] = cachefiles_charmap[keylen & 63]; - key = kmalloc(max, cachefiles_gfp); - if (!key) - return NULL; + memcpy(name + 3, key, keylen); + name[3 + keylen] = 0; + object->d_name = name; + object->d_name_len = 3 + keylen; + goto success; + } - len = 0; + /* Construct the key we actually want to render. We stick the length + * on the front and leave NULs on the back for the encoder to overread. + */ + buffer = kmalloc(2 + keylen + 3, cachefiles_gfp); + if (!buffer) + return false; - /* build the cooked key */ - sprintf(key, "@%02x%c+", (unsigned) csum, 0); - len = 5; - mark = len - 1; + memcpy(buffer + 2, key, keylen); - if (print) { - acc = *(uint16_t *) raw; - raw += 2; + *(uint16_t *)buffer = keylen; + ((char *)buffer)[keylen + 2] = 0; + ((char *)buffer)[keylen + 3] = 0; + ((char *)buffer)[keylen + 4] = 0; - key[len + 1] = cachefiles_charmap[acc & 63]; - acc >>= 6; - key[len] = cachefiles_charmap[acc & 63]; - len += 2; - - seg = 250; - for (loop = keylen; loop > 0; loop--) { - if (seg <= 0) { - key[len++] = '\0'; - mark = len; - key[len++] = '+'; - seg = 252; - } - - key[len++] = *raw++; - ASSERT(len < max); - } + elem3 = DIV_ROUND_UP(2 + keylen, 3); /* Count of 3-byte elements */ + len = elem3 * 4; - switch (type) { - case FSCACHE_COOKIE_TYPE_INDEX: type = 'I'; break; - case FSCACHE_COOKIE_TYPE_DATAFILE: type = 'D'; break; - default: type = 'S'; break; - } - } else { - seg = 252; - for (loop = keylen; loop > 0; loop--) { - if (seg <= 0) { - key[len++] = '\0'; - mark = len; - key[len++] = '+'; - seg = 252; - } - - acc = *raw++; - acc |= *raw++ << 8; - acc |= *raw++ << 16; - - _debug("acc: %06x", acc); - - key[len++] = cachefiles_charmap[acc & 63]; - acc >>= 6; - key[len++] = cachefiles_charmap[acc & 63]; - acc >>= 6; - key[len++] = cachefiles_charmap[acc & 63]; - acc >>= 6; - key[len++] = cachefiles_charmap[acc & 63]; - - ASSERT(len < max); - } + name = kmalloc(1 + len + 1, cachefiles_gfp); + if (!name) { + kfree(buffer); + return false; + } - switch (type) { - case FSCACHE_COOKIE_TYPE_INDEX: type = 'J'; break; - case FSCACHE_COOKIE_TYPE_DATAFILE: type = 'E'; break; - default: type = 'T'; break; - } + switch (object->fscache.cookie->type) { + case FSCACHE_COOKIE_TYPE_INDEX: type = 'J'; break; + case FSCACHE_COOKIE_TYPE_DATAFILE: type = 'E'; break; + default: type = 'T'; break; } - key[mark] = type; - key[len++] = 0; - key[len] = 0; + name[0] = type; + len = 1; + p = buffer; + for (i = 0; i < elem3; i++) { + acc = *p++; + acc |= *p++ << 8; + acc |= *p++ << 16; + + name[len++] = cachefiles_charmap[acc & 63]; + acc >>= 6; + name[len++] = cachefiles_charmap[acc & 63]; + acc >>= 6; + name[len++] = cachefiles_charmap[acc & 63]; + acc >>= 6; + name[len++] = cachefiles_charmap[acc & 63]; + } - _leave(" = %s %d", key, len); - return key; + name[len] = 0; + object->d_name = name; + object->d_name_len = len; + kfree(buffer); +success: + _leave(" = %s", object->d_name); + return true; } diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 04c767624e3d..10b6d571eda8 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -23,9 +23,9 @@ /* * Mark the backing file as being a cache file if it's not already in use so. */ -static bool cachefiles_mark_inode_in_use(struct cachefiles_object *object, - struct dentry *dentry) +static bool cachefiles_mark_inode_in_use(struct cachefiles_object *object) { + struct dentry *dentry = object->dentry; struct inode *inode = d_backing_inode(dentry); bool can_use = false; @@ -48,9 +48,9 @@ static bool cachefiles_mark_inode_in_use(struct cachefiles_object *object, /* * Unmark a backing inode. */ -void cachefiles_unmark_inode_in_use(struct cachefiles_object *object, - struct dentry *dentry) +void cachefiles_unmark_inode_in_use(struct cachefiles_object *object) { + struct dentry *dentry = object->dentry; struct inode *inode = d_backing_inode(dentry); inode_lock(inode); @@ -265,263 +265,221 @@ int cachefiles_delete_object(struct cachefiles_cache *cache, } /* - * walk from the parent object to the child object through the backing - * filesystem, creating directories as we go + * Check and open the terminal object. */ -int cachefiles_walk_to_object(struct cachefiles_object *parent, - struct cachefiles_object *object, - const char *key) +static int cachefiles_check_open_object(struct cachefiles_cache *cache, + struct cachefiles_object *object, + struct dentry *fan) { - struct cachefiles_cache *cache; - struct dentry *dir, *next = NULL; - struct inode *inode; struct path path; - const char *name; - bool marked = false; - int ret, nlen; + int ret; - _enter("OBJ%x{%pd},OBJ%x,%s,", - parent->fscache.debug_id, parent->dentry, - object->fscache.debug_id, key); + if (!cachefiles_mark_inode_in_use(object)) + return -EBUSY; - cache = container_of(parent->fscache.cache, - struct cachefiles_cache, cache); - path.mnt = cache->mnt; + /* if we've found that the terminal object exists, then we need to + * check its attributes and delete it if it's out of date */ + if (!object->new) { + _debug("validate '%pd'", object->dentry); - ASSERT(parent->dentry); - ASSERT(d_backing_inode(parent->dentry)); + ret = cachefiles_check_auxdata(object); + if (ret == -ESTALE) + goto stale; + if (ret < 0) + goto error_unmark; + } + + _debug("=== OBTAINED_OBJECT ==="); - if (!(d_is_dir(parent->dentry))) { - // TODO: convert file to dir - _leave("looking up in none directory"); - return -ENOBUFS; + if (object->new) { + /* attach data to a newly constructed terminal object */ + ret = cachefiles_set_object_xattr(object, XATTR_CREATE); + if (ret < 0) + goto error_unmark; + } else { + /* always update the atime on an object we've just looked up + * (this is used to keep track of culling, and atimes are only + * updated by read, write and readdir but not lookup or + * open) */ + path.mnt = cache->mnt; + path.dentry = object->dentry; + touch_atime(&path); } - dir = dget(parent->dentry); + return 0; -advance: - /* attempt to transit the first directory component */ - name = key; - nlen = strlen(key); +stale: + cachefiles_unmark_inode_in_use(object); + inode_lock_nested(d_inode(fan), I_MUTEX_PARENT); + ret = cachefiles_bury_object(cache, object, fan, object->dentry, + FSCACHE_OBJECT_IS_STALE); + if (ret < 0) + return ret; + _debug("redo lookup"); + return -ESTALE; - /* key ends in a double NUL */ - key = key + nlen + 1; - if (!*key) - key = NULL; +error_unmark: + cachefiles_unmark_inode_in_use(object); + return ret; +} -lookup_again: - /* search the current directory for the element name */ - _debug("lookup '%s'", name); +/* + * Walk to a file, creating it if necessary. + */ +static int cachefiles_walk_to_file(struct cachefiles_cache *cache, + struct cachefiles_object *object, + struct dentry *fan) +{ + struct dentry *dentry; + struct inode *dinode = d_backing_inode(fan); + struct path fan_path; + int ret; - inode_lock_nested(d_inode(dir), I_MUTEX_PARENT); + _enter("%pd %s", fan, object->d_name); - next = lookup_one_len(name, dir, nlen); - if (IS_ERR(next)) { - trace_cachefiles_lookup(object, next, NULL); - ret = PTR_ERR(next); - goto lookup_error; - } + inode_lock_nested(dinode, I_MUTEX_PARENT); - inode = d_backing_inode(next); - trace_cachefiles_lookup(object, next, inode); - _debug("next -> %pd %s", next, inode ? "positive" : "negative"); + dentry = lookup_one_len(object->d_name, fan, object->d_name_len); + if (IS_ERR(dentry)) { + trace_cachefiles_lookup(object, dentry, NULL); + ret = PTR_ERR(dentry); + goto error; + } - if (!key) - object->new = !inode; + trace_cachefiles_lookup(object, dentry, d_backing_inode(dentry)); - /* if this element of the path doesn't exist, then the lookup phase - * failed, and we can release any readers in the certain knowledge that - * there's nothing for them to actually read */ - if (d_is_negative(next)) + if (d_is_negative(dentry)) { + /* This element of the path doesn't exist, so we can release + * any readers in the certain knowledge that there's nothing + * for them to actually read */ fscache_object_lookup_negative(&object->fscache); - /* we need to create the object if it's negative */ - if (key || object->type == FSCACHE_COOKIE_TYPE_INDEX) { - /* index objects and intervening tree levels must be subdirs */ - if (d_is_negative(next)) { - ret = cachefiles_has_space(cache, 1, 0); - if (ret < 0) - goto no_space_error; - - path.dentry = dir; - ret = security_path_mkdir(&path, next, 0); - if (ret < 0) - goto create_error; - ret = vfs_mkdir(&init_user_ns, d_inode(dir), next, 0); - if (!key) - trace_cachefiles_mkdir(object, next, ret); - if (ret < 0) - goto create_error; - - if (unlikely(d_unhashed(next))) { - dput(next); - inode_unlock(d_inode(dir)); - goto lookup_again; - } - ASSERT(d_backing_inode(next)); - - _debug("mkdir -> %pd{ino=%lu}", - next, d_backing_inode(next)->i_ino); - - } else if (!d_can_lookup(next)) { - pr_err("inode %lu is not a directory\n", - d_backing_inode(next)->i_ino); - ret = -ENOBUFS; - goto error; + ret = cachefiles_has_space(cache, 1, 0); + if (ret < 0) { + fscache_object_mark_killed(&object->fscache, FSCACHE_OBJECT_NO_SPACE); + goto error_dput; } - } else { - /* non-index objects start out life as files */ - if (d_is_negative(next)) { - ret = cachefiles_has_space(cache, 1, 0); - if (ret < 0) - goto no_space_error; - - path.dentry = dir; - ret = security_path_mknod(&path, next, S_IFREG, 0); - if (ret < 0) - goto create_error; - ret = vfs_create(&init_user_ns, d_inode(dir), next, - S_IFREG, true); - trace_cachefiles_create(object, next, ret); - if (ret < 0) - goto create_error; - - ASSERT(d_backing_inode(next)); - - _debug("create -> %pd{ino=%lu}", - next, d_backing_inode(next)->i_ino); - - } else if (!d_can_lookup(next) && - !d_is_reg(next) - ) { - pr_err("inode %lu is not a file or directory\n", - d_backing_inode(next)->i_ino); - ret = -ENOBUFS; - goto error; - } - } + fan_path.mnt = cache->mnt; + fan_path.dentry = fan; + ret = security_path_mknod(&fan_path, dentry, S_IFREG, 0); + if (ret < 0) + goto error_dput; + ret = vfs_create(&init_user_ns, dinode, dentry, S_IFREG, true); + trace_cachefiles_create(object, dentry, ret); + if (ret < 0) + goto error_dput; - /* process the next component */ - if (key) { - _debug("advance"); - inode_unlock(d_inode(dir)); - dput(dir); - dir = next; - next = NULL; - goto advance; - } + _debug("create -> %pd{ino=%lu}", + dentry, d_backing_inode(dentry)->i_ino); + object->new = true; - /* we've found the object we were looking for */ - object->dentry = next; + } else if (!d_is_reg(dentry)) { + pr_err("inode %lu is not a file\n", + d_backing_inode(dentry)->i_ino); + ret = -EIO; + goto error_dput; + } else { + _debug("file -> %pd positive", dentry); + } - /* note that we're now using this object */ - if (!cachefiles_mark_inode_in_use(object, object->dentry)) { - ret = -EBUSY; - goto check_error_unlock; + if (dentry->d_sb->s_blocksize > PAGE_SIZE) { + pr_warn("cachefiles: Block size too large\n"); + ret = -EIO; + goto error_dput; } - marked = true; - /* if we've found that the terminal object exists, then we need to - * check its attributes and delete it if it's out of date */ - if (!object->new) { - _debug("validate '%pd'", next); + object->dentry = dentry; + inode_unlock(dinode); + return 0; - ret = cachefiles_check_auxdata(object); - if (ret == -ESTALE) { - /* delete the object (the deleter drops the directory - * mutex) */ - object->dentry = NULL; - - ret = cachefiles_bury_object(cache, object, dir, next, - FSCACHE_OBJECT_IS_STALE); - dput(next); - next = NULL; - - if (ret < 0) - goto error_out2; - - _debug("redo lookup"); - fscache_object_retrying_stale(&object->fscache); - goto lookup_again; - } - } +error_dput: + dput(dentry); +error: + inode_unlock(dinode); + return ret; +} - inode_unlock(d_inode(dir)); - dput(dir); - dir = NULL; +/* + * Walk over the fanout directory. + */ +static struct dentry *cachefiles_walk_over_fanout(struct cachefiles_object *object, + struct cachefiles_cache *cache, + struct dentry *dir) +{ + char name[4]; - _debug("=== OBTAINED_OBJECT ==="); + snprintf(name, sizeof(name), "@%02x", object->key_hash); + return cachefiles_get_directory(cache, dir, name, object); +} - if (object->new) { - /* attach data to a newly constructed terminal object */ - ret = cachefiles_set_object_xattr(object, XATTR_CREATE); - if (ret < 0) - goto check_error; - } else { - /* always update the atime on an object we've just looked up - * (this is used to keep track of culling, and atimes are only - * updated by read, write and readdir but not lookup or - * open) */ - path.dentry = next; - touch_atime(&path); - } +/* + * walk from the parent object to the child object through the backing + * filesystem, creating directories as we go + */ +int cachefiles_walk_to_object(struct cachefiles_object *parent, + struct cachefiles_object *object) +{ + struct cachefiles_cache *cache; + struct dentry *fan, *dentry; + int ret; - /* open a file interface onto a data file */ - if (object->type != FSCACHE_COOKIE_TYPE_INDEX) { - if (d_is_reg(object->dentry)) { - const struct address_space_operations *aops; + _enter("OBJ%x{%pd},OBJ%x,%s,", + parent->fscache.debug_id, parent->dentry, + object->fscache.debug_id, object->d_name); - ret = -EPERM; - aops = d_backing_inode(object->dentry)->i_mapping->a_ops; - if (!aops->bmap) - goto check_error; - if (object->dentry->d_sb->s_blocksize > PAGE_SIZE) - goto check_error; + cache = container_of(parent->fscache.cache, + struct cachefiles_cache, cache); + ASSERT(parent->dentry); + ASSERT(d_backing_inode(parent->dentry)); - object->backer = object->dentry; - } else { - BUG(); // TODO: open file in data-class subdir +lookup_again: + fan = cachefiles_walk_over_fanout(object, cache, parent->dentry); + if (IS_ERR(fan)) + return PTR_ERR(fan); + + /* Walk over path "parent/fanout/object". */ + if (object->type == FSCACHE_COOKIE_TYPE_INDEX) { + dentry = cachefiles_get_directory(cache, fan, object->d_name, + object); + if (IS_ERR(dentry)) { + dput(fan); + return PTR_ERR(dentry); + } + object->dentry = dentry; + } else { + ret = cachefiles_walk_to_file(cache, object, fan); + if (ret < 0) { + dput(fan); + return ret; } } - object->new = 0; - fscache_obtained_object(&object->fscache); + ret = cachefiles_check_open_object(cache, object, fan); + dput(fan); + fan = NULL; + if (ret < 0) + goto check_error; + object->backer = object->dentry; + object->new = false; + fscache_obtained_object(&object->fscache); _leave(" = 0 [%lu]", d_backing_inode(object->dentry)->i_ino); return 0; -no_space_error: - fscache_object_mark_killed(&object->fscache, FSCACHE_OBJECT_NO_SPACE); -create_error: - _debug("create error %d", ret); - if (ret == -EIO) - cachefiles_io_error(cache, "Create/mkdir failed"); - goto error; - -check_error_unlock: - inode_unlock(d_inode(dir)); - dput(dir); check_error: - if (marked) - cachefiles_unmark_inode_in_use(object, object->dentry); + if (ret == -ESTALE) { + dput(object->dentry); + object->dentry = NULL; + fscache_object_retrying_stale(&object->fscache); + goto lookup_again; + } + if (ret == -EIO) + cachefiles_io_error_obj(object, "Lookup failed"); cachefiles_mark_object_inactive(cache, object); dput(object->dentry); object->dentry = NULL; - goto error_out; - -lookup_error: - _debug("lookup error %d", ret); - if (ret == -EIO) - cachefiles_io_error(cache, "Lookup failed"); - next = NULL; -error: - inode_unlock(d_inode(dir)); - dput(next); -error_out2: - dput(dir); -error_out: - _leave(" = error %d", -ret); + _leave(" = error %d", ret); return ret; } @@ -530,7 +488,8 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, */ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, struct dentry *dir, - const char *dirname) + const char *dirname, + struct cachefiles_object *object) { struct dentry *subdir; struct path path; @@ -554,6 +513,12 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, /* we need to create the subdir if it doesn't exist yet */ if (d_is_negative(subdir)) { + /* This element of the path doesn't exist, so we can release + * any readers in the certain knowledge that there's nothing + * for them to actually read */ + if (object) + fscache_object_lookup_negative(&object->fscache); + ret = cachefiles_has_space(cache, 1, 0); if (ret < 0) goto mkdir_error; @@ -577,6 +542,8 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, _debug("mkdir -> %pd{ino=%lu}", subdir, d_backing_inode(subdir)->i_ino); + if (object) + object->new = true; } inode_unlock(d_inode(dir)); diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h index 57d811718953..bd0b5bbd3889 100644 --- a/include/trace/events/cachefiles.h +++ b/include/trace/events/cachefiles.h @@ -119,28 +119,6 @@ TRACE_EVENT(cachefiles_lookup, __entry->obj, __entry->de, __entry->inode) ); -TRACE_EVENT(cachefiles_mkdir, - TP_PROTO(struct cachefiles_object *obj, - struct dentry *de, int ret), - - TP_ARGS(obj, de, ret), - - TP_STRUCT__entry( - __field(unsigned int, obj ) - __field(struct dentry *, de ) - __field(int, ret ) - ), - - TP_fast_assign( - __entry->obj = obj->fscache.debug_id; - __entry->de = de; - __entry->ret = ret; - ), - - TP_printk("o=%08x d=%p r=%u", - __entry->obj, __entry->de, __entry->ret) - ); - TRACE_EVENT(cachefiles_create, TP_PROTO(struct cachefiles_object *obj, struct dentry *de, int ret), From patchwork Mon Oct 18 14:56:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566971 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F26DBC433EF for ; Mon, 18 Oct 2021 14:56:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D05D361002 for ; Mon, 18 Oct 2021 14:56:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232844AbhJRO7I (ORCPT ); Mon, 18 Oct 2021 10:59:08 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:53605 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232741AbhJRO7G (ORCPT ); Mon, 18 Oct 2021 10:59:06 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569015; 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=0IGgvCu7e2XQhbY70i8TSPJVNJmFP5Vsi2waD4HEQVM=; b=PA+71rY0RU4XXDOwTBIFlKfjk55XGIBO9OG8EwscwLgYYbs/boZwr+3LGR2LLvWNwqVD5h z57oLanl8ObWzhXDkk6GIJcTVJT7tSlpZWh3PnP6mthLvJNkx8WVkDl0zfL1YWXCTJd2iU B5on4Qw3MX2sNSS1UZPupK2KpBOF+yQ= 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-226-YOy2swJJMP6NZIQxWFL5mw-1; Mon, 18 Oct 2021 10:56:52 -0400 X-MC-Unique: YOy2swJJMP6NZIQxWFL5mw-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id A2BB418D6A36; Mon, 18 Oct 2021 14:56:49 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 99AE7100E809; Mon, 18 Oct 2021 14:56:46 +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 23/67] cachefiles: trace: Improve the lookup tracepoint From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:56:45 +0100 Message-ID: <163456900574.2614702.12478396115896341195.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Improve the cachefiles_lookup tracepoint: - Don't display the dentry address, since it's going to get hashed. - Do display any error code. - Work out the inode in the tracepoint rather than in the caller so that the logic is conditional on the tracepoint being enabled. Signed-off-by: David Howells --- fs/cachefiles/namei.c | 4 +--- include/trace/events/cachefiles.h | 18 +++++++++--------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 10b6d571eda8..b5a0aec529af 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -340,14 +340,12 @@ static int cachefiles_walk_to_file(struct cachefiles_cache *cache, inode_lock_nested(dinode, I_MUTEX_PARENT); dentry = lookup_one_len(object->d_name, fan, object->d_name_len); + trace_cachefiles_lookup(object, dentry); if (IS_ERR(dentry)) { - trace_cachefiles_lookup(object, dentry, NULL); ret = PTR_ERR(dentry); goto error; } - trace_cachefiles_lookup(object, dentry, d_backing_inode(dentry)); - if (d_is_negative(dentry)) { /* This element of the path doesn't exist, so we can release * any readers in the certain knowledge that there's nothing diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h index bd0b5bbd3889..87681dd957ec 100644 --- a/include/trace/events/cachefiles.h +++ b/include/trace/events/cachefiles.h @@ -98,25 +98,25 @@ TRACE_EVENT(cachefiles_ref, TRACE_EVENT(cachefiles_lookup, TP_PROTO(struct cachefiles_object *obj, - struct dentry *de, - struct inode *inode), + struct dentry *de), - TP_ARGS(obj, de, inode), + TP_ARGS(obj, de), TP_STRUCT__entry( __field(unsigned int, obj ) - __field(struct dentry *, de ) - __field(struct inode *, inode ) + __field(short, error ) + __field(unsigned long, ino ) ), TP_fast_assign( __entry->obj = obj->fscache.debug_id; - __entry->de = de; - __entry->inode = inode; + __entry->ino = (!IS_ERR(de) && d_backing_inode(de) ? + d_backing_inode(de)->i_ino : 0); + __entry->error = IS_ERR(de) ? PTR_ERR(de) : 0; ), - TP_printk("o=%08x d=%p i=%p", - __entry->obj, __entry->de, __entry->inode) + TP_printk("o=%08x i=%lx e=%d", + __entry->obj, __entry->ino, __entry->error) ); TRACE_EVENT(cachefiles_create, From patchwork Mon Oct 18 14:56:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566973 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 901F7C433EF for ; Mon, 18 Oct 2021 14:57:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7803060C49 for ; Mon, 18 Oct 2021 14:57:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232221AbhJRO7W (ORCPT ); Mon, 18 Oct 2021 10:59:22 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:30022 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232905AbhJRO7P (ORCPT ); Mon, 18 Oct 2021 10:59:15 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569024; 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=gffoLzvDPsOEDMd/EdqBWrUIkxMzdS8M/lUepfNC0Jw=; b=gL/Tl6XLhNXjHK7fIwBv3EMMmc8rV+05QXy+5vu3ENNbo+TjTFH1BZYIEfc+H1EobFqfDx lVpWqb66N8VfjT0WTyGazuAAjcYhYcCQTuXd7ntkM4vpq13E/sefKRjqEkdKD8CIipOGwW FykR8R/5vegJPKn/pXhJau8HXC3Tx6E= 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-330-6D7N4RWvOOGQNU4snc2u8A-1; Mon, 18 Oct 2021 10:57:00 -0400 X-MC-Unique: 6D7N4RWvOOGQNU4snc2u8A-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D40611006AA4; Mon, 18 Oct 2021 14:56:58 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id A39C3100E809; Mon, 18 Oct 2021 14:56:55 +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 24/67] cachefiles: Remove separate backer dentry from cachefiles_object From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:56:54 +0100 Message-ID: <163456901488.2614702.3877237088238450861.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org The cachefiles_object struct has two dentry pointers - one for the file/directory representing the object and a second one in case a data object is a directory with a file inside of it that contains the data (the idea being that there might be another file, say, containing a journal of local changes that need committing or a list of cached xattrs). At the moment, this isn't implemented, so remove it and always use the main dentry pointer. Signed-off-by: David Howells --- fs/cachefiles/bind.c | 2 -- fs/cachefiles/interface.c | 28 +++++++++------------------- fs/cachefiles/internal.h | 1 - fs/cachefiles/io.c | 4 ++-- fs/cachefiles/namei.c | 1 - 5 files changed, 11 insertions(+), 25 deletions(-) diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c index fbc8577477c1..cb3296814056 100644 --- a/fs/cachefiles/bind.c +++ b/fs/cachefiles/bind.c @@ -101,8 +101,6 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) if (!fsdef) goto error_root_object; - ASSERTCMP(fsdef->backer, ==, NULL); - atomic_set(&fsdef->usage, 1); fsdef->type = FSCACHE_COOKIE_TYPE_INDEX; diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 2083aca6bd0c..92bb3ba78c41 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -31,8 +31,6 @@ static struct fscache_object *cachefiles_alloc_object( if (!object) goto nomem_object; - ASSERTCMP(object->backer, ==, NULL); - atomic_set(&object->usage, 1); fscache_object_init(&object->fscache, cookie, &cache->cache); @@ -191,10 +189,6 @@ static void cachefiles_drop_object(struct fscache_object *_object) } /* close the filesystem stuff attached to the object */ - if (object->backer != object->dentry) - dput(object->backer); - object->backer = NULL; - cachefiles_unmark_inode_in_use(object); dput(object->dentry); object->dentry = NULL; @@ -235,7 +229,6 @@ void cachefiles_put_object(struct fscache_object *_object, _debug("- kill object OBJ%x", object->fscache.debug_id); ASSERTCMP(object->fscache.parent, ==, NULL); - ASSERTCMP(object->backer, ==, NULL); ASSERTCMP(object->dentry, ==, NULL); ASSERTCMP(object->fscache.n_ops, ==, 0); ASSERTCMP(object->fscache.n_children, ==, 0); @@ -303,17 +296,14 @@ static int cachefiles_attr_changed(struct cachefiles_object *object) if (ni_size == object->i_size) return 0; - if (!object->backer) - return -ENOBUFS; + ASSERT(d_is_reg(object->dentry)); - ASSERT(d_is_reg(object->backer)); - - oi_size = i_size_read(d_backing_inode(object->backer)); + oi_size = i_size_read(d_backing_inode(object->dentry)); if (oi_size == ni_size) return 0; cachefiles_begin_secure(cache, &saved_cred); - inode_lock(d_inode(object->backer)); + inode_lock(d_inode(object->dentry)); /* if there's an extension to a partial page at the end of the backing * file, we need to discard the partial page so that we pick up new @@ -322,17 +312,17 @@ static int cachefiles_attr_changed(struct cachefiles_object *object) _debug("discard tail %llx", oi_size); newattrs.ia_valid = ATTR_SIZE; newattrs.ia_size = oi_size & PAGE_MASK; - ret = notify_change(&init_user_ns, object->backer, &newattrs, NULL); + ret = notify_change(&init_user_ns, object->dentry, &newattrs, NULL); if (ret < 0) goto truncate_failed; } newattrs.ia_valid = ATTR_SIZE; newattrs.ia_size = ni_size; - ret = notify_change(&init_user_ns, object->backer, &newattrs, NULL); + ret = notify_change(&init_user_ns, object->dentry, &newattrs, NULL); truncate_failed: - inode_unlock(d_inode(object->backer)); + inode_unlock(d_inode(object->dentry)); cachefiles_end_secure(cache, saved_cred); if (ret == -EIO) { @@ -365,10 +355,10 @@ static void cachefiles_invalidate_object(struct fscache_object *_object) _enter("{OBJ%x},[%llu]", object->fscache.debug_id, (unsigned long long)ni_size); - if (object->backer) { - ASSERT(d_is_reg(object->backer)); + if (object->dentry) { + ASSERT(d_is_reg(object->dentry)); - path.dentry = object->backer; + path.dentry = object->dentry; path.mnt = cache->mnt; cachefiles_begin_secure(cache, &saved_cred); diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index 83911cf24769..9f2f837027e0 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -36,7 +36,6 @@ struct cachefiles_object { struct fscache_object fscache; /* fscache handle */ char *d_name; /* Filename */ struct dentry *dentry; /* the file/dir representing this object */ - struct dentry *backer; /* backing file */ loff_t i_size; /* object size */ atomic_t usage; /* object usage count */ uint8_t type; /* object type */ diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index 534c81a05918..920ca48eecfa 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -426,9 +426,9 @@ int cachefiles_begin_operation(struct netfs_cache_resources *cres) struct cachefiles_cache, cache); path.mnt = cache->mnt; - path.dentry = object->backer; + path.dentry = object->dentry; file = open_with_fake_path(&path, O_RDWR | O_LARGEFILE | O_DIRECT, - d_inode(object->backer), cache->cache_cred); + d_inode(object->dentry), cache->cache_cred); if (IS_ERR(file)) return PTR_ERR(file); if (!S_ISREG(file_inode(file)->i_mode)) diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index b5a0aec529af..7f02fcb34b1e 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -459,7 +459,6 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, if (ret < 0) goto check_error; - object->backer = object->dentry; object->new = false; fscache_obtained_object(&object->fscache); _leave(" = 0 [%lu]", d_backing_inode(object->dentry)->i_ino); From patchwork Mon Oct 18 14:57:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566975 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7EAF8C433FE for ; Mon, 18 Oct 2021 14:57:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 68E226103B for ; Mon, 18 Oct 2021 14:57:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233033AbhJRO7l (ORCPT ); Mon, 18 Oct 2021 10:59:41 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:24674 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232931AbhJRO7d (ORCPT ); Mon, 18 Oct 2021 10:59:33 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569041; 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=ri23d0kOe2QwmIyAtW/ggOo3iGWrkP0pmwkM3ZjyG+k=; b=OjeifktyIOSqKh2i/bJI7Uftp+icNwMSzdIiMHv3+A3EU29NKNBL7HokHN4dUhXTZwbGQY uBBih+hFt5EGq8KuXfdIT0+ACS7PUNlOlIj7dLb0cq7EQu9eM5qWJcGnJ5Ez19wXyBKEZI eWCZ9t3/ATxZ5TkMFbS/ibf+v4H9d6Q= 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-439-ZCGijVUMPCuOT2aGxddyQg-1; Mon, 18 Oct 2021 10:57:18 -0400 X-MC-Unique: ZCGijVUMPCuOT2aGxddyQg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E788F1006AA6; Mon, 18 Oct 2021 14:57:15 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 04A6860BF4; Mon, 18 Oct 2021 14:57:04 +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 25/67] cachefiles: Fold fscache_object into cachefiles_object From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:57:04 +0100 Message-ID: <163456902408.2614702.7160119571677792662.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Merge struct fscache_object into cachefiles_object so that it can be got rid of. Signed-off-by: David Howells --- fs/cachefiles/bind.c | 6 +- fs/cachefiles/interface.c | 116 +++++++++++++++---------------------- fs/cachefiles/internal.h | 19 +----- fs/cachefiles/key.c | 8 +-- fs/cachefiles/namei.c | 21 +++---- fs/cachefiles/xattr.c | 16 +++-- fs/fscache/cache.c | 10 ++- fs/fscache/cookie.c | 20 +++--- fs/fscache/internal.h | 4 + fs/fscache/object.c | 110 ++++++++++++++++++----------------- include/linux/fscache-cache.h | 71 +++++++++++++---------- include/trace/events/cachefiles.h | 14 ++-- include/trace/events/fscache.h | 2 - 13 files changed, 194 insertions(+), 223 deletions(-) diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c index cb3296814056..8db1ef2d1196 100644 --- a/fs/cachefiles/bind.c +++ b/fs/cachefiles/bind.c @@ -193,7 +193,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) } fsdef->dentry = cachedir; - fsdef->fscache.cookie = NULL; + fsdef->cookie = NULL; /* get the graveyard directory */ graveyard = cachefiles_get_directory(cache, root, "graveyard", NULL); @@ -210,10 +210,10 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) "%s", fsdef->dentry->d_sb->s_id); - fscache_object_init(&fsdef->fscache, &fscache_fsdef_index, + fscache_object_init(fsdef, &fscache_fsdef_index, &cache->cache); - ret = fscache_add_cache(&cache->cache, &fsdef->fscache, cache->tag); + ret = fscache_add_cache(&cache->cache, fsdef, cache->tag); if (ret < 0) goto error_add_cache; diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 92bb3ba78c41..7ec2302a3214 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -15,7 +15,7 @@ static int cachefiles_attr_changed(struct cachefiles_object *object); /* * allocate an object record for a cookie lookup and prepare the lookup data */ -static struct fscache_object *cachefiles_alloc_object( +static struct cachefiles_object *cachefiles_alloc_object( struct fscache_cache *_cache, struct fscache_cookie *cookie) { @@ -33,7 +33,7 @@ static struct fscache_object *cachefiles_alloc_object( atomic_set(&object->usage, 1); - fscache_object_init(&object->fscache, cookie, &cache->cache); + fscache_object_init(object, cookie, &cache->cache); object->type = cookie->type; @@ -41,8 +41,8 @@ static struct fscache_object *cachefiles_alloc_object( if (!cachefiles_cook_key(object)) goto nomem_key; - _leave(" = %x [%s]", object->fscache.debug_id, object->d_name); - return &object->fscache; + _leave(" = %x [%s]", object->debug_id, object->d_name); + return object; nomem_key: kmem_cache_free(cachefiles_object_jar, object); @@ -56,19 +56,17 @@ static struct fscache_object *cachefiles_alloc_object( * attempt to look up the nominated node in this cache * - return -ETIMEDOUT to be scheduled again */ -static int cachefiles_lookup_object(struct fscache_object *_object) +static int cachefiles_lookup_object(struct cachefiles_object *object) { - struct cachefiles_object *parent, *object; + struct cachefiles_object *parent; struct cachefiles_cache *cache; const struct cred *saved_cred; int ret; - _enter("{OBJ%x}", _object->debug_id); + _enter("{OBJ%x}", object->debug_id); - cache = container_of(_object->cache, struct cachefiles_cache, cache); - parent = container_of(_object->parent, - struct cachefiles_object, fscache); - object = container_of(_object, struct cachefiles_object, fscache); + cache = container_of(object->cache, struct cachefiles_cache, cache); + parent = object->parent; ASSERT(object->d_name); @@ -79,13 +77,13 @@ static int cachefiles_lookup_object(struct fscache_object *_object) /* polish off by setting the attributes of non-index files */ if (ret == 0 && - object->fscache.cookie->type != FSCACHE_COOKIE_TYPE_INDEX) + object->cookie->type != FSCACHE_COOKIE_TYPE_INDEX) cachefiles_attr_changed(object); if (ret < 0 && ret != -ETIMEDOUT) { if (ret != -ENOBUFS) pr_warn("Lookup failed error %d\n", ret); - fscache_object_lookup_error(&object->fscache); + fscache_object_lookup_error(object); } _leave(" [%d]", ret); @@ -95,52 +93,43 @@ static int cachefiles_lookup_object(struct fscache_object *_object) /* * indication of lookup completion */ -static void cachefiles_lookup_complete(struct fscache_object *_object) +static void cachefiles_lookup_complete(struct cachefiles_object *object) { - struct cachefiles_object *object; - - object = container_of(_object, struct cachefiles_object, fscache); - - _enter("{OBJ%x}", object->fscache.debug_id); + _enter("{OBJ%x}", object->debug_id); } /* * increment the usage count on an inode object (may fail if unmounting) */ static -struct fscache_object *cachefiles_grab_object(struct fscache_object *_object, - enum fscache_obj_ref_trace why) +struct cachefiles_object *cachefiles_grab_object(struct cachefiles_object *object, + enum fscache_obj_ref_trace why) { - struct cachefiles_object *object = - container_of(_object, struct cachefiles_object, fscache); int u; - _enter("{OBJ%x,%d}", _object->debug_id, atomic_read(&object->usage)); + _enter("{OBJ%x,%d}", object->debug_id, atomic_read(&object->usage)); #ifdef CACHEFILES_DEBUG_SLAB ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000); #endif u = atomic_inc_return(&object->usage); - trace_cachefiles_ref(object, _object->cookie, + trace_cachefiles_ref(object, object->cookie, (enum cachefiles_obj_ref_trace)why, u); - return &object->fscache; + return object; } /* * update the auxiliary data for an object object on disk */ -static void cachefiles_update_object(struct fscache_object *_object) +static void cachefiles_update_object(struct cachefiles_object *object) { - struct cachefiles_object *object; struct cachefiles_cache *cache; const struct cred *saved_cred; - _enter("{OBJ%x}", _object->debug_id); + _enter("{OBJ%x}", object->debug_id); - object = container_of(_object, struct cachefiles_object, fscache); - cache = container_of(object->fscache.cache, struct cachefiles_cache, - cache); + cache = container_of(object->cache, struct cachefiles_cache, cache); cachefiles_begin_secure(cache, &saved_cred); cachefiles_set_object_xattr(object, XATTR_REPLACE); @@ -152,21 +141,16 @@ static void cachefiles_update_object(struct fscache_object *_object) * discard the resources pinned by an object and effect retirement if * requested */ -static void cachefiles_drop_object(struct fscache_object *_object) +static void cachefiles_drop_object(struct cachefiles_object *object) { - struct cachefiles_object *object; struct cachefiles_cache *cache; const struct cred *saved_cred; - ASSERT(_object); - - object = container_of(_object, struct cachefiles_object, fscache); + ASSERT(object); - _enter("{OBJ%x,%d}", - object->fscache.debug_id, atomic_read(&object->usage)); + _enter("{OBJ%x,%d}", object->debug_id, atomic_read(&object->usage)); - cache = container_of(object->fscache.cache, - struct cachefiles_cache, cache); + cache = container_of(object->cache, struct cachefiles_cache, cache); #ifdef CACHEFILES_DEBUG_SLAB ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000); @@ -179,10 +163,10 @@ static void cachefiles_drop_object(struct fscache_object *_object) */ if (object->dentry) { /* delete retired objects */ - if (test_bit(FSCACHE_OBJECT_RETIRED, &object->fscache.flags) && - _object != cache->cache.fsdef + if (test_bit(FSCACHE_OBJECT_RETIRED, &object->flags) && + object != cache->cache.fsdef ) { - _debug("- retire object OBJ%x", object->fscache.debug_id); + _debug("- retire object OBJ%x", object->debug_id); cachefiles_begin_secure(cache, &saved_cred); cachefiles_delete_object(cache, object); cachefiles_end_secure(cache, saved_cred); @@ -200,43 +184,40 @@ static void cachefiles_drop_object(struct fscache_object *_object) /* * dispose of a reference to an object */ -void cachefiles_put_object(struct fscache_object *_object, +void cachefiles_put_object(struct cachefiles_object *object, enum fscache_obj_ref_trace why) { - struct cachefiles_object *object; struct fscache_cache *cache; int u; - ASSERT(_object); - - object = container_of(_object, struct cachefiles_object, fscache); + ASSERT(object); _enter("{OBJ%x,%d}", - object->fscache.debug_id, atomic_read(&object->usage)); + object->debug_id, atomic_read(&object->usage)); #ifdef CACHEFILES_DEBUG_SLAB ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000); #endif - ASSERTIFCMP(object->fscache.parent, - object->fscache.parent->n_children, >, 0); + ASSERTIFCMP(object->parent, + object->parent->n_children, >, 0); u = atomic_dec_return(&object->usage); - trace_cachefiles_ref(object, _object->cookie, + trace_cachefiles_ref(object, object->cookie, (enum cachefiles_obj_ref_trace)why, u); ASSERTCMP(u, !=, -1); if (u == 0) { - _debug("- kill object OBJ%x", object->fscache.debug_id); + _debug("- kill object OBJ%x", object->debug_id); - ASSERTCMP(object->fscache.parent, ==, NULL); + ASSERTCMP(object->parent, ==, NULL); ASSERTCMP(object->dentry, ==, NULL); - ASSERTCMP(object->fscache.n_ops, ==, 0); - ASSERTCMP(object->fscache.n_children, ==, 0); + ASSERTCMP(object->n_ops, ==, 0); + ASSERTCMP(object->n_children, ==, 0); kfree(object->d_name); - cache = object->fscache.cache; - fscache_object_destroy(&object->fscache); + cache = object->cache; + fscache_object_destroy(object); kmem_cache_free(cachefiles_object_jar, object); fscache_object_destroyed(cache); } @@ -285,12 +266,12 @@ static int cachefiles_attr_changed(struct cachefiles_object *object) loff_t oi_size; int ret; - ni_size = object->fscache.cookie->object_size; + ni_size = object->cookie->object_size; _enter("{OBJ%x},[%llu]", - object->fscache.debug_id, (unsigned long long) ni_size); + object->debug_id, (unsigned long long) ni_size); - cache = container_of(object->fscache.cache, + cache = container_of(object->cache, struct cachefiles_cache, cache); if (ni_size == object->i_size) @@ -337,23 +318,20 @@ static int cachefiles_attr_changed(struct cachefiles_object *object) /* * Invalidate an object */ -static void cachefiles_invalidate_object(struct fscache_object *_object) +static void cachefiles_invalidate_object(struct cachefiles_object *object) { - struct cachefiles_object *object; struct cachefiles_cache *cache; const struct cred *saved_cred; struct path path; uint64_t ni_size; int ret; - object = container_of(_object, struct cachefiles_object, fscache); - cache = container_of(object->fscache.cache, - struct cachefiles_cache, cache); + cache = container_of(object->cache, struct cachefiles_cache, cache); - ni_size = object->fscache.cookie->object_size; + ni_size = object->cookie->object_size; _enter("{OBJ%x},[%llu]", - object->fscache.debug_id, (unsigned long long)ni_size); + object->debug_id, (unsigned long long)ni_size); if (object->dentry) { ASSERT(d_is_reg(object->dentry)); diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index 9f2f837027e0..f268495ecbc6 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -29,21 +29,6 @@ extern unsigned cachefiles_debug; #define cachefiles_gfp (__GFP_RECLAIM | __GFP_NORETRY | __GFP_NOMEMALLOC) -/* - * node records - */ -struct cachefiles_object { - struct fscache_object fscache; /* fscache handle */ - char *d_name; /* Filename */ - struct dentry *dentry; /* the file/dir representing this object */ - loff_t i_size; /* object size */ - atomic_t usage; /* object usage count */ - uint8_t type; /* object type */ - bool new; /* T if object new */ - u8 d_name_len; /* Length of filename */ - u8 key_hash; -}; - extern struct kmem_cache *cachefiles_object_jar; /* @@ -114,7 +99,7 @@ extern int cachefiles_has_space(struct cachefiles_cache *cache, */ extern const struct fscache_cache_ops cachefiles_cache_ops; -void cachefiles_put_object(struct fscache_object *_object, +void cachefiles_put_object(struct cachefiles_object *_object, enum fscache_obj_ref_trace why); /* @@ -191,7 +176,7 @@ do { \ do { \ struct cachefiles_cache *___cache; \ \ - ___cache = container_of((object)->fscache.cache, \ + ___cache = container_of((object)->cache, \ struct cachefiles_cache, cache); \ cachefiles_io_error(___cache, FMT, ##__VA_ARGS__); \ } while (0) diff --git a/fs/cachefiles/key.c b/fs/cachefiles/key.c index 56a9b3201b41..ccadbc4776f1 100644 --- a/fs/cachefiles/key.c +++ b/fs/cachefiles/key.c @@ -31,8 +31,8 @@ static const char cachefiles_filecharmap[256] = { */ bool cachefiles_cook_key(struct cachefiles_object *object) { - const u8 *key = fscache_get_key(object->fscache.cookie); - unsigned int acc, sum, keylen = object->fscache.cookie->key_len; + const u8 *key = fscache_get_key(object->cookie); + unsigned int acc, sum, keylen = object->cookie->key_len; char *name; u8 *buffer, *p; int i, len, elem3, print; @@ -57,7 +57,7 @@ bool cachefiles_cook_key(struct cachefiles_object *object) if (!name) return false; - switch (object->fscache.cookie->type) { + switch (object->cookie->type) { case FSCACHE_COOKIE_TYPE_INDEX: type = 'I'; break; case FSCACHE_COOKIE_TYPE_DATAFILE: type = 'D'; break; default: type = 'S'; break; @@ -97,7 +97,7 @@ bool cachefiles_cook_key(struct cachefiles_object *object) return false; } - switch (object->fscache.cookie->type) { + switch (object->cookie->type) { case FSCACHE_COOKIE_TYPE_INDEX: type = 'J'; break; case FSCACHE_COOKIE_TYPE_DATAFILE: type = 'E'; break; default: type = 'T'; break; diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 7f02fcb34b1e..d3903cbb7de3 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -29,7 +29,7 @@ static bool cachefiles_mark_inode_in_use(struct cachefiles_object *object) struct inode *inode = d_backing_inode(dentry); bool can_use = false; - _enter(",%x", object->fscache.debug_id); + _enter(",%x", object->debug_id); inode_lock(inode); @@ -235,7 +235,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache, struct dentry *dir; int ret; - _enter(",OBJ%x{%pd}", object->fscache.debug_id, object->dentry); + _enter(",OBJ%x{%pd}", object->debug_id, object->dentry); ASSERT(object->dentry); ASSERT(d_backing_inode(object->dentry)); @@ -350,11 +350,11 @@ static int cachefiles_walk_to_file(struct cachefiles_cache *cache, /* This element of the path doesn't exist, so we can release * any readers in the certain knowledge that there's nothing * for them to actually read */ - fscache_object_lookup_negative(&object->fscache); + fscache_object_lookup_negative(object); ret = cachefiles_has_space(cache, 1, 0); if (ret < 0) { - fscache_object_mark_killed(&object->fscache, FSCACHE_OBJECT_NO_SPACE); + fscache_object_mark_killed(object, FSCACHE_OBJECT_NO_SPACE); goto error_dput; } @@ -423,11 +423,10 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, int ret; _enter("OBJ%x{%pd},OBJ%x,%s,", - parent->fscache.debug_id, parent->dentry, - object->fscache.debug_id, object->d_name); + parent->debug_id, parent->dentry, + object->debug_id, object->d_name); - cache = container_of(parent->fscache.cache, - struct cachefiles_cache, cache); + cache = container_of(parent->cache, struct cachefiles_cache, cache); ASSERT(parent->dentry); ASSERT(d_backing_inode(parent->dentry)); @@ -460,7 +459,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, goto check_error; object->new = false; - fscache_obtained_object(&object->fscache); + fscache_obtained_object(object); _leave(" = 0 [%lu]", d_backing_inode(object->dentry)->i_ino); return 0; @@ -468,7 +467,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, if (ret == -ESTALE) { dput(object->dentry); object->dentry = NULL; - fscache_object_retrying_stale(&object->fscache); + fscache_object_retrying_stale(object); goto lookup_again; } if (ret == -EIO) @@ -514,7 +513,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, * any readers in the certain knowledge that there's nothing * for them to actually read */ if (object) - fscache_object_lookup_negative(&object->fscache); + fscache_object_lookup_negative(object); ret = cachefiles_has_space(cache, 1, 0); if (ret < 0) diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c index 8b9f30f9ce21..464dea0b467c 100644 --- a/fs/cachefiles/xattr.c +++ b/fs/cachefiles/xattr.c @@ -31,23 +31,23 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object, { struct cachefiles_xattr *buf; struct dentry *dentry = object->dentry; - unsigned int len = object->fscache.cookie->aux_len; + unsigned int len = object->cookie->aux_len; int ret; if (!dentry) return -ESTALE; - _enter("%x,#%d", object->fscache.debug_id, len); + _enter("%x,#%d", object->debug_id, len); buf = kmalloc(sizeof(struct cachefiles_xattr) + len, GFP_KERNEL); if (!buf) return -ENOMEM; - buf->type = object->fscache.cookie->type; + buf->type = object->cookie->type; if (len > 0) - memcpy(buf->data, fscache_get_aux(object->fscache.cookie), len); + memcpy(buf->data, fscache_get_aux(object->cookie), len); - clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags); + clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->cookie->flags); ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache, buf, sizeof(struct cachefiles_xattr) + len, xattr_flags); @@ -68,8 +68,8 @@ int cachefiles_check_auxdata(struct cachefiles_object *object) { struct cachefiles_xattr *buf; struct dentry *dentry = object->dentry; - unsigned int len = object->fscache.cookie->aux_len, tlen; - const void *p = fscache_get_aux(object->fscache.cookie); + unsigned int len = object->cookie->aux_len, tlen; + const void *p = fscache_get_aux(object->cookie); ssize_t ret; ASSERT(dentry); @@ -82,7 +82,7 @@ int cachefiles_check_auxdata(struct cachefiles_object *object) ret = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, buf, tlen); if (ret == tlen && - buf->type == object->fscache.cookie->type && + buf->type == object->cookie->type && memcmp(buf->data, p, len) == 0) ret = 0; else diff --git a/fs/fscache/cache.c b/fs/fscache/cache.c index efcd834d6279..8a3191a89c32 100644 --- a/fs/fscache/cache.c +++ b/fs/fscache/cache.c @@ -93,7 +93,7 @@ struct fscache_cache *fscache_select_cache_for_object( struct fscache_cookie *cookie) { struct fscache_cache_tag *tag; - struct fscache_object *object; + struct cachefiles_object *object; struct fscache_cache *cache; _enter(""); @@ -110,7 +110,7 @@ struct fscache_cache *fscache_select_cache_for_object( * cache */ if (!hlist_empty(&cookie->backing_objects)) { object = hlist_entry(cookie->backing_objects.first, - struct fscache_object, cookie_link); + struct cachefiles_object, cookie_link); cache = object->cache; if (fscache_object_is_dying(object) || @@ -200,7 +200,7 @@ EXPORT_SYMBOL(fscache_init_cache); * description. */ int fscache_add_cache(struct fscache_cache *cache, - struct fscache_object *ifsdef, + struct cachefiles_object *ifsdef, const char *tagname) { struct fscache_cache_tag *tag; @@ -313,14 +313,14 @@ EXPORT_SYMBOL(fscache_io_error); static void fscache_withdraw_all_objects(struct fscache_cache *cache, struct list_head *dying_objects) { - struct fscache_object *object; + struct cachefiles_object *object; while (!list_empty(&cache->object_list)) { spin_lock(&cache->object_list_lock); if (!list_empty(&cache->object_list)) { object = list_entry(cache->object_list.next, - struct fscache_object, cache_link); + struct cachefiles_object, cache_link); list_move_tail(&object->cache_link, dying_objects); _debug("withdraw %x", object->cookie->debug_id); diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 0dc27f82e910..3f7bb2eecdc3 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -26,11 +26,11 @@ static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie); static int fscache_alloc_object(struct fscache_cache *cache, struct fscache_cookie *cookie); static int fscache_attach_object(struct fscache_cookie *cookie, - struct fscache_object *object); + struct cachefiles_object *object); static void fscache_print_cookie(struct fscache_cookie *cookie, char prefix) { - struct fscache_object *object; + struct cachefiles_object *object; struct hlist_node *o; const u8 *k; unsigned loop; @@ -48,7 +48,7 @@ static void fscache_print_cookie(struct fscache_cookie *cookie, char prefix) o = READ_ONCE(cookie->backing_objects.first); if (o) { - object = hlist_entry(o, struct fscache_object, cookie_link); + object = hlist_entry(o, struct cachefiles_object, cookie_link); pr_err("%c-cookie o=%u\n", prefix, object->debug_id); } @@ -396,7 +396,7 @@ EXPORT_SYMBOL(__fscache_enable_cookie); */ static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie) { - struct fscache_object *object; + struct cachefiles_object *object; struct fscache_cache *cache; int ret; @@ -443,7 +443,7 @@ static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie) } object = hlist_entry(cookie->backing_objects.first, - struct fscache_object, cookie_link); + struct cachefiles_object, cookie_link); /* initiate the process of looking up all the objects in the chain * (done by fscache_initialise_object()) */ @@ -476,7 +476,7 @@ static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie) static int fscache_alloc_object(struct fscache_cache *cache, struct fscache_cookie *cookie) { - struct fscache_object *object; + struct cachefiles_object *object; int ret; _enter("%s,%x{%s}", cache->tag->name, cookie->debug_id, cookie->type_name); @@ -548,9 +548,9 @@ static int fscache_alloc_object(struct fscache_cache *cache, * attach a cache object to a cookie */ static int fscache_attach_object(struct fscache_cookie *cookie, - struct fscache_object *object) + struct cachefiles_object *object) { - struct fscache_object *p; + struct cachefiles_object *p; struct fscache_cache *cache = object->cache; int ret; @@ -648,7 +648,7 @@ EXPORT_SYMBOL(__fscache_wait_on_invalidate); */ void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data) { - struct fscache_object *object; + struct cachefiles_object *object; fscache_stat(&fscache_n_updates); @@ -686,7 +686,7 @@ void __fscache_disable_cookie(struct fscache_cookie *cookie, const void *aux_data, bool invalidate) { - struct fscache_object *object; + struct cachefiles_object *object; bool awaken = false; _enter("%x,%u", cookie->debug_id, invalidate); diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index e78ca3151e41..eefcb6dfee3e 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h @@ -106,7 +106,7 @@ static inline bool fscache_object_congested(void) /* * object.c */ -extern void fscache_enqueue_object(struct fscache_object *); +extern void fscache_enqueue_object(struct cachefiles_object *); /* * proc.c @@ -227,7 +227,7 @@ int fscache_stats_show(struct seq_file *m, void *v); * - if the event is not masked for that object, then the object is * queued for attention by the thread pool. */ -static inline void fscache_raise_event(struct fscache_object *object, +static inline void fscache_raise_event(struct cachefiles_object *object, unsigned event) { BUG_ON(event >= NR_FSCACHE_OBJECT_EVENTS); diff --git a/fs/fscache/object.c b/fs/fscache/object.c index 761d6dc4aa0f..e653d0194f71 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c @@ -14,19 +14,19 @@ #include #include "internal.h" -static const struct fscache_state *fscache_abort_initialisation(struct fscache_object *, int); -static const struct fscache_state *fscache_kill_dependents(struct fscache_object *, int); -static const struct fscache_state *fscache_drop_object(struct fscache_object *, int); -static const struct fscache_state *fscache_initialise_object(struct fscache_object *, int); -static const struct fscache_state *fscache_invalidate_object(struct fscache_object *, int); -static const struct fscache_state *fscache_jumpstart_dependents(struct fscache_object *, int); -static const struct fscache_state *fscache_kill_object(struct fscache_object *, int); -static const struct fscache_state *fscache_lookup_failure(struct fscache_object *, int); -static const struct fscache_state *fscache_look_up_object(struct fscache_object *, int); -static const struct fscache_state *fscache_object_available(struct fscache_object *, int); -static const struct fscache_state *fscache_parent_ready(struct fscache_object *, int); -static const struct fscache_state *fscache_update_object(struct fscache_object *, int); -static const struct fscache_state *fscache_object_dead(struct fscache_object *, int); +static const struct fscache_state *fscache_abort_initialisation(struct cachefiles_object *, int); +static const struct fscache_state *fscache_kill_dependents(struct cachefiles_object *, int); +static const struct fscache_state *fscache_drop_object(struct cachefiles_object *, int); +static const struct fscache_state *fscache_initialise_object(struct cachefiles_object *, int); +static const struct fscache_state *fscache_invalidate_object(struct cachefiles_object *, int); +static const struct fscache_state *fscache_jumpstart_dependents(struct cachefiles_object *, int); +static const struct fscache_state *fscache_kill_object(struct cachefiles_object *, int); +static const struct fscache_state *fscache_lookup_failure(struct cachefiles_object *, int); +static const struct fscache_state *fscache_look_up_object(struct cachefiles_object *, int); +static const struct fscache_state *fscache_object_available(struct cachefiles_object *, int); +static const struct fscache_state *fscache_parent_ready(struct cachefiles_object *, int); +static const struct fscache_state *fscache_update_object(struct cachefiles_object *, int); +static const struct fscache_state *fscache_object_dead(struct cachefiles_object *, int); #define __STATE_NAME(n) fscache_osm_##n #define STATE(n) (&__STATE_NAME(n)) @@ -133,21 +133,21 @@ static const struct fscache_transition fscache_osm_run_oob[] = { { 0, NULL } }; -static int fscache_get_object(struct fscache_object *, +static int fscache_get_object(struct cachefiles_object *, enum fscache_obj_ref_trace); -static void fscache_put_object(struct fscache_object *, +static void fscache_put_object(struct cachefiles_object *, enum fscache_obj_ref_trace); -static bool fscache_enqueue_dependents(struct fscache_object *, int); -static void fscache_dequeue_object(struct fscache_object *); -static void fscache_update_aux_data(struct fscache_object *); +static bool fscache_enqueue_dependents(struct cachefiles_object *, int); +static void fscache_dequeue_object(struct cachefiles_object *); +static void fscache_update_aux_data(struct cachefiles_object *); /* * we need to notify the parent when an op completes that we had outstanding * upon it */ -static inline void fscache_done_parent_op(struct fscache_object *object) +static inline void fscache_done_parent_op(struct cachefiles_object *object) { - struct fscache_object *parent = object->parent; + struct cachefiles_object *parent = object->parent; _enter("OBJ%x {OBJ%x,%x}", object->debug_id, parent->debug_id, parent->n_ops); @@ -163,7 +163,7 @@ static inline void fscache_done_parent_op(struct fscache_object *object) /* * Object state machine dispatcher. */ -static void fscache_object_sm_dispatcher(struct fscache_object *object) +static void fscache_object_sm_dispatcher(struct cachefiles_object *object) { const struct fscache_transition *t; const struct fscache_state *state, *new_state; @@ -274,8 +274,8 @@ static void fscache_object_sm_dispatcher(struct fscache_object *object) */ static void fscache_object_work_func(struct work_struct *work) { - struct fscache_object *object = - container_of(work, struct fscache_object, work); + struct cachefiles_object *object = + container_of(work, struct cachefiles_object, work); _enter("{OBJ%x}", object->debug_id); @@ -294,7 +294,7 @@ static void fscache_object_work_func(struct work_struct *work) * See Documentation/filesystems/caching/backend-api.rst for a complete * description. */ -void fscache_object_init(struct fscache_object *object, +void fscache_object_init(struct cachefiles_object *object, struct fscache_cookie *cookie, struct fscache_cache *cache) { @@ -335,7 +335,7 @@ EXPORT_SYMBOL(fscache_object_init); * Mark the object as no longer being live, making sure that we synchronise * against op submission. */ -static inline void fscache_mark_object_dead(struct fscache_object *object) +static inline void fscache_mark_object_dead(struct cachefiles_object *object) { spin_lock(&object->lock); clear_bit(FSCACHE_OBJECT_IS_LIVE, &object->flags); @@ -345,7 +345,7 @@ static inline void fscache_mark_object_dead(struct fscache_object *object) /* * Abort object initialisation before we start it. */ -static const struct fscache_state *fscache_abort_initialisation(struct fscache_object *object, +static const struct fscache_state *fscache_abort_initialisation(struct cachefiles_object *object, int event) { _enter("{OBJ%x},%d", object->debug_id, event); @@ -362,10 +362,10 @@ static const struct fscache_state *fscache_abort_initialisation(struct fscache_o * - we may need to start the process of creating a parent and we need to wait * for the parent's lookup and creation to complete if it's not there yet */ -static const struct fscache_state *fscache_initialise_object(struct fscache_object *object, +static const struct fscache_state *fscache_initialise_object(struct cachefiles_object *object, int event) { - struct fscache_object *parent; + struct cachefiles_object *parent; bool success; _enter("{OBJ%x},%d", object->debug_id, event); @@ -417,10 +417,10 @@ static const struct fscache_state *fscache_initialise_object(struct fscache_obje /* * Once the parent object is ready, we should kick off our lookup op. */ -static const struct fscache_state *fscache_parent_ready(struct fscache_object *object, +static const struct fscache_state *fscache_parent_ready(struct cachefiles_object *object, int event) { - struct fscache_object *parent = object->parent; + struct cachefiles_object *parent = object->parent; _enter("{OBJ%x},%d", object->debug_id, event); @@ -440,11 +440,11 @@ static const struct fscache_state *fscache_parent_ready(struct fscache_object *o * - we hold an "access lock" on the parent object, so the parent object cannot * be withdrawn by either party till we've finished */ -static const struct fscache_state *fscache_look_up_object(struct fscache_object *object, +static const struct fscache_state *fscache_look_up_object(struct cachefiles_object *object, int event) { struct fscache_cookie *cookie = object->cookie; - struct fscache_object *parent = object->parent; + struct cachefiles_object *parent = object->parent; int ret; _enter("{OBJ%x},%d", object->debug_id, event); @@ -499,7 +499,7 @@ static const struct fscache_state *fscache_look_up_object(struct fscache_object * Note negative lookup, permitting those waiting to read data from an already * existing backing object to continue as there's no data for them to read. */ -void fscache_object_lookup_negative(struct fscache_object *object) +void fscache_object_lookup_negative(struct cachefiles_object *object) { struct fscache_cookie *cookie = object->cookie; @@ -531,7 +531,7 @@ EXPORT_SYMBOL(fscache_object_lookup_negative); * Note that after calling this, an object's cookie may be relinquished by the * netfs, and so must be accessed with object lock held. */ -void fscache_obtained_object(struct fscache_object *object) +void fscache_obtained_object(struct cachefiles_object *object) { struct fscache_cookie *cookie = object->cookie; @@ -563,7 +563,7 @@ EXPORT_SYMBOL(fscache_obtained_object); /* * handle an object that has just become available */ -static const struct fscache_state *fscache_object_available(struct fscache_object *object, +static const struct fscache_state *fscache_object_available(struct cachefiles_object *object, int event) { _enter("{OBJ%x},%d", object->debug_id, event); @@ -588,7 +588,7 @@ static const struct fscache_state *fscache_object_available(struct fscache_objec /* * Wake up this object's dependent objects now that we've become available. */ -static const struct fscache_state *fscache_jumpstart_dependents(struct fscache_object *object, +static const struct fscache_state *fscache_jumpstart_dependents(struct cachefiles_object *object, int event) { _enter("{OBJ%x},%d", object->debug_id, event); @@ -601,7 +601,7 @@ static const struct fscache_state *fscache_jumpstart_dependents(struct fscache_o /* * Handle lookup or creation failute. */ -static const struct fscache_state *fscache_lookup_failure(struct fscache_object *object, +static const struct fscache_state *fscache_lookup_failure(struct cachefiles_object *object, int event) { struct fscache_cookie *cookie; @@ -629,7 +629,7 @@ static const struct fscache_state *fscache_lookup_failure(struct fscache_object * Wait for completion of all active operations on this object and the death of * all child objects of this object. */ -static const struct fscache_state *fscache_kill_object(struct fscache_object *object, +static const struct fscache_state *fscache_kill_object(struct cachefiles_object *object, int event) { _enter("{OBJ%x,%d,%d},%d", @@ -652,7 +652,7 @@ static const struct fscache_state *fscache_kill_object(struct fscache_object *ob /* * Kill dependent objects. */ -static const struct fscache_state *fscache_kill_dependents(struct fscache_object *object, +static const struct fscache_state *fscache_kill_dependents(struct cachefiles_object *object, int event) { _enter("{OBJ%x},%d", object->debug_id, event); @@ -665,10 +665,10 @@ static const struct fscache_state *fscache_kill_dependents(struct fscache_object /* * Drop an object's attachments */ -static const struct fscache_state *fscache_drop_object(struct fscache_object *object, +static const struct fscache_state *fscache_drop_object(struct cachefiles_object *object, int event) { - struct fscache_object *parent = object->parent; + struct cachefiles_object *parent = object->parent; struct fscache_cookie *cookie = object->cookie; struct fscache_cache *cache = object->cache; bool awaken = false; @@ -738,7 +738,7 @@ static const struct fscache_state *fscache_drop_object(struct fscache_object *ob /* * get a ref on an object */ -static int fscache_get_object(struct fscache_object *object, +static int fscache_get_object(struct cachefiles_object *object, enum fscache_obj_ref_trace why) { int ret; @@ -752,7 +752,7 @@ static int fscache_get_object(struct fscache_object *object, /* * Discard a ref on an object */ -static void fscache_put_object(struct fscache_object *object, +static void fscache_put_object(struct cachefiles_object *object, enum fscache_obj_ref_trace why) { fscache_stat(&fscache_n_cop_put_object); @@ -766,7 +766,7 @@ static void fscache_put_object(struct fscache_object *object, * * Note the imminent destruction and deallocation of a cache object record. */ -void fscache_object_destroy(struct fscache_object *object) +void fscache_object_destroy(struct cachefiles_object *object) { /* We can get rid of the cookie now */ fscache_put_cookie(object->cookie, fscache_cookie_put_object); @@ -777,7 +777,7 @@ EXPORT_SYMBOL(fscache_object_destroy); /* * enqueue an object for metadata-type processing */ -void fscache_enqueue_object(struct fscache_object *object) +void fscache_enqueue_object(struct cachefiles_object *object) { _enter("{OBJ%x}", object->debug_id); @@ -831,9 +831,9 @@ EXPORT_SYMBOL_GPL(fscache_object_sleep_till_congested); * again then return false immediately. We return true if the list was * cleared. */ -static bool fscache_enqueue_dependents(struct fscache_object *object, int event) +static bool fscache_enqueue_dependents(struct cachefiles_object *object, int event) { - struct fscache_object *dep; + struct cachefiles_object *dep; bool ret = true; _enter("{OBJ%x}", object->debug_id); @@ -845,7 +845,7 @@ static bool fscache_enqueue_dependents(struct fscache_object *object, int event) while (!list_empty(&object->dependents)) { dep = list_entry(object->dependents.next, - struct fscache_object, dep_link); + struct cachefiles_object, dep_link); list_del_init(&dep->dep_link); fscache_raise_event(dep, event); @@ -864,7 +864,7 @@ static bool fscache_enqueue_dependents(struct fscache_object *object, int event) /* * remove an object from whatever queue it's waiting on */ -static void fscache_dequeue_object(struct fscache_object *object) +static void fscache_dequeue_object(struct cachefiles_object *object) { _enter("{OBJ%x}", object->debug_id); @@ -877,7 +877,7 @@ static void fscache_dequeue_object(struct fscache_object *object) _leave(""); } -static const struct fscache_state *fscache_invalidate_object(struct fscache_object *object, +static const struct fscache_state *fscache_invalidate_object(struct cachefiles_object *object, int event) { return transit_to(UPDATE_OBJECT); @@ -886,7 +886,7 @@ static const struct fscache_state *fscache_invalidate_object(struct fscache_obje /* * Update auxiliary data. */ -static void fscache_update_aux_data(struct fscache_object *object) +static void fscache_update_aux_data(struct cachefiles_object *object) { fscache_stat(&fscache_n_updates_run); fscache_stat(&fscache_n_cop_update_object); @@ -897,7 +897,7 @@ static void fscache_update_aux_data(struct fscache_object *object) /* * Asynchronously update an object. */ -static const struct fscache_state *fscache_update_object(struct fscache_object *object, +static const struct fscache_state *fscache_update_object(struct cachefiles_object *object, int event) { _enter("{OBJ%x},%d", object->debug_id, event); @@ -915,7 +915,7 @@ static const struct fscache_state *fscache_update_object(struct fscache_object * * Note that an object lookup found an on-disk object that was adjudged to be * stale and has been deleted. The lookup will be retried. */ -void fscache_object_retrying_stale(struct fscache_object *object) +void fscache_object_retrying_stale(struct cachefiles_object *object) { fscache_stat(&fscache_n_cache_no_space_reject); } @@ -929,7 +929,7 @@ EXPORT_SYMBOL(fscache_object_retrying_stale); * Note that an object was killed. Returns true if the object was * already marked killed, false if it wasn't. */ -void fscache_object_mark_killed(struct fscache_object *object, +void fscache_object_mark_killed(struct cachefiles_object *object, enum fscache_why_object_killed why) { if (test_and_set_bit(FSCACHE_OBJECT_KILLED_BY_CACHE, &object->flags)) { @@ -961,7 +961,7 @@ EXPORT_SYMBOL(fscache_object_mark_killed); * already running (and so can be requeued) but hasn't yet cleared the event * mask. */ -static const struct fscache_state *fscache_object_dead(struct fscache_object *object, +static const struct fscache_state *fscache_object_dead(struct cachefiles_object *object, int event) { if (!test_and_set_bit(FSCACHE_OBJECT_RUN_AFTER_DEAD, diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index 0439dc3021c7..7021c1ec2b64 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -22,7 +22,7 @@ struct fscache_cache; struct fscache_cache_ops; -struct fscache_object; +struct cachefiles_object; enum fscache_cookie_trace; enum fscache_obj_ref_trace { @@ -65,7 +65,7 @@ struct fscache_cache { struct list_head object_list; /* list of data/index objects */ spinlock_t object_list_lock; atomic_t object_count; /* no. of live objects in this cache */ - struct fscache_object *fsdef; /* object for the fsdef index */ + struct cachefiles_object *fsdef; /* object for the fsdef index */ unsigned long flags; #define FSCACHE_IOERROR 0 /* cache stopped on I/O error */ #define FSCACHE_CACHE_WITHDRAWN 1 /* cache has been withdrawn */ @@ -81,46 +81,46 @@ struct fscache_cache_ops { const char *name; /* allocate an object record for a cookie */ - struct fscache_object *(*alloc_object)(struct fscache_cache *cache, + struct cachefiles_object *(*alloc_object)(struct fscache_cache *cache, struct fscache_cookie *cookie); /* look up the object for a cookie * - return -ETIMEDOUT to be requeued */ - int (*lookup_object)(struct fscache_object *object); + int (*lookup_object)(struct cachefiles_object *object); /* finished looking up */ - void (*lookup_complete)(struct fscache_object *object); + void (*lookup_complete)(struct cachefiles_object *object); /* increment the usage count on this object (may fail if unmounting) */ - struct fscache_object *(*grab_object)(struct fscache_object *object, + struct cachefiles_object *(*grab_object)(struct cachefiles_object *object, enum fscache_obj_ref_trace why); /* pin an object in the cache */ - int (*pin_object)(struct fscache_object *object); + int (*pin_object)(struct cachefiles_object *object); /* unpin an object in the cache */ - void (*unpin_object)(struct fscache_object *object); + void (*unpin_object)(struct cachefiles_object *object); /* store the updated auxiliary data on an object */ - void (*update_object)(struct fscache_object *object); + void (*update_object)(struct cachefiles_object *object); /* Invalidate an object */ - void (*invalidate_object)(struct fscache_object *object); + void (*invalidate_object)(struct cachefiles_object *object); /* discard the resources pinned by an object and effect retirement if * necessary */ - void (*drop_object)(struct fscache_object *object); + void (*drop_object)(struct cachefiles_object *object); /* dispose of a reference to an object */ - void (*put_object)(struct fscache_object *object, + void (*put_object)(struct cachefiles_object *object, enum fscache_obj_ref_trace why); /* sync a cache */ void (*sync_cache)(struct fscache_cache *cache); /* reserve space for an object's data and associated metadata */ - int (*reserve_space)(struct fscache_object *object, loff_t i_size); + int (*reserve_space)(struct cachefiles_object *object, loff_t i_size); /* Begin an operation for the netfs lib */ int (*begin_operation)(struct netfs_cache_resources *cres); @@ -155,7 +155,7 @@ struct fscache_transition { struct fscache_state { char name[24]; char short_name[8]; - const struct fscache_state *(*work)(struct fscache_object *object, + const struct fscache_state *(*work)(struct cachefiles_object *object, int event); const struct fscache_transition transitions[]; }; @@ -163,7 +163,7 @@ struct fscache_state { /* * on-disk cache file or index handle */ -struct fscache_object { +struct cachefiles_object { const struct fscache_state *state; /* Object state machine state */ const struct fscache_transition *oob_table; /* OOB state transition table */ int debug_id; /* debugging ID */ @@ -192,40 +192,49 @@ struct fscache_object { struct hlist_node cookie_link; /* link in cookie->backing_objects */ struct fscache_cache *cache; /* cache that supplied this object */ struct fscache_cookie *cookie; /* netfs's file/index object */ - struct fscache_object *parent; /* parent object */ + struct cachefiles_object *parent; /* parent object */ struct work_struct work; /* attention scheduling record */ struct list_head dependents; /* FIFO of dependent objects */ struct list_head dep_link; /* link in parent's dependents list */ + + char *d_name; /* Filename */ + struct dentry *dentry; /* the file/dir representing this object */ + loff_t i_size; /* object size */ + atomic_t usage; /* object usage count */ + uint8_t type; /* object type */ + bool new; /* T if object new */ + u8 d_name_len; /* Length of filename */ + u8 key_hash; }; -extern void fscache_object_init(struct fscache_object *, struct fscache_cookie *, +extern void fscache_object_init(struct cachefiles_object *, struct fscache_cookie *, struct fscache_cache *); -extern void fscache_object_destroy(struct fscache_object *); +extern void fscache_object_destroy(struct cachefiles_object *); -extern void fscache_object_lookup_negative(struct fscache_object *object); -extern void fscache_obtained_object(struct fscache_object *object); +extern void fscache_object_lookup_negative(struct cachefiles_object *object); +extern void fscache_obtained_object(struct cachefiles_object *object); -static inline bool fscache_object_is_live(struct fscache_object *object) +static inline bool fscache_object_is_live(struct cachefiles_object *object) { return test_bit(FSCACHE_OBJECT_IS_LIVE, &object->flags); } -static inline bool fscache_object_is_dying(struct fscache_object *object) +static inline bool fscache_object_is_dying(struct cachefiles_object *object) { return !fscache_object_is_live(object); } -static inline bool fscache_object_is_available(struct fscache_object *object) +static inline bool fscache_object_is_available(struct cachefiles_object *object) { return test_bit(FSCACHE_OBJECT_IS_AVAILABLE, &object->flags); } -static inline bool fscache_cache_is_broken(struct fscache_object *object) +static inline bool fscache_cache_is_broken(struct cachefiles_object *object) { return test_bit(FSCACHE_IOERROR, &object->cache->flags); } -static inline bool fscache_object_is_active(struct fscache_object *object) +static inline bool fscache_object_is_active(struct cachefiles_object *object) { return fscache_object_is_available(object) && fscache_object_is_live(object) && @@ -251,7 +260,7 @@ static inline void fscache_object_destroyed(struct fscache_cache *cache) * Note that an object encountered a fatal error (usually an I/O error) and * that it should be withdrawn as soon as possible. */ -static inline void fscache_object_lookup_error(struct fscache_object *object) +static inline void fscache_object_lookup_error(struct cachefiles_object *object) { set_bit(FSCACHE_OBJECT_EV_ERROR, &object->events); } @@ -268,7 +277,7 @@ static inline void __fscache_use_cookie(struct fscache_cookie *cookie) * Request usage of the cookie attached to an object. NULL is returned if the * relinquishment had reduced the cookie usage count to 0. */ -static inline bool fscache_use_cookie(struct fscache_object *object) +static inline bool fscache_use_cookie(struct cachefiles_object *object) { struct fscache_cookie *cookie = object->cookie; return atomic_inc_not_zero(&cookie->n_active) != 0; @@ -291,7 +300,7 @@ static inline void __fscache_wake_unused_cookie(struct fscache_cookie *cookie) * Cease usage of the cookie attached to an object. When the users count * reaches zero then the cookie relinquishment will be permitted to proceed. */ -static inline void fscache_unuse_cookie(struct fscache_object *object) +static inline void fscache_unuse_cookie(struct cachefiles_object *object) { struct fscache_cookie *cookie = object->cookie; if (__fscache_unuse_cookie(cookie)) @@ -307,7 +316,7 @@ void fscache_init_cache(struct fscache_cache *cache, const char *idfmt, ...); extern int fscache_add_cache(struct fscache_cache *cache, - struct fscache_object *fsdef, + struct cachefiles_object *fsdef, const char *tagname); extern void fscache_withdraw_cache(struct fscache_cache *cache); @@ -315,7 +324,7 @@ extern void fscache_io_error(struct fscache_cache *cache); extern bool fscache_object_sleep_till_congested(signed long *timeoutp); -extern void fscache_object_retrying_stale(struct fscache_object *object); +extern void fscache_object_retrying_stale(struct cachefiles_object *object); enum fscache_why_object_killed { FSCACHE_OBJECT_IS_STALE, @@ -323,7 +332,7 @@ enum fscache_why_object_killed { FSCACHE_OBJECT_WAS_RETIRED, FSCACHE_OBJECT_WAS_CULLED, }; -extern void fscache_object_mark_killed(struct fscache_object *object, +extern void fscache_object_mark_killed(struct cachefiles_object *object, enum fscache_why_object_killed why); extern struct fscache_cookie *fscache_get_cookie(struct fscache_cookie *cookie, diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h index 87681dd957ec..5aec097d51ae 100644 --- a/include/trace/events/cachefiles.h +++ b/include/trace/events/cachefiles.h @@ -85,7 +85,7 @@ TRACE_EVENT(cachefiles_ref, ), TP_fast_assign( - __entry->obj = obj->fscache.debug_id; + __entry->obj = obj->debug_id; __entry->cookie = cookie->debug_id; __entry->usage = usage; __entry->why = why; @@ -109,7 +109,7 @@ TRACE_EVENT(cachefiles_lookup, ), TP_fast_assign( - __entry->obj = obj->fscache.debug_id; + __entry->obj = obj->debug_id; __entry->ino = (!IS_ERR(de) && d_backing_inode(de) ? d_backing_inode(de)->i_ino : 0); __entry->error = IS_ERR(de) ? PTR_ERR(de) : 0; @@ -132,7 +132,7 @@ TRACE_EVENT(cachefiles_create, ), TP_fast_assign( - __entry->obj = obj->fscache.debug_id; + __entry->obj = obj->debug_id; __entry->de = de; __entry->ret = ret; ), @@ -156,7 +156,7 @@ TRACE_EVENT(cachefiles_unlink, ), TP_fast_assign( - __entry->obj = obj ? obj->fscache.debug_id : UINT_MAX; + __entry->obj = obj ? obj->debug_id : UINT_MAX; __entry->de = de; __entry->why = why; ), @@ -183,7 +183,7 @@ TRACE_EVENT(cachefiles_rename, ), TP_fast_assign( - __entry->obj = obj ? obj->fscache.debug_id : UINT_MAX; + __entry->obj = obj ? obj->debug_id : UINT_MAX; __entry->de = de; __entry->to = to; __entry->why = why; @@ -207,7 +207,7 @@ TRACE_EVENT(cachefiles_mark_active, ), TP_fast_assign( - __entry->obj = obj->fscache.debug_id; + __entry->obj = obj->debug_id; __entry->de = de; ), @@ -230,7 +230,7 @@ TRACE_EVENT(cachefiles_mark_inactive, ), TP_fast_assign( - __entry->obj = obj->fscache.debug_id; + __entry->obj = obj->debug_id; __entry->de = de; __entry->inode = inode; ), diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h index eac561d3ac51..412f016f6975 100644 --- a/include/trace/events/fscache.h +++ b/include/trace/events/fscache.h @@ -228,7 +228,7 @@ TRACE_EVENT(fscache_disable, ); TRACE_EVENT(fscache_osm, - TP_PROTO(struct fscache_object *object, + TP_PROTO(struct cachefiles_object *object, const struct fscache_state *state, bool wait, bool oob, s8 event_num), From patchwork Mon Oct 18 14:57:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566977 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 23C7DC433F5 for ; Mon, 18 Oct 2021 14:57:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0D3A761074 for ; Mon, 18 Oct 2021 14:57:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232860AbhJRO7x (ORCPT ); Mon, 18 Oct 2021 10:59:53 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:27726 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232978AbhJRO7k (ORCPT ); Mon, 18 Oct 2021 10:59:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569048; 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=uAB0lmzHxTBxFxXC1tk45FGe7+KmK5QRRpgwLjHh3T8=; b=LcdTzI8NIF+Xet/7pIO+7AGIHjCusuS81IAUllvG8F0uDV0QeSy8QyuAAdvbVUBjW7Lu0m pXShawiMcSUOrlLNjS42USMYCd0DtyOVFIeh1jDOSG02mL9bfSvPukqGGqqNOGlAGfQt7X k8IvIo3mbP/bBBBdhvE6drUTVBtpt/o= 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-136-I4Vx8zoNMYqEEg6v5JGNuw-1; Mon, 18 Oct 2021 10:57:27 -0400 X-MC-Unique: I4Vx8zoNMYqEEg6v5JGNuw-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 68BB48066F0; Mon, 18 Oct 2021 14:57:25 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1436E100E809; Mon, 18 Oct 2021 14:57:21 +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 26/67] cachefiles: Change to storing file* rather than dentry* From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:57:21 +0100 Message-ID: <163456904116.2614702.18059895913577688154.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Attempting to open an ext4 file while files are being closed by do_exit() results in an oops in ext4 because it uses d_path() which expects current->fs to point somewhere. This is a problem if I want to open a cache file in order to write out data to it from the writeback code. Mitigate this by opening a file right at the beginning and keeping it open, replacing it with a new file when invalidation occurs. This has the downside of keeping a bunch of file resources open. Signed-off-by: David Howells --- fs/cachefiles/bind.c | 17 +++- fs/cachefiles/interface.c | 41 +++++----- fs/cachefiles/internal.h | 6 ++ fs/cachefiles/io.c | 41 ++-------- fs/cachefiles/namei.c | 146 ++++++++++++++++++++++--------------- fs/cachefiles/xattr.c | 11 +-- include/linux/fscache-cache.h | 2 - include/trace/events/cachefiles.h | 25 +++--- 8 files changed, 151 insertions(+), 138 deletions(-) diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c index 8db1ef2d1196..af7386ad14af 100644 --- a/fs/cachefiles/bind.c +++ b/fs/cachefiles/bind.c @@ -82,6 +82,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) struct path path; struct kstatfs stats; struct dentry *graveyard, *cachedir, *root; + struct file *dirf; const struct cred *saved_cred; int ret; @@ -192,7 +193,13 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) goto error_unsupported; } - fsdef->dentry = cachedir; + dirf = open_with_fake_path(&path, O_RDONLY | O_DIRECTORY, + d_inode(cachedir), cache->cache_cred); + if (IS_ERR(dirf)) { + ret = PTR_ERR(dirf); + goto error_unsupported; + } + fsdef->file = dirf; fsdef->cookie = NULL; /* get the graveyard directory */ @@ -208,7 +215,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) fscache_init_cache(&cache->cache, &cachefiles_cache_ops, "%s", - fsdef->dentry->d_sb->s_id); + graveyard->d_sb->s_id); fscache_object_init(fsdef, &fscache_fsdef_index, &cache->cache); @@ -234,8 +241,10 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) error_unsupported: mntput(cache->mnt); cache->mnt = NULL; - dput(fsdef->dentry); - fsdef->dentry = NULL; + if (fsdef->file) { + fput(fsdef->file); + fsdef->file = NULL; + } dput(root); error_open_root: kmem_cache_free(cachefiles_object_jar, fsdef); diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 7ec2302a3214..4edb3a09932a 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -161,7 +161,7 @@ static void cachefiles_drop_object(struct cachefiles_object *object) * initialised if the parent goes away or the object gets retired * before we set it up. */ - if (object->dentry) { + if (object->file) { /* delete retired objects */ if (test_bit(FSCACHE_OBJECT_RETIRED, &object->flags) && object != cache->cache.fsdef @@ -174,8 +174,8 @@ static void cachefiles_drop_object(struct cachefiles_object *object) /* close the filesystem stuff attached to the object */ cachefiles_unmark_inode_in_use(object); - dput(object->dentry); - object->dentry = NULL; + fput(object->file); + object->file = NULL; } _leave(""); @@ -210,7 +210,7 @@ void cachefiles_put_object(struct cachefiles_object *object, _debug("- kill object OBJ%x", object->debug_id); ASSERTCMP(object->parent, ==, NULL); - ASSERTCMP(object->dentry, ==, NULL); + ASSERTCMP(object->file, ==, NULL); ASSERTCMP(object->n_ops, ==, 0); ASSERTCMP(object->n_children, ==, 0); @@ -262,6 +262,7 @@ static int cachefiles_attr_changed(struct cachefiles_object *object) struct cachefiles_cache *cache; const struct cred *saved_cred; struct iattr newattrs; + struct file *file = object->file; uint64_t ni_size; loff_t oi_size; int ret; @@ -271,20 +272,22 @@ static int cachefiles_attr_changed(struct cachefiles_object *object) _enter("{OBJ%x},[%llu]", object->debug_id, (unsigned long long) ni_size); - cache = container_of(object->cache, - struct cachefiles_cache, cache); + if (!file) + return -ENOBUFS; + + cache = container_of(object->cache, struct cachefiles_cache, cache); if (ni_size == object->i_size) return 0; - ASSERT(d_is_reg(object->dentry)); + ASSERT(d_is_reg(file->f_path.dentry)); - oi_size = i_size_read(d_backing_inode(object->dentry)); + oi_size = i_size_read(file_inode(file)); if (oi_size == ni_size) return 0; cachefiles_begin_secure(cache, &saved_cred); - inode_lock(d_inode(object->dentry)); + inode_lock(file_inode(file)); /* if there's an extension to a partial page at the end of the backing * file, we need to discard the partial page so that we pick up new @@ -293,17 +296,18 @@ static int cachefiles_attr_changed(struct cachefiles_object *object) _debug("discard tail %llx", oi_size); newattrs.ia_valid = ATTR_SIZE; newattrs.ia_size = oi_size & PAGE_MASK; - ret = notify_change(&init_user_ns, object->dentry, &newattrs, NULL); + ret = notify_change(&init_user_ns, file->f_path.dentry, + &newattrs, NULL); if (ret < 0) goto truncate_failed; } newattrs.ia_valid = ATTR_SIZE; newattrs.ia_size = ni_size; - ret = notify_change(&init_user_ns, object->dentry, &newattrs, NULL); + ret = notify_change(&init_user_ns, file->f_path.dentry, &newattrs, NULL); truncate_failed: - inode_unlock(d_inode(object->dentry)); + inode_unlock(file_inode(file)); cachefiles_end_secure(cache, saved_cred); if (ret == -EIO) { @@ -322,7 +326,7 @@ static void cachefiles_invalidate_object(struct cachefiles_object *object) { struct cachefiles_cache *cache; const struct cred *saved_cred; - struct path path; + struct file *file = object->file; uint64_t ni_size; int ret; @@ -333,16 +337,13 @@ static void cachefiles_invalidate_object(struct cachefiles_object *object) _enter("{OBJ%x},[%llu]", object->debug_id, (unsigned long long)ni_size); - if (object->dentry) { - ASSERT(d_is_reg(object->dentry)); - - path.dentry = object->dentry; - path.mnt = cache->mnt; + if (file) { + ASSERT(d_is_reg(file->f_path.dentry)); cachefiles_begin_secure(cache, &saved_cred); - ret = vfs_truncate(&path, 0); + ret = vfs_truncate(&file->f_path, 0); if (ret == 0) - ret = vfs_truncate(&path, ni_size); + ret = vfs_truncate(&file->f_path, ni_size); cachefiles_end_secure(cache, saved_cred); if (ret != 0) { diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index f268495ecbc6..4705f968e661 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -71,6 +71,12 @@ struct cachefiles_cache { #include +static inline +struct file *cachefiles_cres_file(struct netfs_cache_resources *cres) +{ + return cres->cache_priv2; +} + /* * note change of state for daemon */ diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index 920ca48eecfa..0e1fb44b5d04 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -63,7 +63,7 @@ static int cachefiles_read(struct netfs_cache_resources *cres, void *term_func_priv) { struct cachefiles_kiocb *ki; - struct file *file = cres->cache_priv2; + struct file *file = cachefiles_cres_file(cres); unsigned int old_nofs; ssize_t ret = -ENODATA; size_t len = iov_iter_count(iter), skipped = 0; @@ -190,7 +190,7 @@ static int cachefiles_write(struct netfs_cache_resources *cres, { struct cachefiles_kiocb *ki; struct inode *inode; - struct file *file = cres->cache_priv2; + struct file *file = cachefiles_cres_file(cres); unsigned int old_nofs; ssize_t ret = -ENOBUFS; size_t len = iov_iter_count(iter); @@ -385,7 +385,7 @@ static void cachefiles_end_operation(struct netfs_cache_resources *cres) { #if 0 struct fscache_operation *op = cres->cache_priv; - struct file *file = cres->cache_priv2; + struct file *file = cachefiles_cres_file(cres); _enter(""); @@ -414,41 +414,16 @@ static const struct netfs_cache_ops cachefiles_netfs_cache_ops = { int cachefiles_begin_operation(struct netfs_cache_resources *cres) { #if 0 - struct cachefiles_object *object; - struct cachefiles_cache *cache; - struct path path; - struct file *file; + struct cachefiles_object *object = op->object; _enter(""); - object = container_of(op->object, struct cachefiles_object, fscache); - cache = container_of(object->fscache.cache, - struct cachefiles_cache, cache); - - path.mnt = cache->mnt; - path.dentry = object->dentry; - file = open_with_fake_path(&path, O_RDWR | O_LARGEFILE | O_DIRECT, - d_inode(object->dentry), cache->cache_cred); - if (IS_ERR(file)) - return PTR_ERR(file); - if (!S_ISREG(file_inode(file)->i_mode)) - goto error_file; - if (unlikely(!file->f_op->read_iter) || - unlikely(!file->f_op->write_iter)) { - pr_notice("Cache does not support read_iter and write_iter\n"); - goto error_file; - } - - atomic_inc(&op->usage); - cres->cache_priv = op; - cres->cache_priv2 = file; - cres->ops = &cachefiles_netfs_cache_ops; - cres->debug_id = object->fscache.debug_id; + cres->cache_priv = op; + cres->cache_priv2 = get_file(object->file); + cres->ops = &cachefiles_netfs_cache_ops; + cres->debug_id = object->cookie->debug_id; _leave(""); return 0; - -error_file: - fput(file); #endif cres->ops = &cachefiles_netfs_cache_ops; return -EIO; diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index d3903cbb7de3..a60ef6f1cf1e 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -25,8 +25,7 @@ */ static bool cachefiles_mark_inode_in_use(struct cachefiles_object *object) { - struct dentry *dentry = object->dentry; - struct inode *inode = d_backing_inode(dentry); + struct inode *inode = file_inode(object->file); bool can_use = false; _enter(",%x", object->debug_id); @@ -35,10 +34,10 @@ static bool cachefiles_mark_inode_in_use(struct cachefiles_object *object) if (!(inode->i_flags & S_KERNEL_FILE)) { inode->i_flags |= S_KERNEL_FILE; - trace_cachefiles_mark_active(object, dentry); + trace_cachefiles_mark_active(object, inode); can_use = true; } else { - pr_notice("cachefiles: Inode already in use: %pd\n", dentry); + pr_notice("cachefiles: Inode already in use: %pD\n", object->file); } inode_unlock(inode); @@ -50,13 +49,12 @@ static bool cachefiles_mark_inode_in_use(struct cachefiles_object *object) */ void cachefiles_unmark_inode_in_use(struct cachefiles_object *object) { - struct dentry *dentry = object->dentry; - struct inode *inode = d_backing_inode(dentry); + struct inode *inode = file_inode(object->file); inode_lock(inode); inode->i_flags &= ~S_KERNEL_FILE; inode_unlock(inode); - trace_cachefiles_mark_inactive(object, dentry, inode); + trace_cachefiles_mark_inactive(object, inode); } /* @@ -65,7 +63,7 @@ void cachefiles_unmark_inode_in_use(struct cachefiles_object *object) static void cachefiles_mark_object_inactive(struct cachefiles_cache *cache, struct cachefiles_object *object) { - blkcnt_t i_blocks = d_backing_inode(object->dentry)->i_blocks; + blkcnt_t i_blocks = file_inode(object->file)->i_blocks; /* This object can now be culled, so we need to let the daemon know * that there is something it can remove if it needs to. @@ -106,7 +104,9 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, cachefiles_io_error(cache, "Unlink security error"); } else { trace_cachefiles_unlink(object, rep, why); - dget(rep); + dget(rep); /* Stop the dentry being negated if it's + * only pinned by a file struct. + */ ret = vfs_unlink(&init_user_ns, d_inode(dir), rep, NULL); dput(rep); } @@ -232,30 +232,29 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache, int cachefiles_delete_object(struct cachefiles_cache *cache, struct cachefiles_object *object) { - struct dentry *dir; + struct dentry *dentry = object->file->f_path.dentry, *dir; int ret; - _enter(",OBJ%x{%pd}", object->debug_id, object->dentry); + _enter(",OBJ%x{%pD}", object->debug_id, object->file); - ASSERT(object->dentry); - ASSERT(d_backing_inode(object->dentry)); - ASSERT(object->dentry->d_parent); + ASSERT(d_backing_inode(dentry)); + ASSERT(dentry->d_parent); - dir = dget_parent(object->dentry); + dir = dget_parent(dentry); - inode_lock_nested(d_inode(dir), I_MUTEX_PARENT); + inode_lock_nested(d_backing_inode(dir), I_MUTEX_PARENT); /* We need to check that our parent is _still_ our parent - it may have * been renamed. */ - if (dir == object->dentry->d_parent) { - ret = cachefiles_bury_object(cache, object, dir, object->dentry, + if (dir == dentry->d_parent) { + ret = cachefiles_bury_object(cache, object, dir, dentry, FSCACHE_OBJECT_WAS_RETIRED); } else { /* It got moved, presumably by cachefilesd culling it, so it's * no longer in the key path and we can ignore it. */ - inode_unlock(d_inode(dir)); + inode_unlock(d_backing_inode(dir)); ret = 0; } @@ -271,7 +270,6 @@ static int cachefiles_check_open_object(struct cachefiles_cache *cache, struct cachefiles_object *object, struct dentry *fan) { - struct path path; int ret; if (!cachefiles_mark_inode_in_use(object)) @@ -280,7 +278,7 @@ static int cachefiles_check_open_object(struct cachefiles_cache *cache, /* if we've found that the terminal object exists, then we need to * check its attributes and delete it if it's out of date */ if (!object->new) { - _debug("validate '%pd'", object->dentry); + _debug("validate '%pD'", object->file); ret = cachefiles_check_auxdata(object); if (ret == -ESTALE) @@ -301,9 +299,7 @@ static int cachefiles_check_open_object(struct cachefiles_cache *cache, * (this is used to keep track of culling, and atimes are only * updated by read, write and readdir but not lookup or * open) */ - path.mnt = cache->mnt; - path.dentry = object->dentry; - touch_atime(&path); + touch_atime(&object->file->f_path); } return 0; @@ -311,7 +307,8 @@ static int cachefiles_check_open_object(struct cachefiles_cache *cache, stale: cachefiles_unmark_inode_in_use(object); inode_lock_nested(d_inode(fan), I_MUTEX_PARENT); - ret = cachefiles_bury_object(cache, object, fan, object->dentry, + ret = cachefiles_bury_object(cache, object, fan, + object->file->f_path.dentry, FSCACHE_OBJECT_IS_STALE); if (ret < 0) return ret; @@ -326,13 +323,14 @@ static int cachefiles_check_open_object(struct cachefiles_cache *cache, /* * Walk to a file, creating it if necessary. */ -static int cachefiles_walk_to_file(struct cachefiles_cache *cache, - struct cachefiles_object *object, - struct dentry *fan) +static int cachefiles_open_file(struct cachefiles_cache *cache, + struct cachefiles_object *object, + struct dentry *fan) { struct dentry *dentry; - struct inode *dinode = d_backing_inode(fan); - struct path fan_path; + struct inode *dinode = d_backing_inode(fan), *inode; + struct file *file; + struct path fan_path, path; int ret; _enter("%pd %s", fan, object->d_name); @@ -343,7 +341,7 @@ static int cachefiles_walk_to_file(struct cachefiles_cache *cache, trace_cachefiles_lookup(object, dentry); if (IS_ERR(dentry)) { ret = PTR_ERR(dentry); - goto error; + goto error_unlock; } if (d_is_negative(dentry)) { @@ -368,34 +366,53 @@ static int cachefiles_walk_to_file(struct cachefiles_cache *cache, if (ret < 0) goto error_dput; - _debug("create -> %pd{ino=%lu}", - dentry, d_backing_inode(dentry)->i_ino); - object->new = true; + inode = d_backing_inode(dentry); + _debug("create -> %pd{ino=%lu}", dentry, inode->i_ino); } else if (!d_is_reg(dentry)) { - pr_err("inode %lu is not a file\n", - d_backing_inode(dentry)->i_ino); + inode = d_backing_inode(dentry); + pr_err("inode %lu is not a file\n", inode->i_ino); ret = -EIO; goto error_dput; } else { + inode = d_backing_inode(dentry); _debug("file -> %pd positive", dentry); } - if (dentry->d_sb->s_blocksize > PAGE_SIZE) { - pr_warn("cachefiles: Block size too large\n"); + inode_unlock(dinode); + + /* We need to open a file interface onto a data file now as we can't do + * it on demand because writeback called from do_exit() sees + * current->fs == NULL - which breaks d_path() called from ext4 open. + */ + path.mnt = cache->mnt; + path.dentry = dentry; + file = open_with_fake_path(&path, O_RDWR | O_LARGEFILE | O_DIRECT, + inode, cache->cache_cred); + dput(dentry); + if (IS_ERR(file)) { + ret = PTR_ERR(file); + goto error; + } + if (unlikely(!file->f_op->read_iter) || + unlikely(!file->f_op->write_iter)) { + pr_notice("Cache does not support read_iter and write_iter\n"); ret = -EIO; - goto error_dput; + goto error_fput; } - object->dentry = dentry; - inode_unlock(dinode); + object->file = file; return 0; error_dput: dput(dentry); -error: +error_unlock: inode_unlock(dinode); return ret; +error_fput: + fput(file); +error: + return ret; } /* @@ -419,33 +436,46 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, struct cachefiles_object *object) { struct cachefiles_cache *cache; - struct dentry *fan, *dentry; + struct dentry *fan; int ret; - _enter("OBJ%x{%pd},OBJ%x,%s,", - parent->debug_id, parent->dentry, + _enter("OBJ%x{%pD},OBJ%x,%s,", + parent->debug_id, parent->file, object->debug_id, object->d_name); cache = container_of(parent->cache, struct cachefiles_cache, cache); - ASSERT(parent->dentry); - ASSERT(d_backing_inode(parent->dentry)); + ASSERT(parent->file); lookup_again: - fan = cachefiles_walk_over_fanout(object, cache, parent->dentry); + fan = cachefiles_walk_over_fanout(object, cache, parent->file->f_path.dentry); if (IS_ERR(fan)) return PTR_ERR(fan); - /* Walk over path "parent/fanout/object". */ + /* Open path "parent/fanout/object". */ if (object->type == FSCACHE_COOKIE_TYPE_INDEX) { + struct dentry *dentry; + struct file *file; + struct path path; + dentry = cachefiles_get_directory(cache, fan, object->d_name, object); if (IS_ERR(dentry)) { dput(fan); return PTR_ERR(dentry); } - object->dentry = dentry; + path.mnt = cache->mnt; + path.dentry = dentry; + file = open_with_fake_path(&path, O_RDONLY | O_DIRECTORY, + d_backing_inode(dentry), + cache->cache_cred); + dput(dentry); + if (IS_ERR(file)) { + dput(fan); + return PTR_ERR(file); + } + object->file = file; } else { - ret = cachefiles_walk_to_file(cache, object, fan); + ret = cachefiles_open_file(cache, object, fan); if (ret < 0) { dput(fan); return ret; @@ -460,21 +490,17 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent, object->new = false; fscache_obtained_object(object); - _leave(" = 0 [%lu]", d_backing_inode(object->dentry)->i_ino); - return 0; + _leave(" = t [%lu]", file_inode(object->file)->i_ino); + return true; check_error: - if (ret == -ESTALE) { - dput(object->dentry); - object->dentry = NULL; - fscache_object_retrying_stale(object); + fput(object->file); + object->file = NULL; + if (ret == -ESTALE) goto lookup_again; - } if (ret == -EIO) cachefiles_io_error_obj(object, "Lookup failed"); cachefiles_mark_object_inactive(cache, object); - dput(object->dentry); - object->dentry = NULL; _leave(" = error %d", ret); return ret; } diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c index 464dea0b467c..2f14618d9a36 100644 --- a/fs/cachefiles/xattr.c +++ b/fs/cachefiles/xattr.c @@ -30,12 +30,14 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object, unsigned int xattr_flags) { struct cachefiles_xattr *buf; - struct dentry *dentry = object->dentry; + struct dentry *dentry; + struct file *file = object->file; unsigned int len = object->cookie->aux_len; int ret; - if (!dentry) + if (!file) return -ESTALE; + dentry = file->f_path.dentry; _enter("%x,#%d", object->debug_id, len); @@ -67,14 +69,11 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object, int cachefiles_check_auxdata(struct cachefiles_object *object) { struct cachefiles_xattr *buf; - struct dentry *dentry = object->dentry; + struct dentry *dentry = object->file->f_path.dentry; unsigned int len = object->cookie->aux_len, tlen; const void *p = fscache_get_aux(object->cookie); ssize_t ret; - ASSERT(dentry); - ASSERT(d_backing_inode(dentry)); - tlen = sizeof(struct cachefiles_xattr) + len; buf = kmalloc(tlen, GFP_KERNEL); if (!buf) diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index 7021c1ec2b64..90a7c92fca98 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -198,7 +198,7 @@ struct cachefiles_object { struct list_head dep_link; /* link in parent's dependents list */ char *d_name; /* Filename */ - struct dentry *dentry; /* the file/dir representing this object */ + struct file *file; /* The file representing this object */ loff_t i_size; /* object size */ atomic_t usage; /* object usage count */ uint8_t type; /* object type */ diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h index 5aec097d51ae..10ad5305d1c5 100644 --- a/include/trace/events/cachefiles.h +++ b/include/trace/events/cachefiles.h @@ -196,47 +196,44 @@ TRACE_EVENT(cachefiles_rename, TRACE_EVENT(cachefiles_mark_active, TP_PROTO(struct cachefiles_object *obj, - struct dentry *de), + struct inode *inode), - TP_ARGS(obj, de), + TP_ARGS(obj, inode), /* Note that obj may be NULL */ TP_STRUCT__entry( __field(unsigned int, obj ) - __field(struct dentry *, de ) + __field(ino_t, inode ) ), TP_fast_assign( __entry->obj = obj->debug_id; - __entry->de = de; + __entry->inode = inode->i_ino; ), - TP_printk("o=%08x d=%p", - __entry->obj, __entry->de) + TP_printk("o=%08x i=%lx", + __entry->obj, __entry->inode) ); TRACE_EVENT(cachefiles_mark_inactive, TP_PROTO(struct cachefiles_object *obj, - struct dentry *de, struct inode *inode), - TP_ARGS(obj, de, inode), + TP_ARGS(obj, inode), /* Note that obj may be NULL */ TP_STRUCT__entry( __field(unsigned int, obj ) - __field(struct dentry *, de ) - __field(struct inode *, inode ) + __field(ino_t, inode ) ), TP_fast_assign( __entry->obj = obj->debug_id; - __entry->de = de; - __entry->inode = inode; + __entry->inode = inode->i_ino; ), - TP_printk("o=%08x d=%p i=%p", - __entry->obj, __entry->de, __entry->inode) + TP_printk("o=%08x i=%lx", + __entry->obj, __entry->inode) ); #endif /* _TRACE_CACHEFILES_H */ From patchwork Mon Oct 18 14:57:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566979 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ED114C433EF for ; Mon, 18 Oct 2021 14:57:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D32556103C for ; Mon, 18 Oct 2021 14:57:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232870AbhJRPAI (ORCPT ); Mon, 18 Oct 2021 11:00:08 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:34842 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233088AbhJRO75 (ORCPT ); Mon, 18 Oct 2021 10:59:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569065; 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=GNPDlFd2NslhWdTLh2Oj9wTL+m4p3QmKel08TqL4wkc=; b=SX2R7w2KsRaEsYBV2LAYwL/zEctX3/0oOu2ccZB6UvbpH5RMAEk0YGmANs9Xzd4Rsrcyg2 9QuljYu2GLOC0xIQu+jTtO6rTYxHWGANVUq2frsR0r0FAF77K10xvq1UkZh7QzKpTSpmmX mZ9wuSmCvnuOZpADsITQodoPYlZ+TpI= 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-553-1kb8q-8UNbC0iJEAYxuwyg-1; Mon, 18 Oct 2021 10:57:39 -0400 X-MC-Unique: 1kb8q-8UNbC0iJEAYxuwyg-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 98DFE1006AA2; Mon, 18 Oct 2021 14:57:37 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 877E55D6D7; Mon, 18 Oct 2021 14:57:31 +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 27/67] cachefiles: trace: Log coherency checks From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:57:30 +0100 Message-ID: <163456905064.2614702.902644495518051262.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Add a cachefiles tracepoint that logs the result of coherency management when the coherency data on a file in the cache is checked or committed. Signed-off-by: David Howells --- fs/cachefiles/xattr.c | 44 +++++++++++++++++++++-------- include/trace/events/cachefiles.h | 56 +++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 12 deletions(-) diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c index 2f14618d9a36..bfb2f4d605af 100644 --- a/fs/cachefiles/xattr.c +++ b/fs/cachefiles/xattr.c @@ -53,12 +53,21 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object, ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache, buf, sizeof(struct cachefiles_xattr) + len, xattr_flags); - kfree(buf); - if (ret < 0 && ret != -ENOMEM) - cachefiles_io_error_obj( - object, - "Failed to set xattr with error %d", ret); + if (ret < 0) { + trace_cachefiles_coherency(object, file_inode(file)->i_ino, + 0, + cachefiles_coherency_set_fail); + if (ret != -ENOMEM) + cachefiles_io_error_obj( + object, + "Failed to set xattr with error %d", ret); + } else { + trace_cachefiles_coherency(object, file_inode(file)->i_ino, + 0, + cachefiles_coherency_set_ok); + } + kfree(buf); _leave(" = %d", ret); return ret; } @@ -72,21 +81,32 @@ int cachefiles_check_auxdata(struct cachefiles_object *object) struct dentry *dentry = object->file->f_path.dentry; unsigned int len = object->cookie->aux_len, tlen; const void *p = fscache_get_aux(object->cookie); - ssize_t ret; + enum cachefiles_coherency_trace why; + ssize_t xlen; + int ret = -ESTALE; tlen = sizeof(struct cachefiles_xattr) + len; buf = kmalloc(tlen, GFP_KERNEL); if (!buf) return -ENOMEM; - ret = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, buf, tlen); - if (ret == tlen && - buf->type == object->cookie->type && - memcmp(buf->data, p, len) == 0) + xlen = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, buf, tlen); + if (xlen != tlen) { + if (xlen == -EIO) + cachefiles_io_error_obj( + object, + "Failed to read aux with error %zd", xlen); + why = cachefiles_coherency_check_xattr; + } else if (buf->type != object->cookie->type) { + why = cachefiles_coherency_check_type; + } else if (memcmp(buf->data, p, len) != 0) { + why = cachefiles_coherency_check_aux; + } else { + why = cachefiles_coherency_check_ok; ret = 0; - else - ret = -ESTALE; + } + trace_cachefiles_coherency(object, file_inode(object->file)->i_ino, 0, why); kfree(buf); return ret; } diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h index 10ad5305d1c5..6e9f6462833d 100644 --- a/include/trace/events/cachefiles.h +++ b/include/trace/events/cachefiles.h @@ -24,6 +24,19 @@ enum cachefiles_obj_ref_trace { cachefiles_obj_ref__nr_traces }; +enum cachefiles_coherency_trace { + cachefiles_coherency_check_aux, + cachefiles_coherency_check_content, + cachefiles_coherency_check_dirty, + cachefiles_coherency_check_len, + cachefiles_coherency_check_objsize, + cachefiles_coherency_check_ok, + cachefiles_coherency_check_type, + cachefiles_coherency_check_xattr, + cachefiles_coherency_set_fail, + cachefiles_coherency_set_ok, +}; + #endif /* @@ -47,6 +60,18 @@ enum cachefiles_obj_ref_trace { EM(cachefiles_obj_put_wait_retry, "PUT wait_retry") \ E_(cachefiles_obj_put_wait_timeo, "PUT wait_timeo") +#define cachefiles_coherency_traces \ + EM(cachefiles_coherency_check_aux, "BAD aux ") \ + EM(cachefiles_coherency_check_content, "BAD cont") \ + EM(cachefiles_coherency_check_dirty, "BAD dirt") \ + EM(cachefiles_coherency_check_len, "BAD len ") \ + EM(cachefiles_coherency_check_objsize, "BAD osiz") \ + EM(cachefiles_coherency_check_ok, "OK ") \ + EM(cachefiles_coherency_check_type, "BAD type") \ + EM(cachefiles_coherency_check_xattr, "BAD xatt") \ + EM(cachefiles_coherency_set_fail, "SET fail") \ + E_(cachefiles_coherency_set_ok, "SET ok ") + /* * Export enum symbols via userspace. */ @@ -57,6 +82,7 @@ enum cachefiles_obj_ref_trace { cachefiles_obj_kill_traces; cachefiles_obj_ref_traces; +cachefiles_coherency_traces; /* * Now redefine the EM() and E_() macros to map the enums to the strings that @@ -236,6 +262,36 @@ TRACE_EVENT(cachefiles_mark_inactive, __entry->obj, __entry->inode) ); +TRACE_EVENT(cachefiles_coherency, + TP_PROTO(struct cachefiles_object *obj, + ino_t ino, + int content, + enum cachefiles_coherency_trace why), + + TP_ARGS(obj, ino, content, why), + + /* Note that obj may be NULL */ + TP_STRUCT__entry( + __field(unsigned int, obj ) + __field(enum cachefiles_coherency_trace, why ) + __field(int, content ) + __field(u64, ino ) + ), + + TP_fast_assign( + __entry->obj = obj->debug_id; + __entry->why = why; + __entry->content = content; + __entry->ino = ino; + ), + + TP_printk("o=%08x %s i=%llx c=%u", + __entry->obj, + __print_symbolic(__entry->why, cachefiles_coherency_traces), + __entry->ino, + __entry->content) + ); + #endif /* _TRACE_CACHEFILES_H */ /* This part must be outside protection */ From patchwork Mon Oct 18 14:57:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566981 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 17485C43219 for ; Mon, 18 Oct 2021 14:58:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F12976103C for ; Mon, 18 Oct 2021 14:58:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233079AbhJRPAK (ORCPT ); Mon, 18 Oct 2021 11:00:10 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:20764 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232622AbhJRPAE (ORCPT ); Mon, 18 Oct 2021 11:00:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569072; 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=FqXtD4ctY9AuNokwYb2eI4uzaefOorI1un4GDbWnL4g=; b=Jt0NeKx4sfTIFHRsNUSq8MDxfx0eUQ2ForwzyxZfUjeowFDGLGR6SnysTkHgARPJSv3Pjl bBWUYxvOM0mSUO0AT5h6/GlXESt+haNCyAe5nymjn9Kx6zkD8aGoNhZHgmPzLIwHQls6jP lbHfNza593VIzqXF+UMlFTOK6c1Y/28= 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-383-uJKXfj15M2-9BoLIeck12g-1; Mon, 18 Oct 2021 10:57:49 -0400 X-MC-Unique: uJKXfj15M2-9BoLIeck12g-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 0CB1F8066F5; Mon, 18 Oct 2021 14:57:47 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id B80A7100EA05; Mon, 18 Oct 2021 14:57:43 +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 28/67] cachefiles: Trace truncations From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:57:42 +0100 Message-ID: <163456906284.2614702.7451773731985568258.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Add a tracepoint to trace truncation operations. Signed-off-by: David Howells --- fs/cachefiles/interface.c | 9 +++++++- include/trace/events/cachefiles.h | 40 +++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 4edb3a09932a..8f98e5c27d66 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -341,9 +341,16 @@ static void cachefiles_invalidate_object(struct cachefiles_object *object) ASSERT(d_is_reg(file->f_path.dentry)); cachefiles_begin_secure(cache, &saved_cred); + trace_cachefiles_trunc(object, file_inode(file), + i_size_read(file_inode(file)), 0, + cachefiles_trunc_invalidate); ret = vfs_truncate(&file->f_path, 0); - if (ret == 0) + if (ret == 0) { + trace_cachefiles_trunc(object, file_inode(file), + 0, ni_size, + cachefiles_trunc_set_size); ret = vfs_truncate(&file->f_path, ni_size); + } cachefiles_end_secure(cache, saved_cred); if (ret != 0) { diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h index 6e9f6462833d..09d76c160451 100644 --- a/include/trace/events/cachefiles.h +++ b/include/trace/events/cachefiles.h @@ -37,6 +37,11 @@ enum cachefiles_coherency_trace { cachefiles_coherency_set_ok, }; +enum cachefiles_trunc_trace { + cachefiles_trunc_invalidate, + cachefiles_trunc_set_size, +}; + #endif /* @@ -72,6 +77,10 @@ enum cachefiles_coherency_trace { EM(cachefiles_coherency_set_fail, "SET fail") \ E_(cachefiles_coherency_set_ok, "SET ok ") +#define cachefiles_trunc_traces \ + EM(cachefiles_trunc_invalidate, "INVAL ") \ + E_(cachefiles_trunc_set_size, "SETSIZ") + /* * Export enum symbols via userspace. */ @@ -83,6 +92,7 @@ enum cachefiles_coherency_trace { cachefiles_obj_kill_traces; cachefiles_obj_ref_traces; cachefiles_coherency_traces; +cachefiles_trunc_traces; /* * Now redefine the EM() and E_() macros to map the enums to the strings that @@ -292,6 +302,36 @@ TRACE_EVENT(cachefiles_coherency, __entry->content) ); +TRACE_EVENT(cachefiles_trunc, + TP_PROTO(struct cachefiles_object *obj, struct inode *backer, + loff_t from, loff_t to, enum cachefiles_trunc_trace why), + + TP_ARGS(obj, backer, from, to, why), + + TP_STRUCT__entry( + __field(unsigned int, obj ) + __field(unsigned int, backer ) + __field(enum cachefiles_trunc_trace, why ) + __field(loff_t, from ) + __field(loff_t, to ) + ), + + TP_fast_assign( + __entry->obj = obj->debug_id; + __entry->backer = backer->i_ino; + __entry->from = from; + __entry->to = to; + __entry->why = why; + ), + + TP_printk("o=%08x b=%08x %s l=%llx->%llx", + __entry->obj, + __entry->backer, + __print_symbolic(__entry->why, cachefiles_trunc_traces), + __entry->from, + __entry->to) + ); + #endif /* _TRACE_CACHEFILES_H */ /* This part must be outside protection */ From patchwork Mon Oct 18 14:57:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566983 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 09B35C433FE for ; Mon, 18 Oct 2021 14:58:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E517D610A3 for ; Mon, 18 Oct 2021 14:58:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233017AbhJRPAZ (ORCPT ); Mon, 18 Oct 2021 11:00:25 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:23955 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232717AbhJRPAQ (ORCPT ); Mon, 18 Oct 2021 11:00:16 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569084; 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=GruXL50DosX11u6Eiitd3mjK2Wt4qFrfQfU0liRNHgw=; b=ezz9LvF5r5NMcQoJtpTKPRJlqP/BTK3pAHeJ0W3lFxlvs1f5RU4pJ9HxXFTpBxkbKYngDn AEtmFq0Fw8tmT5W62n9VbYwqhv5IccCC0NLr/LTW/68g2YoZ/v5/aXCVH3psGaJqdCOl6b 3/WkzKe4VCWdljzsjfLzy5bm6+6LZTw= 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-394-o6RxVNI9Ph2jSiIgLDSOyw-1; Mon, 18 Oct 2021 10:58:01 -0400 X-MC-Unique: o6RxVNI9Ph2jSiIgLDSOyw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 147A510A8E06; Mon, 18 Oct 2021 14:57:59 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 08C63641AB; Mon, 18 Oct 2021 14:57:52 +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 29/67] cachefiles: Trace read and write operations From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:57:52 +0100 Message-ID: <163456907226.2614702.16135532021542996215.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Add tracepoints for read and write operations on cache files. Signed-off-by: David Howells --- fs/cachefiles/io.c | 6 +++- include/trace/events/cachefiles.h | 58 +++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index 0e1fb44b5d04..f703a93e238b 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -62,6 +62,7 @@ static int cachefiles_read(struct netfs_cache_resources *cres, netfs_io_terminated_t term_func, void *term_func_priv) { + struct cachefiles_object *object = cres->cache_priv; struct cachefiles_kiocb *ki; struct file *file = cachefiles_cres_file(cres); unsigned int old_nofs; @@ -124,6 +125,7 @@ static int cachefiles_read(struct netfs_cache_resources *cres, get_file(ki->iocb.ki_filp); + trace_cachefiles_read(object, file_inode(file), ki->iocb.ki_pos, len - skipped); old_nofs = memalloc_nofs_save(); ret = vfs_iocb_iter_read(file, &ki->iocb, iter); memalloc_nofs_restore(old_nofs); @@ -188,6 +190,7 @@ static int cachefiles_write(struct netfs_cache_resources *cres, netfs_io_terminated_t term_func, void *term_func_priv) { + struct cachefiles_object *object = cres->cache_priv; struct cachefiles_kiocb *ki; struct inode *inode; struct file *file = cachefiles_cres_file(cres); @@ -229,6 +232,7 @@ static int cachefiles_write(struct netfs_cache_resources *cres, get_file(ki->iocb.ki_filp); + trace_cachefiles_write(object, inode, ki->iocb.ki_pos, len); old_nofs = memalloc_nofs_save(); ret = vfs_iocb_iter_write(file, &ki->iocb, iter); memalloc_nofs_restore(old_nofs); @@ -418,7 +422,7 @@ int cachefiles_begin_operation(struct netfs_cache_resources *cres) _enter(""); - cres->cache_priv = op; + cres->cache_priv = object; cres->cache_priv2 = get_file(object->file); cres->ops = &cachefiles_netfs_cache_ops; cres->debug_id = object->cookie->debug_id; diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h index 09d76c160451..47df44550ad6 100644 --- a/include/trace/events/cachefiles.h +++ b/include/trace/events/cachefiles.h @@ -302,6 +302,64 @@ TRACE_EVENT(cachefiles_coherency, __entry->content) ); +TRACE_EVENT(cachefiles_read, + TP_PROTO(struct cachefiles_object *obj, + struct inode *backer, + loff_t start, + size_t len), + + TP_ARGS(obj, backer, start, len), + + TP_STRUCT__entry( + __field(unsigned int, obj ) + __field(unsigned int, backer ) + __field(size_t, len ) + __field(loff_t, start ) + ), + + TP_fast_assign( + __entry->obj = obj->debug_id; + __entry->backer = backer->i_ino; + __entry->start = start; + __entry->len = len; + ), + + TP_printk("o=%08x b=%08x s=%llx l=%zx", + __entry->obj, + __entry->backer, + __entry->start, + __entry->len) + ); + +TRACE_EVENT(cachefiles_write, + TP_PROTO(struct cachefiles_object *obj, + struct inode *backer, + loff_t start, + size_t len), + + TP_ARGS(obj, backer, start, len), + + TP_STRUCT__entry( + __field(unsigned int, obj ) + __field(unsigned int, backer ) + __field(size_t, len ) + __field(loff_t, start ) + ), + + TP_fast_assign( + __entry->obj = obj->debug_id; + __entry->backer = backer->i_ino; + __entry->start = start; + __entry->len = len; + ), + + TP_printk("o=%08x b=%08x s=%llx l=%zx", + __entry->obj, + __entry->backer, + __entry->start, + __entry->len) + ); + TRACE_EVENT(cachefiles_trunc, TP_PROTO(struct cachefiles_object *obj, struct inode *backer, loff_t from, loff_t to, enum cachefiles_trunc_trace why), From patchwork Mon Oct 18 14:58:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12566985 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E8CFCC433EF for ; Mon, 18 Oct 2021 14:58:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C721A6103D for ; Mon, 18 Oct 2021 14:58:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232628AbhJRPBD (ORCPT ); Mon, 18 Oct 2021 11:01:03 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:45283 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232083AbhJRPBD (ORCPT ); Mon, 18 Oct 2021 11:01:03 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569132; 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=K5FTLf3BYt9yC5gnmuuFov8Yi7OVdM9eRPeEUyTv68E=; b=B0ELvZRJNt5Rq7J2VGIl7cEtBzP6PNlKDDBZlBGT7YWUJQAYRLsSJNffwq6p2kDVQkzJGr H6MIDfD2gl09p1zb370I+F27yuaIDjbDhz5pXI8n8iJx98kfu6KiBsZuHlovrT8ApsMXf4 DIDWO2Bh7l/KSgYmX9L5oYEw+9FcxZY= 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-415-j8jdinTONVS7GUILmqYu9Q-1; Mon, 18 Oct 2021 10:58:48 -0400 X-MC-Unique: j8jdinTONVS7GUILmqYu9Q-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7E3E991278; Mon, 18 Oct 2021 14:58:46 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2B9076788F; Mon, 18 Oct 2021 14:58:05 +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 30/67] cachefiles: Round the cachefile size up to DIO block size From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:58:04 +0100 Message-ID: <163456908429.2614702.18199815281243741948.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Round the size of a cachefile up to DIO block size so that we can always read back the last partial page of a file using direct I/O. Signed-off-by: David Howells --- fs/cachefiles/bind.c | 3 ++- fs/cachefiles/interface.c | 2 ++ fs/cachefiles/internal.h | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c index af7386ad14af..4ea8c93e14d8 100644 --- a/fs/cachefiles/bind.c +++ b/fs/cachefiles/bind.c @@ -126,7 +126,8 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) !d_backing_inode(root)->i_op->mkdir || !(d_backing_inode(root)->i_opflags & IOP_XATTR) || !root->d_sb->s_op->statfs || - !root->d_sb->s_op->sync_fs) + !root->d_sb->s_op->sync_fs || + root->d_sb->s_blocksize > PAGE_SIZE) goto error_unsupported; ret = -EROFS; diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 8f98e5c27d66..3e678ab14c85 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -268,6 +268,7 @@ static int cachefiles_attr_changed(struct cachefiles_object *object) int ret; ni_size = object->cookie->object_size; + ni_size = round_up(ni_size, CACHEFILES_DIO_BLOCK_SIZE); _enter("{OBJ%x},[%llu]", object->debug_id, (unsigned long long) ni_size); @@ -346,6 +347,7 @@ static void cachefiles_invalidate_object(struct cachefiles_object *object) cachefiles_trunc_invalidate); ret = vfs_truncate(&file->f_path, 0); if (ret == 0) { + ni_size = round_up(ni_size, CACHEFILES_DIO_BLOCK_SIZE); trace_cachefiles_trunc(object, file_inode(file), 0, ni_size, cachefiles_trunc_set_size); diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index 4705f968e661..ff00c5249f4f 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -19,6 +19,8 @@ #include #include +#define CACHEFILES_DIO_BLOCK_SIZE 4096 + struct cachefiles_cache; struct cachefiles_object; From patchwork Mon Oct 18 14:58:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567097 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05D48C4332F for ; Mon, 18 Oct 2021 14:59:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E3FAD610A3 for ; Mon, 18 Oct 2021 14:59:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233141AbhJRPBQ (ORCPT ); Mon, 18 Oct 2021 11:01:16 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:22217 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233067AbhJRPBP (ORCPT ); Mon, 18 Oct 2021 11:01:15 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569143; 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=qpmC6KV6XlN7tGrzNmQxvfZVaWj4hw0BElRSYjH98xU=; b=fTLKzGAT4CDB0pcGljBFPZrxTSL1ayNf9dbRPEcjTE43E2yjyK8TlEVwWPahtbjHte/ULT BHPgGdZ87BotgUB+3N+XO/UX5zaa4XjoUBk1CHwjexuBjnQpP0EFQSCgtTVyDRZywzNKf0 jbDU5V0I+qUc+RkI0H9dz8QaDWAXbaE= 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-512-ncCaC32SNx61rESZ2ISbmQ-1; Mon, 18 Oct 2021 10:59:00 -0400 X-MC-Unique: ncCaC32SNx61rESZ2ISbmQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3CD1B802682; Mon, 18 Oct 2021 14:58:58 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 84A8B5F4EE; Mon, 18 Oct 2021 14:58:52 +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 31/67] cachefiles: Don't use XATTR_ flags with vfs_setxattr() From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:58:51 +0100 Message-ID: <163456913173.2614702.12279776553978969628.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Don't pass XATTR_CREATE/XATTR_REPLACE to vfs_setxattr(); just pass 0 as we don't want to have to deal with the error or try to guess which we want to use. Signed-off-by: David Howells --- fs/cachefiles/interface.c | 2 +- fs/cachefiles/internal.h | 3 +-- fs/cachefiles/namei.c | 2 +- fs/cachefiles/xattr.c | 6 ++---- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 3e678ab14c85..674d3d75fa70 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -132,7 +132,7 @@ static void cachefiles_update_object(struct cachefiles_object *object) cache = container_of(object->cache, struct cachefiles_cache, cache); cachefiles_begin_secure(cache, &saved_cred); - cachefiles_set_object_xattr(object, XATTR_REPLACE); + cachefiles_set_object_xattr(object); cachefiles_end_secure(cache, saved_cred); _leave(""); } diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index ff00c5249f4f..92f90a5a4e93 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -162,8 +162,7 @@ static inline void cachefiles_end_secure(struct cachefiles_cache *cache, /* * xattr.c */ -extern int cachefiles_set_object_xattr(struct cachefiles_object *object, - unsigned int xattr_flags); +extern int cachefiles_set_object_xattr(struct cachefiles_object *object); extern int cachefiles_check_auxdata(struct cachefiles_object *object); extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, struct dentry *dentry); diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index a60ef6f1cf1e..cb08be5fb28e 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -291,7 +291,7 @@ static int cachefiles_check_open_object(struct cachefiles_cache *cache, if (object->new) { /* attach data to a newly constructed terminal object */ - ret = cachefiles_set_object_xattr(object, XATTR_CREATE); + ret = cachefiles_set_object_xattr(object); if (ret < 0) goto error_unmark; } else { diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c index bfb2f4d605af..82c822bb71af 100644 --- a/fs/cachefiles/xattr.c +++ b/fs/cachefiles/xattr.c @@ -26,8 +26,7 @@ static const char cachefiles_xattr_cache[] = /* * set the state xattr on a cache file */ -int cachefiles_set_object_xattr(struct cachefiles_object *object, - unsigned int xattr_flags) +int cachefiles_set_object_xattr(struct cachefiles_object *object) { struct cachefiles_xattr *buf; struct dentry *dentry; @@ -51,8 +50,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object, clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->cookie->flags); ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache, - buf, sizeof(struct cachefiles_xattr) + len, - xattr_flags); + buf, sizeof(struct cachefiles_xattr) + len, 0); if (ret < 0) { trace_cachefiles_coherency(object, file_inode(file)->i_ino, 0, From patchwork Mon Oct 18 14:59:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567099 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ED9A4C433FE for ; Mon, 18 Oct 2021 15:00:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D62FA6103D for ; Mon, 18 Oct 2021 15:00:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232986AbhJRPCO (ORCPT ); Mon, 18 Oct 2021 11:02:14 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:25686 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232649AbhJRPCC (ORCPT ); Mon, 18 Oct 2021 11:02:02 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569190; 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=u3eVY7sKaIJbpFTvM7wbMyoLphftgkd/AnG9vQi6mbo=; b=iCjGMh4W10OIaZWhBn/pc68QBc270Fdidrbp3oug5OeQeN6vApeQg+QlQK/QSA5s5FW7o9 u4VFtV8/tb0ji9RR1cAfotcS0Ja9FHfPJt9Z7ahwkF7saLetwOXek3/2SSoMqpYOKw2Ti/ yP1fr9lEb7yxEdxo+GZjdHCmFsurjFI= 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-298-XkSNNV2nNNKmB6b_yyqTZg-1; Mon, 18 Oct 2021 10:59:45 -0400 X-MC-Unique: XkSNNV2nNNKmB6b_yyqTZg-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 620D1802575; Mon, 18 Oct 2021 14:59:43 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3841760657; Mon, 18 Oct 2021 14:59:40 +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 33/67] cachefiles: Trace decisions in cachefiles_prepare_read() From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:59:39 +0100 Message-ID: <163456917935.2614702.1886040219032881319.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Add a tracepoint to log decisions made in cachefiles_prepare_read() about what it's going to request for the next subrequest and why. Signed-off-by: David Howells --- fs/cachefiles/io.c | 22 +++++++++++-- fs/cachefiles/main.c | 2 + include/trace/events/cachefiles.h | 64 +++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 3 deletions(-) diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index e5c29c0decea..c05f64cdfd0e 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -303,6 +303,7 @@ static int cachefiles_write(struct netfs_cache_resources *cres, static enum netfs_read_source cachefiles_prepare_read(struct netfs_read_subrequest *subreq, loff_t i_size) { + enum cachefiles_prepare_read_trace why; struct netfs_read_request *rreq = subreq->rreq; struct netfs_cache_resources *cres = &rreq->cache_resources; struct cachefiles_object *object; @@ -312,26 +313,31 @@ static enum netfs_read_source cachefiles_prepare_read(struct netfs_read_subreque struct file *file = cachefiles_cres_file(cres); enum netfs_read_source ret = NETFS_DOWNLOAD_FROM_SERVER; loff_t off, to; + ino_t ino = file ? file_inode(file)->i_ino : 0; _enter("%zx @%llx/%llx", subreq->len, subreq->start, i_size); if (subreq->start >= i_size) { ret = NETFS_FILL_WITH_ZEROES; + why = cachefiles_trace_read_after_eof; goto out_no_object; } if (test_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags)) { __set_bit(NETFS_SREQ_WRITE_TO_CACHE, &subreq->flags); + why = cachefiles_trace_read_no_data; goto out_no_object; } /* The object and the file may be being created in the background. */ if (!file) { + why = cachefiles_trace_read_no_file; if (!fscache_wait_for_operation(cres, FSCACHE_WANT_READ)) goto out_no_object; file = cachefiles_cres_file(cres); if (!file) goto out_no_object; + ino = file_inode(file)->i_ino; } object = cachefiles_cres_object(cres); @@ -340,23 +346,31 @@ static enum netfs_read_source cachefiles_prepare_read(struct netfs_read_subreque off = vfs_llseek(file, subreq->start, SEEK_DATA); if (off < 0 && off >= (loff_t)-MAX_ERRNO) { - if (off == (loff_t)-ENXIO) + if (off == (loff_t)-ENXIO) { + why = cachefiles_trace_read_seek_nxio; goto download_and_store; + } + why = cachefiles_trace_read_seek_error; goto out; } - if (off >= subreq->start + subreq->len) + if (off >= subreq->start + subreq->len) { + why = cachefiles_trace_read_found_hole; goto download_and_store; + } if (off > subreq->start) { off = round_up(off, cache->bsize); subreq->len = off - subreq->start; + why = cachefiles_trace_read_found_part; goto download_and_store; } to = vfs_llseek(file, subreq->start, SEEK_HOLE); - if (to < 0 && to >= (loff_t)-MAX_ERRNO) + if (to < 0 && to >= (loff_t)-MAX_ERRNO) { + why = cachefiles_trace_read_seek_error; goto out; + } if (to < subreq->start + subreq->len) { if (subreq->start + subreq->len >= i_size) @@ -366,6 +380,7 @@ static enum netfs_read_source cachefiles_prepare_read(struct netfs_read_subreque subreq->len = to - subreq->start; } + why = cachefiles_trace_read_have_data; ret = NETFS_READ_FROM_CACHE; goto out; @@ -375,6 +390,7 @@ static enum netfs_read_source cachefiles_prepare_read(struct netfs_read_subreque out: cachefiles_end_secure(cache, saved_cred); out_no_object: + trace_cachefiles_prep_read(subreq, ret, why, ino); return ret; } diff --git a/fs/cachefiles/main.c b/fs/cachefiles/main.c index dc7731812b98..522fda828563 100644 --- a/fs/cachefiles/main.c +++ b/fs/cachefiles/main.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #define CREATE_TRACE_POINTS #include "internal.h" diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h index d98adabce92e..d63e5fb46d27 100644 --- a/include/trace/events/cachefiles.h +++ b/include/trace/events/cachefiles.h @@ -60,6 +60,17 @@ enum cachefiles_trunc_trace { cachefiles_trunc_shrink, }; +enum cachefiles_prepare_read_trace { + cachefiles_trace_read_after_eof, + cachefiles_trace_read_found_hole, + cachefiles_trace_read_found_part, + cachefiles_trace_read_have_data, + cachefiles_trace_read_no_data, + cachefiles_trace_read_no_file, + cachefiles_trace_read_seek_error, + cachefiles_trace_read_seek_nxio, +}; + #endif /* @@ -103,6 +114,17 @@ enum cachefiles_trunc_trace { EM(cachefiles_trunc_dio_adjust, "DIOADJ") \ E_(cachefiles_trunc_shrink, "SHRINK") +#define cachefiles_prepare_read_traces \ + EM(cachefiles_trace_read_after_eof, "after-eof ") \ + EM(cachefiles_trace_read_found_hole, "found-hole") \ + EM(cachefiles_trace_read_found_part, "found-part") \ + EM(cachefiles_trace_read_have_data, "have-data ") \ + EM(cachefiles_trace_read_no_data, "no-data ") \ + EM(cachefiles_trace_read_no_file, "no-file ") \ + EM(cachefiles_trace_read_seek_error, "seek-error") \ + E_(cachefiles_trace_read_seek_nxio, "seek-enxio") + + /* * Export enum symbols via userspace. */ @@ -115,6 +137,7 @@ cachefiles_obj_kill_traces; cachefiles_obj_ref_traces; cachefiles_coherency_traces; cachefiles_trunc_traces; +cachefiles_prepare_read_traces; /* * Now redefine the EM() and E_() macros to map the enums to the strings that @@ -324,6 +347,47 @@ TRACE_EVENT(cachefiles_coherency, __entry->content) ); +TRACE_EVENT(cachefiles_prep_read, + TP_PROTO(struct netfs_read_subrequest *sreq, + enum netfs_read_source source, + enum cachefiles_prepare_read_trace why, + ino_t cache_inode), + + TP_ARGS(sreq, source, why, cache_inode), + + TP_STRUCT__entry( + __field(unsigned int, rreq ) + __field(unsigned short, index ) + __field(unsigned short, flags ) + __field(enum netfs_read_source, source ) + __field(enum cachefiles_prepare_read_trace, why ) + __field(size_t, len ) + __field(loff_t, start ) + __field(unsigned int, netfs_inode ) + __field(unsigned int, cache_inode ) + ), + + TP_fast_assign( + __entry->rreq = sreq->rreq->debug_id; + __entry->index = sreq->debug_index; + __entry->flags = sreq->flags; + __entry->source = source; + __entry->why = why; + __entry->len = sreq->len; + __entry->start = sreq->start; + __entry->netfs_inode = sreq->rreq->inode->i_ino; + __entry->cache_inode = cache_inode; + ), + + TP_printk("R=%08x[%u] %s %s f=%02x s=%llx %zx ni=%x b=%x", + __entry->rreq, __entry->index, + __print_symbolic(__entry->source, netfs_sreq_sources), + __print_symbolic(__entry->why, cachefiles_prepare_read_traces), + __entry->flags, + __entry->start, __entry->len, + __entry->netfs_inode, __entry->cache_inode) + ); + TRACE_EVENT(cachefiles_read, TP_PROTO(struct cachefiles_object *obj, struct inode *backer, From patchwork Mon Oct 18 14:59:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567101 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03639C43217 for ; Mon, 18 Oct 2021 15:00:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DF41261074 for ; Mon, 18 Oct 2021 15:00:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232996AbhJRPCP (ORCPT ); Mon, 18 Oct 2021 11:02:15 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:32615 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232885AbhJRPCL (ORCPT ); Mon, 18 Oct 2021 11:02:11 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569200; 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=jdB/32s/uc8yVIqnMp8H9Wpa3fu6IqGejTkXRVt6ecY=; b=jWddr7GjGB+mUTVZ2jaqHqvk9y3beS0qhf8DEvnOUPhWPHFxqGPqCA+d89Kj4aCZMu8E7k ds8k3xrGTwmNxerU9Q2Jde66oavDO9DJUOKLkNxT9h42k6D8IGGVxU6t+XOtfXA7YK+G3b fLQA7WHfdI+okDVftFDIGu1D26ubE0M= 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-360-NIMBeaJPN3WF7tGHAL-ytg-1; Mon, 18 Oct 2021 10:59:54 -0400 X-MC-Unique: NIMBeaJPN3WF7tGHAL-ytg-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9D33B80710A; Mon, 18 Oct 2021 14:59:52 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 728301037F36; Mon, 18 Oct 2021 14:59:49 +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 34/67] cachefiles: Make cachefiles_write_prepare() check for space From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:59:48 +0100 Message-ID: <163456918862.2614702.15568944072409008939.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Make the cachefiles_write_prepare() function check that there's sufficient space to fully satisfy a proposed write. If we already checked for allocated data during read preparation, then this fact can be used to skip the more thorough checks here. If there's enough space in the cache, we just allow the write. If we're uncertain, then we use SEEK_DATA/SEEK_HOLE to check if the block is already fully allocated - and if it is, we just allow the write. However, if there's insufficient space for the whole write and there's partially allocated data in the file, we punch out that data and disallow the write. This frees up some space and removes old data from the cache. Signed-off-by: David Howells --- fs/cachefiles/io.c | 82 ++++++++++++++++++++++++++++++++++++++++++++---- fs/netfs/read_helper.c | 2 + include/linux/netfs.h | 3 +- 3 files changed, 79 insertions(+), 8 deletions(-) diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index c05f64cdfd0e..350243b45dd5 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include "internal.h" @@ -385,8 +386,7 @@ static enum netfs_read_source cachefiles_prepare_read(struct netfs_read_subreque goto out; download_and_store: - if (cachefiles_has_space(cache, 0, (subreq->len + PAGE_SIZE - 1) / PAGE_SIZE) == 0) - __set_bit(NETFS_SREQ_WRITE_TO_CACHE, &subreq->flags); + __set_bit(NETFS_SREQ_WRITE_TO_CACHE, &subreq->flags); out: cachefiles_end_secure(cache, saved_cred); out_no_object: @@ -397,17 +397,87 @@ static enum netfs_read_source cachefiles_prepare_read(struct netfs_read_subreque /* * 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) +static int __cachefiles_prepare_write(struct netfs_cache_resources *cres, + loff_t *_start, size_t *_len, loff_t i_size, + bool no_space_allocated_yet) { - loff_t start = *_start; + struct cachefiles_object *object = cachefiles_cres_object(cres); + struct cachefiles_cache *cache = object->volume->cache; + struct file *file = cachefiles_cres_file(cres); + loff_t start = *_start, pos; size_t len = *_len, down; + int ret; /* Round to DIO size */ down = start - round_down(start, PAGE_SIZE); *_start = start - down; *_len = round_up(down + len, PAGE_SIZE); - return 0; + + /* We need to work out whether there's sufficient disk space to perform + * the write - but we can skip that check if we have space already + * allocated. + */ + if (no_space_allocated_yet) + goto check_space; + + pos = vfs_llseek(file, *_start, SEEK_DATA); + if (pos < 0 && pos >= (loff_t)-MAX_ERRNO) { + if (pos == -ENXIO) + goto check_space; /* Unallocated tail */ + return pos; + } + if ((u64)pos >= (u64)*_start + *_len) + goto check_space; /* Unallocated region */ + + /* We have a block that's at least partially filled - if we're low on + * space, we need to see if it's fully allocated. If it's not, we may + * want to cull it. + */ + if (cachefiles_has_space(cache, 0, *_len / PAGE_SIZE) == 0) + return 0; /* Enough space to simply overwrite the whole block */ + + pos = vfs_llseek(file, *_start, SEEK_HOLE); + if (pos < 0 && pos >= (loff_t)-MAX_ERRNO) + return pos; + if ((u64)pos >= (u64)*_start + *_len) + return 0; /* Fully allocated */ + + /* Partially allocated, but insufficient space: cull. */ + ret = vfs_fallocate(file, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + *_start, *_len); + if (ret < 0) { + cachefiles_io_error_obj(object, + "CacheFiles: fallocate failed (%d)\n", ret); + ret = -EIO; + } + + return ret; + +check_space: + return cachefiles_has_space(cache, 0, *_len / PAGE_SIZE); +} + +static int cachefiles_prepare_write(struct netfs_cache_resources *cres, + loff_t *_start, size_t *_len, loff_t i_size, + bool no_space_allocated_yet) +{ + struct cachefiles_object *object = cachefiles_cres_object(cres); + struct cachefiles_cache *cache = object->volume->cache; + const struct cred *saved_cred; + int ret; + + if (!cachefiles_cres_file(cres)) { + if (!fscache_wait_for_operation(cres, FSCACHE_WANT_WRITE)) + return -ENOBUFS; + if (!cachefiles_cres_file(cres)) + return -ENOBUFS; + } + + cachefiles_begin_secure(cache, &saved_cred); + ret = __cachefiles_prepare_write(cres, _start, _len, i_size, + no_space_allocated_yet); + cachefiles_end_secure(cache, saved_cred); + return ret; } /* diff --git a/fs/netfs/read_helper.c b/fs/netfs/read_helper.c index dfc60c79a9f3..80f8e334371d 100644 --- a/fs/netfs/read_helper.c +++ b/fs/netfs/read_helper.c @@ -323,7 +323,7 @@ static void netfs_rreq_do_write_to_cache(struct netfs_read_request *rreq) } ret = cres->ops->prepare_write(cres, &subreq->start, &subreq->len, - rreq->i_size); + rreq->i_size, true); if (ret < 0) { trace_netfs_failure(rreq, subreq, ret, netfs_fail_prepare_write); trace_netfs_sreq(subreq, netfs_sreq_trace_write_skip); diff --git a/include/linux/netfs.h b/include/linux/netfs.h index 014fb502fd91..99137486d351 100644 --- a/include/linux/netfs.h +++ b/include/linux/netfs.h @@ -220,7 +220,8 @@ struct netfs_cache_ops { * actually do. */ int (*prepare_write)(struct netfs_cache_resources *cres, - loff_t *_start, size_t *_len, loff_t i_size); + loff_t *_start, size_t *_len, loff_t i_size, + bool no_space_allocated_yet); /* Prepare a write operation for the fallback fscache API, working out * whether we can cache a page or not. From patchwork Mon Oct 18 14:59:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567103 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D2C4EC433FE for ; Mon, 18 Oct 2021 15:00:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B3E6161074 for ; Mon, 18 Oct 2021 15:00:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232879AbhJRPCX (ORCPT ); Mon, 18 Oct 2021 11:02:23 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:37149 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233049AbhJRPCW (ORCPT ); Mon, 18 Oct 2021 11:02:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569210; 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=b/gZcyOT12TFKnNipl9VJdyVU0Aa1uUb86IiYe5LXiA=; b=YTOhspTb+yzZo2mexDhulrNspJ4sx6UJitX3L6LPt5N5rwPTVahoA2HPGWQ9ZppXC1yPwI CedyyuTZBLlAcC4Hhg/I6LPMn1AZnktQZLu7KFpDI4N4re5I647r+Ah19jon0ZVtknxICm 67G/RlfIQq1+8lJ7Bd3JAlDaA3ZkAxU= 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-445-qPTHu9zDMMuiURJoIoLBmQ-1; Mon, 18 Oct 2021 11:00:07 -0400 X-MC-Unique: qPTHu9zDMMuiURJoIoLBmQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 316CE9F92C; Mon, 18 Oct 2021 15:00:02 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id B6A8560C17; Mon, 18 Oct 2021 14:59:58 +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 35/67] fscache: Automatically close a file that's been unused for a while From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 15:59:57 +0100 Message-ID: <163456919786.2614702.17176086827977019423.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org When a cache object becomes fully unused, schedule it to be committed and closed after a few seconds if not re-used. Signed-off-by: David Howells --- fs/fscache/cookie.c | 108 +++++++++++++++++++++++++++++++++++++++- fs/fscache/io.c | 2 + include/linux/fscache.h | 5 +- include/trace/events/fscache.h | 8 +++ 4 files changed, 120 insertions(+), 3 deletions(-) diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 90a16e6d6917..dfc61b2e105d 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -15,6 +15,8 @@ struct kmem_cache *fscache_cookie_jar; +static void fscache_cookie_lru_timed_out(struct timer_list *timer); +static void fscache_cookie_lru_worker(struct work_struct *work); static void fscache_cookie_worker(struct work_struct *work); static void fscache_drop_cookie(struct fscache_cookie *cookie); static void fscache_lookup_cookie(struct fscache_cookie *cookie); @@ -24,7 +26,12 @@ static void fscache_invalidate_cookie(struct fscache_cookie *cookie); static struct hlist_bl_head fscache_cookie_hash[1 << fscache_cookie_hash_shift]; static LIST_HEAD(fscache_cookies); static DEFINE_RWLOCK(fscache_cookies_lock); -static const char fscache_cookie_stages[FSCACHE_COOKIE_STAGE__NR] = "-LCAIFWRD"; +static LIST_HEAD(fscache_cookie_lru); +static DEFINE_SPINLOCK(fscache_cookie_lru_lock); +static DEFINE_TIMER(fscache_cookie_lru_timer, fscache_cookie_lru_timed_out); +static DECLARE_WORK(fscache_cookie_lru_work, fscache_cookie_lru_worker); +static const char fscache_cookie_stages[FSCACHE_COOKIE_STAGE__NR] = "-LCAIFMWRD"; +unsigned int fscache_lru_cookie_timeout = 10 * HZ; void fscache_print_cookie(struct fscache_cookie *cookie, char prefix) { @@ -49,6 +56,11 @@ void fscache_print_cookie(struct fscache_cookie *cookie, char prefix) static void fscache_free_cookie(struct fscache_cookie *cookie) { + if (WARN_ON_ONCE(!list_empty(&cookie->commit_link))) { + spin_lock(&fscache_cookie_lru_lock); + list_del_init(&cookie->commit_link); + spin_unlock(&fscache_cookie_lru_lock); + } write_lock(&fscache_cookies_lock); list_del(&cookie->proc_link); write_unlock(&fscache_cookies_lock); @@ -265,6 +277,7 @@ static struct fscache_cookie *fscache_alloc_cookie( cookie->debug_id = atomic_inc_return(&fscache_cookie_debug_id); cookie->stage = FSCACHE_COOKIE_STAGE_QUIESCENT; spin_lock_init(&cookie->lock); + INIT_LIST_HEAD(&cookie->commit_link); INIT_WORK(&cookie->work, fscache_cookie_worker); write_lock(&fscache_cookies_lock); @@ -448,6 +461,7 @@ void __fscache_use_cookie(struct fscache_cookie *cookie, bool will_modify) atomic_inc(&cookie->n_active); +again: stage = cookie->stage; switch (stage) { case FSCACHE_COOKIE_STAGE_QUIESCENT: @@ -474,6 +488,13 @@ void __fscache_use_cookie(struct fscache_cookie *cookie, bool will_modify) case FSCACHE_COOKIE_STAGE_WITHDRAWING: break; + case FSCACHE_COOKIE_STAGE_COMMITTING: + spin_unlock(&cookie->lock); + wait_var_event(&cookie->stage, + READ_ONCE(cookie->stage) != FSCACHE_COOKIE_STAGE_COMMITTING); + spin_lock(&cookie->lock); + goto again; + case FSCACHE_COOKIE_STAGE_DROPPED: case FSCACHE_COOKIE_STAGE_RELINQUISHING: WARN(1, "Can't use cookie in stage %u\n", cookie->stage); @@ -497,7 +518,19 @@ void __fscache_unuse_cookie(struct fscache_cookie *cookie, { if (aux_data || object_size) __fscache_update_cookie(cookie, aux_data, object_size); - atomic_dec(&cookie->n_active); + cookie->unused_at = jiffies; + if (atomic_dec_return(&cookie->n_active) == 0) { + if (test_bit(FSCACHE_COOKIE_IS_CACHING, &cookie->flags)) { + spin_lock(&fscache_cookie_lru_lock); + if (list_empty(&cookie->commit_link)) { + fscache_get_cookie(cookie, fscache_cookie_get_lru); + list_move_tail(&cookie->commit_link, &fscache_cookie_lru); + } + spin_unlock(&fscache_cookie_lru_lock); + timer_reduce(&fscache_cookie_lru_timer, + jiffies + fscache_lru_cookie_timeout); + } + } } EXPORT_SYMBOL(__fscache_unuse_cookie); @@ -532,6 +565,7 @@ static void __fscache_cookie_worker(struct fscache_cookie *cookie) case FSCACHE_COOKIE_STAGE_FAILED: break; + case FSCACHE_COOKIE_STAGE_COMMITTING: case FSCACHE_COOKIE_STAGE_RELINQUISHING: case FSCACHE_COOKIE_STAGE_WITHDRAWING: if (test_and_clear_bit(FSCACHE_COOKIE_IS_CACHING, &cookie->flags) && @@ -541,6 +575,8 @@ static void __fscache_cookie_worker(struct fscache_cookie *cookie) fscache_see_cookie(cookie, fscache_cookie_see_relinquish); fscache_drop_cookie(cookie); break; + } else if (cookie->stage == FSCACHE_COOKIE_STAGE_COMMITTING) { + fscache_see_cookie(cookie, fscache_cookie_see_committing); } else { fscache_see_cookie(cookie, fscache_cookie_see_withdraw); } @@ -550,6 +586,7 @@ static void __fscache_cookie_worker(struct fscache_cookie *cookie) case FSCACHE_COOKIE_STAGE_DROPPED: clear_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &cookie->flags); clear_bit(FSCACHE_COOKIE_DO_WITHDRAW, &cookie->flags); + clear_bit(FSCACHE_COOKIE_DO_COMMIT, &cookie->flags); set_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags); fscache_set_cookie_stage(cookie, FSCACHE_COOKIE_STAGE_QUIESCENT); break; @@ -578,6 +615,72 @@ static void __fscache_withdraw_cookie(struct fscache_cookie *cookie) __fscache_end_cookie_access(cookie); } +static void fscache_cookie_lru_do_one(struct fscache_cookie *cookie) +{ + fscache_see_cookie(cookie, fscache_cookie_see_lru_do_one); + + spin_lock(&cookie->lock); + if (cookie->stage != FSCACHE_COOKIE_STAGE_ACTIVE || + time_before(jiffies, cookie->unused_at + fscache_lru_cookie_timeout) || + atomic_read(&cookie->n_active) > 0) { + spin_unlock(&cookie->lock); + } else { + __fscache_set_cookie_stage(cookie, FSCACHE_COOKIE_STAGE_COMMITTING); + set_bit(FSCACHE_COOKIE_DO_COMMIT, &cookie->flags); + spin_unlock(&cookie->lock); + _debug("lru c=%x", cookie->debug_id); + __fscache_withdraw_cookie(cookie); + } + + fscache_put_cookie(cookie, fscache_cookie_put_lru); +} + +static void fscache_cookie_lru_worker(struct work_struct *work) +{ + struct fscache_cookie *cookie; + unsigned long unused_at; + + spin_lock(&fscache_cookie_lru_lock); + + while (!list_empty(&fscache_cookie_lru)) { + cookie = list_first_entry(&fscache_cookie_lru, + struct fscache_cookie, commit_link); + unused_at = cookie->unused_at + fscache_lru_cookie_timeout; + if (time_before(jiffies, unused_at)) { + timer_reduce(&fscache_cookie_lru_timer, unused_at); + break; + } + + list_del_init(&cookie->commit_link); + spin_unlock(&fscache_cookie_lru_lock); + fscache_cookie_lru_do_one(cookie); + spin_lock(&fscache_cookie_lru_lock); + } + + spin_unlock(&fscache_cookie_lru_lock); +} + +static void fscache_cookie_lru_timed_out(struct timer_list *timer) +{ + queue_work(fscache_wq, &fscache_cookie_lru_work); +} + +static void fscache_cookie_drop_from_lru(struct fscache_cookie *cookie) +{ + bool need_put = false; + + if (!list_empty(&cookie->commit_link)) { + spin_lock(&fscache_cookie_lru_lock); + if (!list_empty(&cookie->commit_link)) { + list_del_init(&cookie->commit_link); + need_put = true; + } + spin_unlock(&fscache_cookie_lru_lock); + if (need_put) + fscache_put_cookie(cookie, fscache_cookie_put_lru); + } +} + /* * Ask the cache to effect invalidation of a cookie. */ @@ -687,6 +790,7 @@ static void fscache_drop_cookie(struct fscache_cookie *cookie) static void fscache_drop_withdraw_cookie(struct fscache_cookie *cookie) { + fscache_cookie_drop_from_lru(cookie); __fscache_withdraw_cookie(cookie); } diff --git a/fs/fscache/io.c b/fs/fscache/io.c index 2b1c9f433530..ef4b0606019d 100644 --- a/fs/fscache/io.c +++ b/fs/fscache/io.c @@ -43,6 +43,7 @@ bool fscache_wait_for_operation(struct netfs_cache_resources *cres, goto ready; /* There can be no content */ fallthrough; case FSCACHE_COOKIE_STAGE_LOOKING_UP: + case FSCACHE_COOKIE_STAGE_COMMITTING: wait_var_event(&cookie->stage, READ_ONCE(cookie->stage) != stage); goto again; @@ -92,6 +93,7 @@ static int fscache_begin_operation(struct netfs_cache_resources *cres, switch (stage) { case FSCACHE_COOKIE_STAGE_LOOKING_UP: + case FSCACHE_COOKIE_STAGE_COMMITTING: goto wait_and_validate; case FSCACHE_COOKIE_STAGE_INVALIDATING: case FSCACHE_COOKIE_STAGE_CREATING: diff --git a/include/linux/fscache.h b/include/linux/fscache.h index aeee14f5663a..c6ee09661351 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -59,6 +59,7 @@ enum fscache_cookie_stage { FSCACHE_COOKIE_STAGE_ACTIVE, /* The cache is active, readable and writable */ FSCACHE_COOKIE_STAGE_INVALIDATING, /* The cache is being invalidated */ FSCACHE_COOKIE_STAGE_FAILED, /* The cache failed, withdraw to clear */ + FSCACHE_COOKIE_STAGE_COMMITTING, /* The cookie is being committed */ FSCACHE_COOKIE_STAGE_WITHDRAWING, /* The cookie is being withdrawn */ FSCACHE_COOKIE_STAGE_RELINQUISHING, /* The cookie is being relinquished */ FSCACHE_COOKIE_STAGE_DROPPED, /* The cookie has been dropped */ @@ -108,9 +109,10 @@ struct fscache_cookie { void *cache_priv; /* Cache-side representation */ struct hlist_bl_node hash_link; /* Link in hash table */ struct list_head proc_link; /* Link in proc list */ + struct list_head commit_link; /* Link in commit queue */ struct work_struct work; /* Commit/relinq/withdraw work */ loff_t object_size; /* Size of the netfs object */ - + unsigned long unused_at; /* Time at which unused (jiffies) */ unsigned long flags; #define FSCACHE_COOKIE_RELINQUISHED 0 /* T if cookie has been relinquished */ #define FSCACHE_COOKIE_RETIRED 1 /* T if this cookie has retired on relinq */ @@ -121,6 +123,7 @@ struct fscache_cookie { #define FSCACHE_COOKIE_NACC_ELEVATED 8 /* T if n_accesses is incremented */ #define FSCACHE_COOKIE_DO_RELINQUISH 9 /* T if this cookie needs relinquishment */ #define FSCACHE_COOKIE_DO_WITHDRAW 10 /* T if this cookie needs withdrawing */ +#define FSCACHE_COOKIE_DO_COMMIT 11 /* T if this cookie needs committing */ enum fscache_cookie_stage stage; u8 advice; /* FSCACHE_ADV_* */ diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h index 0d9789745a91..50f28a2a4ca8 100644 --- a/include/trace/events/fscache.h +++ b/include/trace/events/fscache.h @@ -52,16 +52,20 @@ enum fscache_cookie_trace { fscache_cookie_get_end_access, fscache_cookie_get_hash_collision, fscache_cookie_get_inval_work, + fscache_cookie_get_lru, fscache_cookie_get_use_work, fscache_cookie_get_withdraw, fscache_cookie_new_acquire, fscache_cookie_put_hash_collision, + fscache_cookie_put_lru, fscache_cookie_put_object, fscache_cookie_put_over_queued, fscache_cookie_put_relinquish, fscache_cookie_put_withdrawn, fscache_cookie_put_work, fscache_cookie_see_active, + fscache_cookie_see_lru_do_one, + fscache_cookie_see_committing, fscache_cookie_see_relinquish, fscache_cookie_see_withdraw, fscache_cookie_see_work, @@ -127,16 +131,20 @@ enum fscache_access_trace { EM(fscache_cookie_get_hash_collision, "GET hcoll") \ EM(fscache_cookie_get_end_access, "GQ endac") \ EM(fscache_cookie_get_inval_work, "GQ inval") \ + EM(fscache_cookie_get_lru, "GET lru ") \ EM(fscache_cookie_get_use_work, "GQ use ") \ EM(fscache_cookie_get_withdraw, "GQ wthdr") \ EM(fscache_cookie_new_acquire, "NEW acq ") \ EM(fscache_cookie_put_hash_collision, "PUT hcoll") \ + EM(fscache_cookie_put_lru, "PUT lru ") \ EM(fscache_cookie_put_object, "PUT obj ") \ EM(fscache_cookie_put_over_queued, "PQ overq") \ EM(fscache_cookie_put_relinquish, "PUT relnq") \ EM(fscache_cookie_put_withdrawn, "PUT wthdn") \ EM(fscache_cookie_put_work, "PQ work ") \ EM(fscache_cookie_see_active, "- active") \ + EM(fscache_cookie_see_lru_do_one, "- lrudo") \ + EM(fscache_cookie_see_committing, "- x-cmt") \ EM(fscache_cookie_see_relinquish, "- x-rlq") \ EM(fscache_cookie_see_withdraw, "- x-wth") \ E_(fscache_cookie_see_work, "- work ") From patchwork Mon Oct 18 15:00:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567105 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 570E1C433EF for ; Mon, 18 Oct 2021 15:00:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 426B6610A3 for ; Mon, 18 Oct 2021 15:00:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233056AbhJRPCf (ORCPT ); Mon, 18 Oct 2021 11:02:35 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:47375 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233127AbhJRPCb (ORCPT ); Mon, 18 Oct 2021 11:02:31 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569219; 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=G0Z0o/WV3mIg+DEa6x5tVtljedfdYDVPKK/rSOm0vTU=; b=R3iuuL71S6ECQBK/yPIWbRxHnGC9RpY67m1NiOEP1EBUjlayH9gClnpEkgW7ICgMhID9yn n7RwjGhOxbu9fDqzErwSiioLcgzkzoczI6g8askhosCl+k3OznqyBHefeNDhiJpiEkknt9 ts8NgBPtd+0UoAs3CPuK0e1Mu9mOcRE= 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-476-OVp8rcT5NZiDCc86yQYTJQ-1; Mon, 18 Oct 2021 11:00:16 -0400 X-MC-Unique: OVp8rcT5NZiDCc86yQYTJQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4D19A802682; Mon, 18 Oct 2021 15:00:14 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 511675D6D7; Mon, 18 Oct 2021 15:00:08 +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 36/67] fscache: Add stats for the cookie commit LRU From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:00:07 +0100 Message-ID: <163456920740.2614702.10833323576114946075.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Add some stats to indicate the state of the cookie commit LRU, including an indication of how many are currently on it, how many have been expired, removed (withdrawn/reused) or dropped (relinquished) from it and how long till the next reap happens. Signed-off-by: David Howells --- fs/fscache/cookie.c | 10 +++++++++- fs/fscache/internal.h | 5 +++++ fs/fscache/stats.c | 12 ++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index dfc61b2e105d..c6b553609f33 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -28,7 +28,7 @@ static LIST_HEAD(fscache_cookies); static DEFINE_RWLOCK(fscache_cookies_lock); static LIST_HEAD(fscache_cookie_lru); static DEFINE_SPINLOCK(fscache_cookie_lru_lock); -static DEFINE_TIMER(fscache_cookie_lru_timer, fscache_cookie_lru_timed_out); +DEFINE_TIMER(fscache_cookie_lru_timer, fscache_cookie_lru_timed_out); static DECLARE_WORK(fscache_cookie_lru_work, fscache_cookie_lru_worker); static const char fscache_cookie_stages[FSCACHE_COOKIE_STAGE__NR] = "-LCAIFMWRD"; unsigned int fscache_lru_cookie_timeout = 10 * HZ; @@ -60,6 +60,8 @@ static void fscache_free_cookie(struct fscache_cookie *cookie) spin_lock(&fscache_cookie_lru_lock); list_del_init(&cookie->commit_link); spin_unlock(&fscache_cookie_lru_lock); + fscache_stat_d(&fscache_n_cookies_lru); + fscache_stat(&fscache_n_cookies_lru_removed); } write_lock(&fscache_cookies_lock); list_del(&cookie->proc_link); @@ -525,6 +527,7 @@ void __fscache_unuse_cookie(struct fscache_cookie *cookie, if (list_empty(&cookie->commit_link)) { fscache_get_cookie(cookie, fscache_cookie_get_lru); list_move_tail(&cookie->commit_link, &fscache_cookie_lru); + fscache_stat(&fscache_n_cookies_lru); } spin_unlock(&fscache_cookie_lru_lock); timer_reduce(&fscache_cookie_lru_timer, @@ -624,10 +627,12 @@ static void fscache_cookie_lru_do_one(struct fscache_cookie *cookie) time_before(jiffies, cookie->unused_at + fscache_lru_cookie_timeout) || atomic_read(&cookie->n_active) > 0) { spin_unlock(&cookie->lock); + fscache_stat(&fscache_n_cookies_lru_removed); } else { __fscache_set_cookie_stage(cookie, FSCACHE_COOKIE_STAGE_COMMITTING); set_bit(FSCACHE_COOKIE_DO_COMMIT, &cookie->flags); spin_unlock(&cookie->lock); + fscache_stat(&fscache_n_cookies_lru_expired); _debug("lru c=%x", cookie->debug_id); __fscache_withdraw_cookie(cookie); } @@ -652,6 +657,7 @@ static void fscache_cookie_lru_worker(struct work_struct *work) } list_del_init(&cookie->commit_link); + fscache_stat_d(&fscache_n_cookies_lru); spin_unlock(&fscache_cookie_lru_lock); fscache_cookie_lru_do_one(cookie); spin_lock(&fscache_cookie_lru_lock); @@ -673,6 +679,8 @@ static void fscache_cookie_drop_from_lru(struct fscache_cookie *cookie) spin_lock(&fscache_cookie_lru_lock); if (!list_empty(&cookie->commit_link)) { list_del_init(&cookie->commit_link); + fscache_stat_d(&fscache_n_cookies_lru); + fscache_stat(&fscache_n_cookies_lru_dropped); need_put = true; } spin_unlock(&fscache_cookie_lru_lock); diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index f74f7bdea633..62e6a5bbef8e 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h @@ -32,6 +32,7 @@ struct fscache_cache *fscache_lookup_cache(const char *name, bool is_cache); */ extern struct kmem_cache *fscache_cookie_jar; extern const struct seq_operations fscache_cookies_seq_ops; +extern struct timer_list fscache_cookie_lru_timer; extern void fscache_print_cookie(struct fscache_cookie *cookie, char prefix); extern bool fscache_begin_cookie_access(struct fscache_cookie *cookie, @@ -70,6 +71,10 @@ extern atomic_t fscache_n_volumes; extern atomic_t fscache_n_volumes_collision; extern atomic_t fscache_n_volumes_nomem; extern atomic_t fscache_n_cookies; +extern atomic_t fscache_n_cookies_lru; +extern atomic_t fscache_n_cookies_lru_expired; +extern atomic_t fscache_n_cookies_lru_removed; +extern atomic_t fscache_n_cookies_lru_dropped; extern atomic_t fscache_n_retrievals; extern atomic_t fscache_n_retrievals_ok; diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c index 13e90b940bd2..5700e5712018 100644 --- a/fs/fscache/stats.c +++ b/fs/fscache/stats.c @@ -18,6 +18,10 @@ atomic_t fscache_n_volumes; atomic_t fscache_n_volumes_collision; atomic_t fscache_n_volumes_nomem; atomic_t fscache_n_cookies; +atomic_t fscache_n_cookies_lru; +atomic_t fscache_n_cookies_lru_expired; +atomic_t fscache_n_cookies_lru_removed; +atomic_t fscache_n_cookies_lru_dropped; atomic_t fscache_n_retrievals; atomic_t fscache_n_retrievals_ok; @@ -89,6 +93,14 @@ int fscache_stats_show(struct seq_file *m, void *v) atomic_read(&fscache_n_acquires_nobufs), atomic_read(&fscache_n_acquires_oom)); + seq_printf(m, "LRU : n=%u exp=%u rmv=%u drp=%u at=%ld\n", + atomic_read(&fscache_n_cookies_lru), + atomic_read(&fscache_n_cookies_lru_expired), + atomic_read(&fscache_n_cookies_lru_removed), + atomic_read(&fscache_n_cookies_lru_dropped), + timer_pending(&fscache_cookie_lru_timer) ? + fscache_cookie_lru_timer.expires - jiffies : 0); + seq_printf(m, "Invals : n=%u run=%u\n", atomic_read(&fscache_n_invalidates), atomic_read(&fscache_n_invalidates_run)); From patchwork Mon Oct 18 15:00:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567107 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AE1A0C433EF for ; Mon, 18 Oct 2021 15:00:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9A2546103D for ; Mon, 18 Oct 2021 15:00:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233103AbhJRPCw (ORCPT ); Mon, 18 Oct 2021 11:02:52 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:32916 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233223AbhJRPCm (ORCPT ); Mon, 18 Oct 2021 11:02:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569231; 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=d1PPrqrxGOJrlgwg8gulFUWciRFXvDwTO+SwsfF1Gf8=; b=hkwcI+0kwt6K4o16hCpTI525vFvFpT+SXiRkZ28a+g+0SAT77789QQSfQU1GXdlOeVYkUs 4YD1549YEcpr0En1YS0T8VuR1vtmE7L6yYCfrOoGQEJa4KOBVNbeJ+6/qtVHfkZ9ymjp6f z8p9tJ69fiLrsDiTwStF0oCYVZ/Ijxg= 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-386-HreReUItP1K4SxpQq7cwIA-1; Mon, 18 Oct 2021 11:00:25 -0400 X-MC-Unique: HreReUItP1K4SxpQq7cwIA-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 AC8B6A40C3; Mon, 18 Oct 2021 15:00:23 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 73D9360D30; Mon, 18 Oct 2021 15:00:20 +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 37/67] fscache: Move fscache_update_cookie() complete inline From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:00:19 +0100 Message-ID: <163456921953.2614702.8851027265019457749.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org --- fs/fscache/cookie.c | 18 ----------------- fs/fscache/internal.h | 18 ----------------- fs/fscache/stats.c | 9 +++------ include/linux/fscache-cache.h | 11 ---------- include/linux/fscache.h | 43 ++++++++++++++++++++++++++++++++++++++++- 5 files changed, 45 insertions(+), 54 deletions(-) diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index c6b553609f33..94976f90dc71 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -748,24 +748,6 @@ void __fscache_invalidate(struct fscache_cookie *cookie) } EXPORT_SYMBOL(__fscache_invalidate); -/* - * Update the index entries backing a cookie. The writeback is done lazily. - */ -void __fscache_update_cookie(struct fscache_cookie *cookie, - const void *aux_data, const loff_t *object_size) -{ - fscache_stat(&fscache_n_updates); - - spin_lock(&cookie->lock); - - fscache_update_aux(cookie, aux_data, object_size); - set_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &cookie->flags); - - spin_unlock(&cookie->lock); - _leave(""); -} -EXPORT_SYMBOL(__fscache_update_cookie); - /* * Remove a cookie from the hash table. */ diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index 62e6a5bbef8e..1cb1effa7cba 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h @@ -107,10 +107,6 @@ extern atomic_t fscache_n_acquires_oom; extern atomic_t fscache_n_invalidates; extern atomic_t fscache_n_invalidates_run; -extern atomic_t fscache_n_updates; -extern atomic_t fscache_n_updates_null; -extern atomic_t fscache_n_updates_run; - extern atomic_t fscache_n_relinquishes; extern atomic_t fscache_n_relinquishes_null; extern atomic_t fscache_n_relinquishes_retire; @@ -152,20 +148,6 @@ bool fscache_begin_volume_access(struct fscache_volume *volume, enum fscache_access_trace why); void fscache_create_volume(struct fscache_volume *volume, bool wait); -/* - * Update the auxiliary data on a cookie. - */ -static inline -void fscache_update_aux(struct fscache_cookie *cookie, - const void *aux_data, const loff_t *object_size) -{ - void *p = fscache_get_aux(cookie); - - if (aux_data && p) - memcpy(p, aux_data, cookie->aux_len); - if (object_size) - cookie->object_size = *object_size; -} /*****************************************************************************/ /* diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c index 5700e5712018..a16473df8be0 100644 --- a/fs/fscache/stats.c +++ b/fs/fscache/stats.c @@ -55,8 +55,7 @@ atomic_t fscache_n_invalidates; atomic_t fscache_n_invalidates_run; atomic_t fscache_n_updates; -atomic_t fscache_n_updates_null; -atomic_t fscache_n_updates_run; +EXPORT_SYMBOL(fscache_n_updates); atomic_t fscache_n_relinquishes; atomic_t fscache_n_relinquishes_null; @@ -105,10 +104,8 @@ int fscache_stats_show(struct seq_file *m, void *v) atomic_read(&fscache_n_invalidates), atomic_read(&fscache_n_invalidates_run)); - seq_printf(m, "Updates: n=%u nul=%u run=%u\n", - atomic_read(&fscache_n_updates), - atomic_read(&fscache_n_updates_null), - atomic_read(&fscache_n_updates_run)); + seq_printf(m, "Updates: n=%u\n", + atomic_read(&fscache_n_updates)); seq_printf(m, "Relinqs: n=%u rtr=%u drop=%u\n", atomic_read(&fscache_n_relinquishes), diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index 657e54b4cd90..bf0d3e862915 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -139,17 +139,6 @@ static inline void *fscache_get_key(struct fscache_cookie *cookie) return cookie->key; } -/* - * Find the auxiliary data on a cookie. - */ -static inline void *fscache_get_aux(struct fscache_cookie *cookie) -{ - if (cookie->aux_len <= sizeof(cookie->inline_aux)) - return cookie->inline_aux; - else - return cookie->aux; -} - /** * fscache_cookie_lookup_negative - Note negative lookup * @cookie: The cookie that was being looked up diff --git a/include/linux/fscache.h b/include/linux/fscache.h index c6ee09661351..41e579ff65ee 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -159,7 +159,6 @@ extern struct fscache_cookie *__fscache_acquire_cookie( extern void __fscache_use_cookie(struct fscache_cookie *, bool); extern void __fscache_unuse_cookie(struct fscache_cookie *, const void *, const loff_t *); extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool); -extern void __fscache_update_cookie(struct fscache_cookie *, const void *, const loff_t *); extern void __fscache_invalidate(struct fscache_cookie *); #ifdef FSCACHE_USE_NEW_IO_API extern int __fscache_begin_read_operation(struct netfs_cache_resources *, struct fscache_cookie *); @@ -293,6 +292,48 @@ void fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire) __fscache_relinquish_cookie(cookie, retire); } +/* + * Find the auxiliary data on a cookie. + */ +static inline void *fscache_get_aux(struct fscache_cookie *cookie) +{ + if (cookie->aux_len <= sizeof(cookie->inline_aux)) + return cookie->inline_aux; + else + return cookie->aux; +} + +/* + * Update the auxiliary data on a cookie. + */ +static inline +void fscache_update_aux(struct fscache_cookie *cookie, + const void *aux_data, const loff_t *object_size) +{ + void *p = fscache_get_aux(cookie); + + if (aux_data && p) + memcpy(p, aux_data, cookie->aux_len); + if (object_size) + cookie->object_size = *object_size; +} + +#ifdef CONFIG_FSCACHE_STATS +extern atomic_t fscache_n_updates; +#endif + +static inline +void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data, + const loff_t *object_size) +{ +#ifdef CONFIG_FSCACHE_STATS + atomic_inc(&fscache_n_updates); +#endif + fscache_update_aux(cookie, aux_data, object_size); + smp_wmb(); + set_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &cookie->flags); +} + /** * fscache_update_cookie - Request that a cache object be updated * @cookie: The cookie representing the cache object From patchwork Mon Oct 18 15:00:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567109 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F2A38C433F5 for ; Mon, 18 Oct 2021 15:00:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DAC87610A3 for ; Mon, 18 Oct 2021 15:00:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233106AbhJRPC5 (ORCPT ); Mon, 18 Oct 2021 11:02:57 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:20611 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233207AbhJRPCx (ORCPT ); Mon, 18 Oct 2021 11:02:53 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569242; 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=0rLWjOac2bldltPLSIvO7t4xwzOfczTlvO1pL5kPDYk=; b=bzipQAIsjMrV11iBqzSqtPppzlefxhmrvwPSa12U1LmrKgU0xkNpGANyq6kqxqL3B9+xDF BRcqTsye1KduA/q75bYPZRi3ExoB7h3RqTzN9QTdTsm2LTHmc4ZXtMBdu4TsUwktaoA+9F Sm/M+VRce5UGH/Co4CLWmYyxkh/i538= 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-272-hJFmt2ErMya7D3FK-BzwiQ-1; Mon, 18 Oct 2021 11:00:35 -0400 X-MC-Unique: hJFmt2ErMya7D3FK-BzwiQ-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 B317180DDE1; Mon, 18 Oct 2021 15:00:32 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id A878A60D30; Mon, 18 Oct 2021 15:00:29 +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 38/67] fscache: Remove more obsolete stats From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:00:28 +0100 Message-ID: <163456922892.2614702.12945425715751699836.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Remove some more stats that have become obsolete. Signed-off-by: David Howells --- fs/fscache/internal.h | 3 --- fs/fscache/stats.c | 13 +++---------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index 1cb1effa7cba..65fb4e88f655 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h @@ -101,14 +101,11 @@ extern atomic_t fscache_n_acquires; extern atomic_t fscache_n_acquires_null; extern atomic_t fscache_n_acquires_no_cache; extern atomic_t fscache_n_acquires_ok; -extern atomic_t fscache_n_acquires_nobufs; extern atomic_t fscache_n_acquires_oom; extern atomic_t fscache_n_invalidates; -extern atomic_t fscache_n_invalidates_run; extern atomic_t fscache_n_relinquishes; -extern atomic_t fscache_n_relinquishes_null; extern atomic_t fscache_n_relinquishes_retire; extern atomic_t fscache_n_relinquishes_dropped; diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c index a16473df8be0..44b3b901e191 100644 --- a/fs/fscache/stats.c +++ b/fs/fscache/stats.c @@ -6,7 +6,6 @@ */ #define FSCACHE_DEBUG_LEVEL CACHE -#include #include #include #include "internal.h" @@ -48,17 +47,14 @@ atomic_t fscache_n_acquires; atomic_t fscache_n_acquires_null; atomic_t fscache_n_acquires_no_cache; atomic_t fscache_n_acquires_ok; -atomic_t fscache_n_acquires_nobufs; atomic_t fscache_n_acquires_oom; atomic_t fscache_n_invalidates; -atomic_t fscache_n_invalidates_run; atomic_t fscache_n_updates; EXPORT_SYMBOL(fscache_n_updates); atomic_t fscache_n_relinquishes; -atomic_t fscache_n_relinquishes_null; atomic_t fscache_n_relinquishes_retire; atomic_t fscache_n_relinquishes_dropped; @@ -83,13 +79,11 @@ int fscache_stats_show(struct seq_file *m, void *v) atomic_read(&fscache_n_volumes_nomem) ); - seq_printf(m, "Acquire: n=%u nul=%u noc=%u ok=%u nbf=%u" - " oom=%u\n", + seq_printf(m, "Acquire: n=%u nul=%u noc=%u ok=%u oom=%u\n", atomic_read(&fscache_n_acquires), atomic_read(&fscache_n_acquires_null), atomic_read(&fscache_n_acquires_no_cache), atomic_read(&fscache_n_acquires_ok), - atomic_read(&fscache_n_acquires_nobufs), atomic_read(&fscache_n_acquires_oom)); seq_printf(m, "LRU : n=%u exp=%u rmv=%u drp=%u at=%ld\n", @@ -100,9 +94,8 @@ int fscache_stats_show(struct seq_file *m, void *v) timer_pending(&fscache_cookie_lru_timer) ? fscache_cookie_lru_timer.expires - jiffies : 0); - seq_printf(m, "Invals : n=%u run=%u\n", - atomic_read(&fscache_n_invalidates), - atomic_read(&fscache_n_invalidates_run)); + seq_printf(m, "Invals : n=%u\n", + atomic_read(&fscache_n_invalidates)); seq_printf(m, "Updates: n=%u\n", atomic_read(&fscache_n_updates)); From patchwork Mon Oct 18 15:00:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567111 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C6617C433FE for ; Mon, 18 Oct 2021 15:02:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AF74760EC0 for ; Mon, 18 Oct 2021 15:02:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233313AbhJRPEW (ORCPT ); Mon, 18 Oct 2021 11:04:22 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:43639 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233284AbhJRPDH (ORCPT ); Mon, 18 Oct 2021 11:03:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569255; 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=De0jqwH/v0yTKtY0BasvsuLkI5xzm/i5IM30qZPwEs0=; b=D1cIsx8l5YFU5IlJCL9syhUClH4++BICXPbkIOLBEQGA1z/y2gziD5qpSf3sMwIiyRpspg W7NNLb5KcHZIjBZD08Rb44iXLNCnKC3HspgKDbg07PffCIK76KTzE0cO45pv5k1DHepllQ g4Evh88KpvFVSLS+jQqTjFSxuxiArpY= 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-387-oRDe2hXsMXKdtd5p2LIFWw-1; Mon, 18 Oct 2021 11:00:44 -0400 X-MC-Unique: oRDe2hXsMXKdtd5p2LIFWw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 228148042E1; Mon, 18 Oct 2021 15:00:42 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id D793660BF4; Mon, 18 Oct 2021 15:00:38 +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 39/67] fscache: Note the object size during invalidation From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:00:37 +0100 Message-ID: <163456923795.2614702.17791069992979263352.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Note the size of the cache object during invalidation. For AFS, we set this to the file size when invalidating a file due to third-party interference. Signed-off-by: David Howells --- fs/afs/inode.c | 2 +- fs/fscache/cookie.c | 3 ++- include/linux/fscache.h | 7 ++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/fs/afs/inode.c b/fs/afs/inode.c index c2f4afff9837..c21c1352b149 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -565,7 +565,7 @@ static void afs_zap_data(struct afs_vnode *vnode) _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode); #ifdef CONFIG_AFS_FSCACHE - fscache_invalidate(vnode->cache); + fscache_invalidate(vnode->cache, i_size_read(&vnode->vfs_inode)); #endif /* nuke all the non-dirty pages that aren't locked, mapped or being diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 94976f90dc71..6b49c2321256 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -704,7 +704,7 @@ static void fscache_invalidate_cookie(struct fscache_cookie *cookie) /* * Invalidate an object. Callable with spinlocks held. */ -void __fscache_invalidate(struct fscache_cookie *cookie) +void __fscache_invalidate(struct fscache_cookie *cookie, loff_t new_size) { bool is_caching; @@ -718,6 +718,7 @@ void __fscache_invalidate(struct fscache_cookie *cookie) spin_lock(&cookie->lock); set_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags); + cookie->object_size = new_size; cookie->inval_counter++; switch (cookie->stage) { diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 41e579ff65ee..fa7eef2674bf 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -159,7 +159,7 @@ extern struct fscache_cookie *__fscache_acquire_cookie( extern void __fscache_use_cookie(struct fscache_cookie *, bool); extern void __fscache_unuse_cookie(struct fscache_cookie *, const void *, const loff_t *); extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool); -extern void __fscache_invalidate(struct fscache_cookie *); +extern void __fscache_invalidate(struct fscache_cookie *, loff_t); #ifdef FSCACHE_USE_NEW_IO_API extern int __fscache_begin_read_operation(struct netfs_cache_resources *, struct fscache_cookie *); #endif @@ -388,6 +388,7 @@ void fscache_unpin_cookie(struct fscache_cookie *cookie) /** * fscache_invalidate - Notify cache that an object needs invalidation * @cookie: The cookie representing the cache object + * @size: The revised size of the object. * * Notify the cache that an object is needs to be invalidated and that it * should abort any retrievals or stores it is doing on the cache. The object @@ -399,10 +400,10 @@ void fscache_unpin_cookie(struct fscache_cookie *cookie) * description. */ static inline -void fscache_invalidate(struct fscache_cookie *cookie) +void fscache_invalidate(struct fscache_cookie *cookie, loff_t size) { if (fscache_cookie_valid(cookie)) - __fscache_invalidate(cookie); + __fscache_invalidate(cookie, size); } /** From patchwork Mon Oct 18 15:00:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567127 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E4F2FC4332F for ; Mon, 18 Oct 2021 15:03:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D09446103D for ; Mon, 18 Oct 2021 15:03:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233095AbhJRPFL (ORCPT ); Mon, 18 Oct 2021 11:05:11 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:40790 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233371AbhJRPDI (ORCPT ); Mon, 18 Oct 2021 11:03:08 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569256; 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=Xp2LKQx9if5tGosngwP99n5iEOkL5LnpG8JtI6hikwc=; b=MdvdYSE8JT+w/BGbcrbVM1D7XGd+HxAZsiYNuWQzrTWskUUpQI+kgmmFsDiCIT+BwUVGhg I0P7KQRUQi7qCU68omx8Q52IknW6AFY/zDIBgDo9uDvBYcmtnrCPrsgaLBOHS9Wbe4LVOC FpKZ+NqPUTHQ7bxnmcW9uo/usQW2IG4= 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-258-74102ZF3MtCUjCBHtUJWNQ-1; Mon, 18 Oct 2021 11:00:53 -0400 X-MC-Unique: 74102ZF3MtCUjCBHtUJWNQ-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7C760100CCC0; Mon, 18 Oct 2021 15:00:51 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 420DC1980E; Mon, 18 Oct 2021 15:00:48 +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 40/67] vfs, fscache: Force ->write_inode() to occur if cookie pinned for writeback From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:00:47 +0100 Message-ID: <163456924735.2614702.11449131617169771724.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Use an inode flag, I_PINNING_FSCACHE_WB, to indicate that a cookie is pinned in use by that inode for the purposes of writeback. Pinning is necessary because the in-use pin from the open file is released before the writeback takes place, but if the resources aren't pinned, the dirty data can't be written to the cache. Signed-off-by: David Howells --- fs/fscache/io.c | 38 ++++++++++++++++++++++++++++++++++++++ include/linux/fscache.h | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/fs/fscache/io.c b/fs/fscache/io.c index ef4b0606019d..25976413fe34 100644 --- a/fs/fscache/io.c +++ b/fs/fscache/io.c @@ -214,3 +214,41 @@ int __fscache_fallback_write_page(struct fscache_cookie *cookie, struct page *pa return ret; } EXPORT_SYMBOL(__fscache_fallback_write_page); + +/** + * fscache_set_page_dirty - Mark page dirty and pin a cache object for writeback + * @page: The page being dirtied + * @cookie: The cookie referring to the cache object + * + * Set the dirty flag on a page and pin an in-use cache object in memory when + * dirtying a page so that writeback can later write to it. This is intended + * to be called from the filesystem's ->set_page_dirty() method. + * + * Returns 1 if PG_dirty was set on the page, 0 otherwise. + */ +int fscache_set_page_dirty(struct page *page, struct fscache_cookie *cookie) +{ + struct inode *inode = page->mapping->host; + bool need_use = false; + + _enter(""); + + if (!__set_page_dirty_nobuffers(page)) + return 0; + if (!fscache_cookie_valid(cookie)) + return 1; + + if (!(inode->i_state & I_PINNING_FSCACHE_WB)) { + spin_lock(&inode->i_lock); + if (!(inode->i_state & I_PINNING_FSCACHE_WB)) { + inode->i_state |= I_PINNING_FSCACHE_WB; + need_use = true; + } + spin_unlock(&inode->i_lock); + + if (need_use) + fscache_use_cookie(cookie, true); + } + return 1; +} +EXPORT_SYMBOL(fscache_set_page_dirty); diff --git a/include/linux/fscache.h b/include/linux/fscache.h index fa7eef2674bf..abf5413c3151 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -512,6 +512,47 @@ int fscache_write(struct netfs_cache_resources *cres, #endif /* FSCACHE_USE_NEW_IO_API */ +#if __fscache_available +extern int fscache_set_page_dirty(struct page *page, struct fscache_cookie *cookie); +#else +#define fscache_set_page_dirty(PAGE, COOKIE) (__set_page_dirty_nobuffers((PAGE))) +#endif + +/** + * fscache_unpin_writeback - Unpin writeback resources + * @wbc: The writeback control + * @cookie: The cookie referring to the cache object + * + * Unpin the writeback resources pinned by fscache_set_page_dirty(). This is + * intended to be called by the netfs's ->write_inode() method. + */ +static inline void fscache_unpin_writeback(struct writeback_control *wbc, + struct fscache_cookie *cookie) +{ + if (wbc->unpinned_fscache_wb) + fscache_unuse_cookie(cookie, NULL, NULL); +} + +/** + * fscache_clear_inode_writeback - Clear writeback resources pinned by an inode + * @cookie: The cookie referring to the cache object + * @inode: The inode to clean up + * @aux: Auxiliary data to apply to the inode + * + * Clear any writeback resources held by an inode when the inode is evicted. + * This must be called before clear_inode() is called. + */ +static inline void fscache_clear_inode_writeback(struct fscache_cookie *cookie, + struct inode *inode, + const void *aux) +{ + if (inode->i_state & I_PINNING_FSCACHE_WB) { + loff_t i_size = i_size_read(inode); + fscache_unuse_cookie(cookie, aux, &i_size); + } + +} + #ifdef FSCACHE_USE_FALLBACK_IO_API /** From patchwork Mon Oct 18 15:00:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567113 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 02EA0C433F5 for ; Mon, 18 Oct 2021 15:02:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DC4F260EC0 for ; Mon, 18 Oct 2021 15:02:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232067AbhJRPEi (ORCPT ); Mon, 18 Oct 2021 11:04:38 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:43241 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233476AbhJRPDT (ORCPT ); Mon, 18 Oct 2021 11:03:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569267; 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=tyfueRWcvZbFZpicF1tHL+3lmAtJffKA8+YjsGo6828=; b=J/PepAiR/xLvL0ukququJkxldIXIFFWwZEB+4UpT+A/PF1Yt6XSY6oErxbEc+QrWfi0POi OM8kTM2szKQKyOmiKFosvF08unCHgem6MkRvXfOTz8VtJ6Eyf31UqJo7vncISIOWIyiX11 JmWcH/RJ+K7N1Bxe/9hzOMtO34dHVo4= 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-321-2IzxT3O8Mg-udXAv-P67-Q-1; Mon, 18 Oct 2021 11:01:04 -0400 X-MC-Unique: 2IzxT3O8Mg-udXAv-P67-Q-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D4C4C80DDE3; Mon, 18 Oct 2021 15:01:00 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 943FF60BF4; Mon, 18 Oct 2021 15:00: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 41/67] afs: Render cache cookie key as big endian From: David Howells To: linux-cachefs@redhat.com Cc: Marc Dionne , linux-afs@lists.infradead.org, dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:00:56 +0100 Message-ID: <163456925673.2614702.17571187496574827113.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Render the parts of the cookie key for an afs inode cookie as big endian. Signed-off-by: David Howells cc: Marc Dionne cc: linux-afs@lists.infradead.org --- fs/afs/file.c | 2 +- fs/afs/inode.c | 16 ++++++++-------- fs/afs/internal.h | 8 +++++++- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/fs/afs/file.c b/fs/afs/file.c index b4666da93b54..5e29d433960d 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -189,7 +189,7 @@ int afs_release(struct inode *inode, struct file *file) if ((file->f_mode & FMODE_WRITE)) { i_size = i_size_read(&vnode->vfs_inode); - aux.data_version = vnode->status.data_version; + afs_set_cache_aux(vnode, &aux); fscache_unuse_cookie(afs_vnode_cache(vnode), &aux, &i_size); } else { fscache_unuse_cookie(afs_vnode_cache(vnode), NULL, NULL); diff --git a/fs/afs/inode.c b/fs/afs/inode.c index c21c1352b149..842570e4470f 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -413,9 +413,9 @@ static void afs_get_inode_cache(struct afs_vnode *vnode) { #ifdef CONFIG_AFS_FSCACHE struct { - u32 vnode_id; - u32 unique; - u32 vnode_id_ext[2]; /* Allow for a 96-bit key */ + __be32 vnode_id; + __be32 unique; + __be32 vnode_id_ext[2]; /* Allow for a 96-bit key */ } __packed key; struct afs_vnode_cache_aux aux; @@ -424,11 +424,11 @@ static void afs_get_inode_cache(struct afs_vnode *vnode) return; } - key.vnode_id = vnode->fid.vnode; - key.unique = vnode->fid.unique; - key.vnode_id_ext[0] = vnode->fid.vnode >> 32; - key.vnode_id_ext[1] = vnode->fid.vnode_hi; - aux.data_version = vnode->status.data_version; + key.vnode_id = htonl(vnode->fid.vnode); + key.unique = htonl(vnode->fid.unique); + key.vnode_id_ext[0] = htonl(vnode->fid.vnode >> 32); + key.vnode_id_ext[1] = htonl(vnode->fid.vnode_hi); + afs_set_cache_aux(vnode, &aux); vnode->cache = fscache_acquire_cookie( vnode->volume->cache, diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 8e168c3fa5d1..3180ba6bd46d 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -869,9 +869,15 @@ struct afs_operation { * Cache auxiliary data. */ struct afs_vnode_cache_aux { - u64 data_version; + __be64 data_version; } __packed; +static inline void afs_set_cache_aux(struct afs_vnode *vnode, + struct afs_vnode_cache_aux *aux) +{ + aux->data_version = cpu_to_be64(vnode->status.data_version); +} + /* * We use page->private to hold the amount of the page that we've written to, * splitting the field into two parts. However, we need to represent a range From patchwork Mon Oct 18 15:01:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567117 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D4F24C433F5 for ; Mon, 18 Oct 2021 15:02:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B1C9A60E0C for ; Mon, 18 Oct 2021 15:02:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233279AbhJRPEj (ORCPT ); Mon, 18 Oct 2021 11:04:39 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:58473 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233559AbhJRPD1 (ORCPT ); Mon, 18 Oct 2021 11:03:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569275; 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=X/VMVPY3Zd09milyYLfDMV0nw0wF/nfvqEV6fmUcSps=; b=StTyaL0qnueHb74wtf9TnwMx+PdVKEs13P8fLNQ619zRFidNRv8YQWGxQuyH2v3DOEB52+ DZT6OSzE/9ppDUWVla2lsM5UV3176PlUPKB7hP4UfZjHfF8mkIL9/VeV6OvPH7CoWtDdMu zaOmePtr9+XFhm+yMXPNrsaSnHR5/bE= 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-272-LJGDIiC4MxavSMMQ0x2aqg-1; Mon, 18 Oct 2021 11:01:12 -0400 X-MC-Unique: LJGDIiC4MxavSMMQ0x2aqg-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3FBC880DDE1; Mon, 18 Oct 2021 15:01:10 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id DD31A5C1D0; Mon, 18 Oct 2021 15:01:06 +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 42/67] cachefiles: Use tmpfile/link From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:01:06 +0100 Message-ID: <163456926609.2614702.17249270156115609970.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Make cachefiles use a temporary file (created with vfs_tmpfile()) for a new file rather than creating it immediately. This means we don't have to wait exclusively on the directory's inode lock at this point. The directory entry creation is then deferred to the point at which the file is committed. Indeed, if the file is deleted before that point, it can just be abandoned without ever modifying the directory. Invalidation is achieved by simply closing the old file and creating a new tmpfile. Any in-progress ops hold the old file open till they've finished. We don't need to cancel them and can just deal with reissuing a read to the server upon completion (that will be a separate patch). Note: This would be easier if linkat() could be given a flag to indicate the destination should be overwritten or if RENAME_EXCHANGE could be applied to tmpfiles, effectively unlinking the destination. Signed-off-by: David Howells --- fs/cachefiles/interface.c | 85 +++++++++----- fs/cachefiles/internal.h | 9 ++ fs/cachefiles/namei.c | 219 ++++++++++++++++++++++++++----------- include/trace/events/cachefiles.h | 48 ++++++-- 4 files changed, 251 insertions(+), 110 deletions(-) diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index d186a68ff810..a114b59e5b29 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -197,6 +197,9 @@ static void cachefiles_commit_object(struct cachefiles_object *object, update = true; if (update) cachefiles_update_object(object); + + if (test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) + cachefiles_commit_tmpfile(cache, object); } /* @@ -206,9 +209,14 @@ static void cachefiles_clean_up_object(struct cachefiles_object *object, struct cachefiles_cache *cache) { if (test_bit(FSCACHE_COOKIE_RETIRED, &object->cookie->flags)) { - cachefiles_see_object(object, cachefiles_obj_see_clean_delete); - _debug("- inval object OBJ%x", object->debug_id); - cachefiles_delete_object(object, FSCACHE_OBJECT_WAS_RETIRED); + if (!test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) { + cachefiles_see_object(object, cachefiles_obj_see_clean_delete); + _debug("- inval object OBJ%x", object->debug_id); + cachefiles_delete_object(object, FSCACHE_OBJECT_WAS_RETIRED); + } else { + cachefiles_see_object(object, cachefiles_obj_see_clean_drop_tmp); + _debug("- inval object OBJ%x tmpfile", object->debug_id); + } } else { cachefiles_see_object(object, cachefiles_obj_see_clean_commit); cachefiles_commit_object(object, cache); @@ -372,41 +380,58 @@ static bool cachefiles_invalidate_cookie(struct fscache_cookie *cookie, unsigned int flags) { struct cachefiles_object *object = cookie->cache_priv; - struct cachefiles_cache *cache = object->volume->cache; - const struct cred *saved_cred; - struct file *file = object->file; - uint64_t ni_size = cookie->object_size; - int ret; + struct file *new_file, *old_file; + bool old_tmpfile; - _enter("{OBJ%x},[%llu]", - object->debug_id, (unsigned long long)ni_size); + _enter("o=%x,[%llu]", object->debug_id, object->cookie->object_size); - if (file) { - ASSERT(d_is_reg(file->f_path.dentry)); + old_tmpfile = test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags); - cachefiles_begin_secure(cache, &saved_cred); - trace_cachefiles_trunc(object, file_inode(file), - i_size_read(file_inode(file)), 0, - cachefiles_trunc_invalidate); - ret = vfs_truncate(&file->f_path, 0); - if (ret == 0) { - ni_size = round_up(ni_size, CACHEFILES_DIO_BLOCK_SIZE); - trace_cachefiles_trunc(object, file_inode(file), - 0, ni_size, - cachefiles_trunc_set_size); - ret = vfs_truncate(&file->f_path, ni_size); - } - cachefiles_end_secure(cache, saved_cred); + if (!object->file) { + fscache_set_cookie_stage(cookie, FSCACHE_COOKIE_STAGE_ACTIVE); + _leave(" = t [light]"); + return true; + } + + new_file = cachefiles_create_tmpfile(object); + if (IS_ERR(new_file)) + goto failed; + + /* Substitute the VFS target */ + _debug("sub"); + spin_lock(&object->lock); + + old_file = object->file; + object->file = new_file; + set_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags); + set_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &object->cookie->flags); + + spin_unlock(&object->lock); + _debug("subbed"); + + /* Allow I/O to take place again */ + fscache_set_cookie_stage(cookie, FSCACHE_COOKIE_STAGE_ACTIVE); - if (ret != 0) { - if (ret == -EIO) - cachefiles_io_error_obj(object, - "Invalidate failed"); - return false; + if (old_file) { + if (!old_tmpfile) { + struct cachefiles_volume *volume = object->volume; + struct dentry *fan = volume->fanout[(u8)object->key_hash]; + + inode_lock_nested(d_inode(fan), I_MUTEX_PARENT); + cachefiles_bury_object(volume->cache, object, fan, + old_file->f_path.dentry, + FSCACHE_OBJECT_INVALIDATED); } + fput(old_file); } + _leave(" = t"); return true; + +failed: + fscache_set_cookie_stage(cookie, FSCACHE_COOKIE_STAGE_FAILED); + _leave(" = f"); + return false; } const struct fscache_cache_ops cachefiles_cache_ops = { diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index d8a70ecbe94a..6cc22c85c8f2 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -59,6 +59,7 @@ struct cachefiles_object { u8 key_hash; /* Hash of object key */ unsigned long flags; #define CACHEFILES_OBJECT_IS_NEW 0 /* Set if object is new */ +#define CACHEFILES_OBJECT_USING_TMPFILE 1 /* Have an unlinked tmpfile */ }; extern struct kmem_cache *cachefiles_object_jar; @@ -171,6 +172,11 @@ extern bool cachefiles_cook_key(struct cachefiles_object *object); * namei.c */ extern void cachefiles_unmark_inode_in_use(struct cachefiles_object *object); +extern int cachefiles_bury_object(struct cachefiles_cache *cache, + struct cachefiles_object *object, + struct dentry *dir, + struct dentry *rep, + enum fscache_why_object_killed why); extern int cachefiles_delete_object(struct cachefiles_object *object, enum fscache_why_object_killed why); extern bool cachefiles_walk_to_object(struct cachefiles_object *object); @@ -183,6 +189,9 @@ extern int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir, extern int cachefiles_check_in_use(struct cachefiles_cache *cache, struct dentry *dir, char *filename); +extern struct file *cachefiles_create_tmpfile(struct cachefiles_object *object); +extern bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache, + struct cachefiles_object *object); /* * security.c diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index f7e73aba9104..0edf1276768b 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -80,11 +80,11 @@ static void cachefiles_mark_object_inactive(struct cachefiles_object *object) * - directory backed objects are stuffed into the graveyard for userspace to * delete */ -static int cachefiles_bury_object(struct cachefiles_cache *cache, - struct cachefiles_object *object, - struct dentry *dir, - struct dentry *rep, - enum fscache_why_object_killed why) +int cachefiles_bury_object(struct cachefiles_cache *cache, + struct cachefiles_object *object, + struct dentry *dir, + struct dentry *rep, + enum fscache_why_object_killed why) { struct dentry *grave, *trap; struct path path, path_to_graveyard; @@ -302,83 +302,73 @@ static int cachefiles_open_file(struct cachefiles_object *object, { struct cachefiles_cache *cache = object->volume->cache; struct dentry *dentry; - struct inode *dinode = d_backing_inode(fan), *inode; struct file *file; - struct path fan_path, path; + struct path path; int ret; _enter("%pd %s", fan, object->d_name); - inode_lock_nested(dinode, I_MUTEX_PARENT); - - dentry = lookup_one_len(object->d_name, fan, object->d_name_len); + dentry = lookup_positive_unlocked(object->d_name, fan, object->d_name_len); trace_cachefiles_lookup(object, dentry); - if (IS_ERR(dentry)) { - ret = PTR_ERR(dentry); - goto error_unlock; - } - - if (d_is_negative(dentry)) { + if (dentry == ERR_PTR(-ENOENT)) { + set_bit(CACHEFILES_OBJECT_IS_NEW, &object->flags); fscache_cookie_lookup_negative(object->cookie); ret = cachefiles_has_space(cache, 1, 0); if (ret < 0) - goto error_dput; - - fan_path.mnt = cache->mnt; - fan_path.dentry = fan; - ret = security_path_mknod(&fan_path, dentry, S_IFREG, 0); - if (ret < 0) - goto error_dput; - ret = vfs_create(&init_user_ns, dinode, dentry, S_IFREG, true); - trace_cachefiles_create(object, dentry, ret); - if (ret < 0) - goto error_dput; + goto error; - inode = d_backing_inode(dentry); - _debug("create -> %pd{ino=%lu}", dentry, inode->i_ino); - set_bit(CACHEFILES_OBJECT_IS_NEW, &object->flags); + file = cachefiles_create_tmpfile(object); + if (IS_ERR(file)) { + ret = PTR_ERR(file); + goto error; + } - } else if (!d_is_reg(dentry)) { - inode = d_backing_inode(dentry); - pr_err("inode %lu is not a file\n", inode->i_ino); - ret = -EIO; - goto error_dput; - } else { - inode = d_backing_inode(dentry); - _debug("file -> %pd positive", dentry); + set_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &object->cookie->flags); + set_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags); + _debug("create -> %pD{ino=%lu}", file, file_inode(file)->i_ino); + goto out; } - inode_unlock(dinode); - - /* We need to open a file interface onto a data file now as we can't do - * it on demand because writeback called from do_exit() sees - * current->fs == NULL - which breaks d_path() called from ext4 open. - */ - path.mnt = cache->mnt; - path.dentry = dentry; - file = open_with_fake_path(&path, O_RDWR | O_LARGEFILE | O_DIRECT, - inode, cache->cache_cred); - dput(dentry); - if (IS_ERR(file)) { - ret = PTR_ERR(file); + if (IS_ERR(dentry)) { + ret = PTR_ERR(dentry); goto error; } - if (unlikely(!file->f_op->read_iter) || - unlikely(!file->f_op->write_iter)) { - pr_notice("Cache does not support read_iter and write_iter\n"); + + if (!d_is_reg(dentry)) { + pr_err("%pd is not a file\n", dentry); + dput(dentry); ret = -EIO; - goto error_fput; + goto error; + } else { + clear_bit(CACHEFILES_OBJECT_IS_NEW, &object->flags); + + /* We need to open a file interface onto a data file now as we + * can't do it on demand because writeback called from + * do_exit() sees current->fs == NULL - which breaks d_path() + * called from ext4 open. + */ + path.mnt = cache->mnt; + path.dentry = dentry; + file = open_with_fake_path(&path, O_RDWR | O_LARGEFILE | O_DIRECT, + d_backing_inode(dentry), cache->cache_cred); + dput(dentry); + if (IS_ERR(file)) { + ret = PTR_ERR(file); + goto error; + } + if (unlikely(!file->f_op->read_iter) || + unlikely(!file->f_op->write_iter)) { + pr_notice("Cache does not support read_iter and write_iter\n"); + ret = -EIO; + goto error_fput; + } + _debug("file -> %pd positive", dentry); } +out: object->file = file; return 0; - -error_dput: - dput(dentry); -error_unlock: - inode_unlock(dinode); - return ret; error_fput: fput(file); error: @@ -458,9 +448,11 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, /* we need to create the subdir if it doesn't exist yet */ if (d_is_negative(subdir)) { - ret = cachefiles_has_space(cache, 1, 0); - if (ret < 0) - goto mkdir_error; + if (cache->store) { + ret = cachefiles_has_space(cache, 1, 0); + if (ret < 0) + goto mkdir_error; + } _debug("attempt mkdir"); @@ -498,7 +490,6 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, if (!(d_backing_inode(subdir)->i_opflags & IOP_XATTR) || !d_backing_inode(subdir)->i_op->lookup || !d_backing_inode(subdir)->i_op->mkdir || - !d_backing_inode(subdir)->i_op->create || !d_backing_inode(subdir)->i_op->rename || !d_backing_inode(subdir)->i_op->rmdir || !d_backing_inode(subdir)->i_op->unlink) @@ -687,3 +678,101 @@ int cachefiles_check_in_use(struct cachefiles_cache *cache, struct dentry *dir, //_leave(" = 0"); return ret; } + +/* + * Create a temporary file and leave it unattached and un-xattr'd until the + * time comes to discard the object from memory. + */ +struct file *cachefiles_create_tmpfile(struct cachefiles_object *object) +{ + struct cachefiles_volume *volume = object->volume; + struct cachefiles_cache *cache = volume->cache; + const struct cred *saved_cred; + struct dentry *fan = volume->fanout[(u8)object->key_hash]; + struct file *file; + struct path path; + uint64_t ni_size = object->cookie->object_size; + long ret; + + ni_size = round_up(ni_size, CACHEFILES_DIO_BLOCK_SIZE); + + cachefiles_begin_secure(cache, &saved_cred); + + path.mnt = cache->mnt, + path.dentry = vfs_tmpfile(&init_user_ns, fan, S_IFREG, O_RDWR); + if (IS_ERR(path.dentry)) { + if (PTR_ERR(path.dentry) == -EIO) + cachefiles_io_error_obj(object, "Failed to create tmpfile"); + file = ERR_CAST(path.dentry); + goto out; + } + + trace_cachefiles_tmpfile(object, d_backing_inode(path.dentry)); + + if (ni_size > 0) { + trace_cachefiles_trunc(object, d_backing_inode(path.dentry), 0, ni_size, + cachefiles_trunc_expand_tmpfile); + ret = vfs_truncate(&path, ni_size); + if (ret < 0) { + file = ERR_PTR(ret); + goto out_dput; + } + } + + file = open_with_fake_path(&path, O_RDWR | O_LARGEFILE | O_DIRECT, + d_backing_inode(path.dentry), cache->cache_cred); + if (IS_ERR(file)) + goto out_dput; + if (unlikely(!file->f_op->read_iter) || + unlikely(!file->f_op->write_iter)) { + fput(file); + pr_notice("Cache does not support read_iter and write_iter\n"); + file = ERR_PTR(-EINVAL); + } + +out_dput: + dput(path.dentry); +out: + cachefiles_end_secure(cache, saved_cred); + return file; +} + +/* + * Attempt to link a temporary file into its rightful place in the cache. + */ +bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache, + struct cachefiles_object *object) +{ + struct cachefiles_volume *volume = object->volume; + struct dentry *dentry, *fan = volume->fanout[(u8)object->key_hash]; + bool success = false; + int ret; + + _enter(",%pD", object->file); + + inode_lock_nested(d_inode(fan), I_MUTEX_PARENT); + dentry = lookup_one_len(object->d_name, fan, object->d_name_len); + if (IS_ERR(dentry)) { + _debug("lookup fail %ld", PTR_ERR(dentry)); + goto out_unlock; + } + + ret = vfs_link(object->file->f_path.dentry, &init_user_ns, + d_inode(fan), dentry, NULL); + if (ret < 0) { + _debug("link fail %d", ret); + } else { + trace_cachefiles_link(object, file_inode(object->file)); + spin_lock(&object->lock); + /* TODO: Do we want to switch the file pointer to the new dentry? */ + clear_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags); + spin_unlock(&object->lock); + success = true; + } + + dput(dentry); +out_unlock: + inode_unlock(d_inode(fan)); + _leave(" = %u", success); + return success; +} diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h index d63e5fb46d27..c0632ee8cf69 100644 --- a/include/trace/events/cachefiles.h +++ b/include/trace/events/cachefiles.h @@ -35,6 +35,7 @@ enum cachefiles_obj_ref_trace { enum fscache_why_object_killed { FSCACHE_OBJECT_IS_STALE, + FSCACHE_OBJECT_INVALIDATED, FSCACHE_OBJECT_NO_SPACE, FSCACHE_OBJECT_WAS_RETIRED, FSCACHE_OBJECT_WAS_CULLED, @@ -54,9 +55,8 @@ enum cachefiles_coherency_trace { }; enum cachefiles_trunc_trace { - cachefiles_trunc_invalidate, - cachefiles_trunc_set_size, cachefiles_trunc_dio_adjust, + cachefiles_trunc_expand_tmpfile, cachefiles_trunc_shrink, }; @@ -78,6 +78,7 @@ enum cachefiles_prepare_read_trace { */ #define cachefiles_obj_kill_traces \ EM(FSCACHE_OBJECT_IS_STALE, "stale") \ + EM(FSCACHE_OBJECT_INVALIDATED, "inval") \ EM(FSCACHE_OBJECT_NO_SPACE, "no_space") \ EM(FSCACHE_OBJECT_WAS_RETIRED, "was_retired") \ E_(FSCACHE_OBJECT_WAS_CULLED, "was_culled") @@ -109,9 +110,8 @@ enum cachefiles_prepare_read_trace { E_(cachefiles_coherency_set_ok, "SET ok ") #define cachefiles_trunc_traces \ - EM(cachefiles_trunc_invalidate, "INVAL ") \ - EM(cachefiles_trunc_set_size, "SETSIZ") \ EM(cachefiles_trunc_dio_adjust, "DIOADJ") \ + EM(cachefiles_trunc_expand_tmpfile, "EXPTMP") \ E_(cachefiles_trunc_shrink, "SHRINK") #define cachefiles_prepare_read_traces \ @@ -200,26 +200,44 @@ TRACE_EVENT(cachefiles_lookup, __entry->obj, __entry->ino, __entry->error) ); -TRACE_EVENT(cachefiles_create, - TP_PROTO(struct cachefiles_object *obj, - struct dentry *de, int ret), +TRACE_EVENT(cachefiles_tmpfile, + TP_PROTO(struct cachefiles_object *obj, struct inode *backer), - TP_ARGS(obj, de, ret), + TP_ARGS(obj, backer), TP_STRUCT__entry( - __field(unsigned int, obj ) - __field(struct dentry *, de ) - __field(int, ret ) + __field(unsigned int, obj ) + __field(unsigned int, backer ) ), TP_fast_assign( __entry->obj = obj->debug_id; - __entry->de = de; - __entry->ret = ret; + __entry->backer = backer->i_ino; + ), + + TP_printk("o=%08x b=%08x", + __entry->obj, + __entry->backer) + ); + +TRACE_EVENT(cachefiles_link, + TP_PROTO(struct cachefiles_object *obj, struct inode *backer), + + TP_ARGS(obj, backer), + + TP_STRUCT__entry( + __field(unsigned int, obj ) + __field(unsigned int, backer ) + ), + + TP_fast_assign( + __entry->obj = obj->debug_id; + __entry->backer = backer->i_ino; ), - TP_printk("o=%08x d=%p r=%u", - __entry->obj, __entry->de, __entry->ret) + TP_printk("o=%08x b=%08x", + __entry->obj, + __entry->backer) ); TRACE_EVENT(cachefiles_unlink, From patchwork Mon Oct 18 15:01:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567115 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D803EC433FE for ; Mon, 18 Oct 2021 15:02:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C5767610A3 for ; Mon, 18 Oct 2021 15:02:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233373AbhJRPEl (ORCPT ); Mon, 18 Oct 2021 11:04:41 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:52348 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233627AbhJRPDe (ORCPT ); Mon, 18 Oct 2021 11:03:34 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569283; 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=AiokSUHP63IAgtyhFtYg1E8iTK1oEkZZd/Ii+eTDS9s=; b=eSCbTWtCkRIKtkxWxJ+HtIZv51dt/PEtU2x7QuybLXmDJ7xYn1k9vTwfrdzUpoGye74L3b W24i2jdyJrAUcezb4p/FXkwVdm3HNhlmMAq7Hk8pqBWTm8rr4GrbJMmZ4XIhDb9etXwxbL I0ResLOftLSGbMEmC2Tub6YYCXpuVA0= 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-481-16xKwpWINGSbwVakiWdDLA-1; Mon, 18 Oct 2021 11:01:21 -0400 X-MC-Unique: 16xKwpWINGSbwVakiWdDLA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 92B4C100CCC3; Mon, 18 Oct 2021 15:01:19 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 59B1A60BF4; Mon, 18 Oct 2021 15:01:16 +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 43/67] fscache: Rewrite invalidation From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:01:15 +0100 Message-ID: <163456927548.2614702.9118810769340245220.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Rewrite the fscache_invalidate() function. The following changes are made to fscache: (1) Invalidation is now ignored or allowed to proceed depending on the 'stage' a non-index cookie is in with respect to the backing object. (2) If invalidation is proceeds, it pins the object and holds a cookie access count for the duration to prevent the cache from going away. (3) The fscache_object struct is given an invalidation counter that is incremented every time fscache_invalidate() is called, even if the cookie is at a stage in which it cannot be applied. The counter, however, can be noted and applied retroactively later. (4) The invalidation counter is noted in the operation struct when a cache operation is begun and can be checked on operation completion to find out if any consequent metadata changes should be dropped. (5) New operations aren't allowed to proceed if the object is being invalidated. Signed-off-by: David Howells --- fs/afs/inode.c | 4 +--- fs/afs/internal.h | 9 +++++++++ fs/cachefiles/interface.c | 3 +-- fs/cachefiles/io.c | 4 ++-- fs/fscache/cookie.c | 14 +++++++------- fs/fscache/io.c | 1 + include/linux/fscache-cache.h | 3 +-- include/linux/fscache.h | 16 ++++++++++++---- include/linux/netfs.h | 1 + include/trace/events/fscache.h | 19 +++++++++++++++++++ 10 files changed, 54 insertions(+), 20 deletions(-) diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 842570e4470f..32038ccbce67 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -564,9 +564,7 @@ static void afs_zap_data(struct afs_vnode *vnode) { _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode); -#ifdef CONFIG_AFS_FSCACHE - fscache_invalidate(vnode->cache, i_size_read(&vnode->vfs_inode)); -#endif + afs_invalidate_cache(vnode, 0); /* nuke all the non-dirty pages that aren't locked, mapped or being * written back in a regular file and completely discard the pages in a diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 3180ba6bd46d..6c591b7c55f1 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -878,6 +878,15 @@ static inline void afs_set_cache_aux(struct afs_vnode *vnode, aux->data_version = cpu_to_be64(vnode->status.data_version); } +static inline void afs_invalidate_cache(struct afs_vnode *vnode, unsigned int flags) +{ + struct afs_vnode_cache_aux aux; + + afs_set_cache_aux(vnode, &aux); + fscache_invalidate(afs_vnode_cache(vnode), &aux, + i_size_read(&vnode->vfs_inode), flags); +} + /* * We use page->private to hold the amount of the page that we've written to, * splitting the field into two parts. However, we need to represent a range diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index a114b59e5b29..96a703d5f62c 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -376,8 +376,7 @@ static int cachefiles_attr_changed(struct cachefiles_object *object) /* * Invalidate the storage associated with a cookie. */ -static bool cachefiles_invalidate_cookie(struct fscache_cookie *cookie, - unsigned int flags) +static bool cachefiles_invalidate_cookie(struct fscache_cookie *cookie) { struct cachefiles_object *object = cookie->cache_priv; struct file *new_file, *old_file; diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index 350243b45dd5..67ea9f44931f 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -134,7 +134,7 @@ static int cachefiles_read(struct netfs_cache_resources *cres, ki->iocb.ki_ioprio = get_current_ioprio(); ki->skipped = skipped; ki->object = object; - ki->inval_counter = object->cookie->inval_counter; + ki->inval_counter = cres->inval_counter; ki->term_func = term_func; ki->term_func_priv = term_func_priv; ki->was_async = true; @@ -239,7 +239,7 @@ static int cachefiles_write(struct netfs_cache_resources *cres, ki->iocb.ki_hint = ki_hint_validate(file_write_hint(file)); ki->iocb.ki_ioprio = get_current_ioprio(); ki->object = object; - ki->inval_counter = object->cookie->inval_counter; + ki->inval_counter = cres->inval_counter; ki->start = start_pos; ki->len = len; ki->term_func = term_func; diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 6b49c2321256..8731188a5ac7 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -694,17 +694,16 @@ static void fscache_cookie_drop_from_lru(struct fscache_cookie *cookie) */ static void fscache_invalidate_cookie(struct fscache_cookie *cookie) { - if (cookie->volume->cache->ops->invalidate_cookie(cookie, 0)) - fscache_set_cookie_stage(cookie, FSCACHE_COOKIE_STAGE_ACTIVE); - else - fscache_set_cookie_stage(cookie, FSCACHE_COOKIE_STAGE_FAILED); + cookie->volume->cache->ops->invalidate_cookie(cookie); fscache_end_cookie_access(cookie, fscache_access_invalidate_cookie_end); } /* - * Invalidate an object. Callable with spinlocks held. + * Invalidate an object. */ -void __fscache_invalidate(struct fscache_cookie *cookie, loff_t new_size) +void __fscache_invalidate(struct fscache_cookie *cookie, + const void *aux_data, loff_t new_size, + unsigned int flags) { bool is_caching; @@ -718,8 +717,9 @@ void __fscache_invalidate(struct fscache_cookie *cookie, loff_t new_size) spin_lock(&cookie->lock); set_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags); - cookie->object_size = new_size; + fscache_update_aux(cookie, aux_data, &new_size); cookie->inval_counter++; + trace_fscache_invalidate(cookie, new_size); switch (cookie->stage) { case FSCACHE_COOKIE_STAGE_INVALIDATING: /* is_still_valid will catch it */ diff --git a/fs/fscache/io.c b/fs/fscache/io.c index 25976413fe34..ad9798f0c850 100644 --- a/fs/fscache/io.c +++ b/fs/fscache/io.c @@ -81,6 +81,7 @@ static int fscache_begin_operation(struct netfs_cache_resources *cres, cres->cache_priv = cookie; cres->cache_priv2 = NULL; cres->debug_id = cookie->debug_id; + cres->inval_counter = cookie->inval_counter; if (!fscache_begin_cookie_access(cookie, why)) return -ENOBUFS; diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index bf0d3e862915..22064611d182 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -67,8 +67,7 @@ struct fscache_cache_ops { void (*withdraw_cookie)(struct fscache_cookie *cookie); /* Invalidate an object */ - bool (*invalidate_cookie)(struct fscache_cookie *cookie, - unsigned int flags); + bool (*invalidate_cookie)(struct fscache_cookie *cookie); /* Begin an operation for the netfs lib */ bool (*begin_operation)(struct netfs_cache_resources *cres, diff --git a/include/linux/fscache.h b/include/linux/fscache.h index abf5413c3151..a29bd81996ea 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -159,7 +159,7 @@ extern struct fscache_cookie *__fscache_acquire_cookie( extern void __fscache_use_cookie(struct fscache_cookie *, bool); extern void __fscache_unuse_cookie(struct fscache_cookie *, const void *, const loff_t *); extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool); -extern void __fscache_invalidate(struct fscache_cookie *, loff_t); +extern void __fscache_invalidate(struct fscache_cookie *, const void *, loff_t, unsigned int); #ifdef FSCACHE_USE_NEW_IO_API extern int __fscache_begin_read_operation(struct netfs_cache_resources *, struct fscache_cookie *); #endif @@ -388,22 +388,30 @@ void fscache_unpin_cookie(struct fscache_cookie *cookie) /** * fscache_invalidate - Notify cache that an object needs invalidation * @cookie: The cookie representing the cache object + * @aux_data: The updated auxiliary data for the cookie (may be NULL) * @size: The revised size of the object. + * @flags: Invalidation flags (FSCACHE_INVAL_*) * * Notify the cache that an object is needs to be invalidated and that it * should abort any retrievals or stores it is doing on the cache. The object * is then marked non-caching until such time as the invalidation is complete. * - * This can be called with spinlocks held. + * FSCACHE_INVAL_LIGHT indicates that if the object has been invalidated and + * replaced by a temporary object, the temporary object need not be replaced + * again. This is primarily intended for use with FSCACHE_ADV_SINGLE_CHUNK. + * + * FSCACHE_INVAL_DIO_WRITE indicates that this is due to a direct I/O write and + * may cause caching to be suspended on this cookie. * * See Documentation/filesystems/caching/netfs-api.rst for a complete * description. */ static inline -void fscache_invalidate(struct fscache_cookie *cookie, loff_t size) +void fscache_invalidate(struct fscache_cookie *cookie, + const void *aux_data, loff_t size, unsigned int flags) { if (fscache_cookie_valid(cookie)) - __fscache_invalidate(cookie, size); + __fscache_invalidate(cookie, aux_data, size, flags); } /** diff --git a/include/linux/netfs.h b/include/linux/netfs.h index 99137486d351..3c70eef56599 100644 --- a/include/linux/netfs.h +++ b/include/linux/netfs.h @@ -103,6 +103,7 @@ struct netfs_cache_resources { void *cache_priv; void *cache_priv2; unsigned int debug_id; /* Cookie debug ID */ + unsigned int inval_counter; /* object->inval_counter at begin_op */ }; /* diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h index 50f28a2a4ca8..adde3bb61f0f 100644 --- a/include/trace/events/fscache.h +++ b/include/trace/events/fscache.h @@ -410,6 +410,25 @@ TRACE_EVENT(fscache_relinquish, __entry->n_active, __entry->flags, __entry->retire) ); +TRACE_EVENT(fscache_invalidate, + TP_PROTO(struct fscache_cookie *cookie, loff_t new_size), + + TP_ARGS(cookie, new_size), + + TP_STRUCT__entry( + __field(unsigned int, cookie ) + __field(loff_t, new_size ) + ), + + TP_fast_assign( + __entry->cookie = cookie->debug_id; + __entry->new_size = new_size; + ), + + TP_printk("c=%08x sz=%llx", + __entry->cookie, __entry->new_size) + ); + #endif /* _TRACE_FSCACHE_H */ /* This part must be outside protection */ From patchwork Mon Oct 18 15:01:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567119 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E6841C433EF for ; Mon, 18 Oct 2021 15:02:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D2D42610A1 for ; Mon, 18 Oct 2021 15:02:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233394AbhJRPEn (ORCPT ); Mon, 18 Oct 2021 11:04:43 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:58010 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233790AbhJRPDz (ORCPT ); Mon, 18 Oct 2021 11:03:55 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569303; 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=EuP1b5wi/prrLttPJMaPCO/uxdQhwIzMYqp5U826ZAY=; b=WWs1KaNAiw7Emwg7P5gd6MCFXT4ILwsNLmU+fe1SbGbRqBvmaBSZEZFhxK+HK5WtaM0Btn evjRMi9T6YK/cmpY2ZAlID2CrbtRf4W8kfiJaH4QG8Y4J7ofRlqsHCVJJqsOxQ7GwT8U5y QAAAEq9kmK3Gp9T0TfpVDeLMOaDTr+A= 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-467-bWgVBC04P6a3jJhJWZ1_LQ-1; Mon, 18 Oct 2021 11:01:40 -0400 X-MC-Unique: bWgVBC04P6a3jJhJWZ1_LQ-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id AD1AE101AFC3; Mon, 18 Oct 2021 15:01:37 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id B51751A7E9; Mon, 18 Oct 2021 15:01:25 +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 44/67] fscache: disable cookie when doing an invalidation for DIO write From: David Howells To: linux-cachefs@redhat.com Cc: Jeff Layton , dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:01:24 +0100 Message-ID: <163456928482.2614702.6139737560803005640.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org From: Jeff Layton O_DIRECT I/O is probably a good indicator that we don't need to be caching this file at the moment. Disable the cookie by treating it as we would a NULL cookie after the invalidation completes. Reenable when the last unuse is done. Signed-off-by: Jeff Layton Signed-off-by: David Howells --- fs/afs/file.c | 2 +- fs/fscache/cookie.c | 5 +++++ include/linux/fscache.h | 15 ++++++++++----- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/fs/afs/file.c b/fs/afs/file.c index 5e29d433960d..5e674a503c1b 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -357,7 +357,7 @@ static bool afs_is_cache_enabled(struct inode *inode) { struct fscache_cookie *cookie = afs_vnode_cache(AFS_FS_I(inode)); - return fscache_cookie_valid(cookie) && cookie->cache_priv; + return fscache_cookie_enabled(cookie) && cookie->cache_priv; } static int afs_begin_cache_operation(struct netfs_read_request *rreq) diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 8731188a5ac7..70bfbd269652 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -522,6 +522,7 @@ void __fscache_unuse_cookie(struct fscache_cookie *cookie, __fscache_update_cookie(cookie, aux_data, object_size); cookie->unused_at = jiffies; if (atomic_dec_return(&cookie->n_active) == 0) { + clear_bit(FSCACHE_COOKIE_DISABLED, &cookie->flags); if (test_bit(FSCACHE_COOKIE_IS_CACHING, &cookie->flags)) { spin_lock(&fscache_cookie_lru_lock); if (list_empty(&cookie->commit_link)) { @@ -715,6 +716,10 @@ void __fscache_invalidate(struct fscache_cookie *cookie, "Trying to invalidate relinquished cookie\n")) return; + if ((flags & FSCACHE_INVAL_DIO_WRITE) && + test_and_set_bit(FSCACHE_COOKIE_DISABLED, &cookie->flags)) + return; + spin_lock(&cookie->lock); set_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags); fscache_update_aux(cookie, aux_data, &new_size); diff --git a/include/linux/fscache.h b/include/linux/fscache.h index a29bd81996ea..08663ad7feed 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -28,12 +28,14 @@ #define fscache_volume_valid(volume) (volume) #define fscache_cookie_valid(cookie) (cookie) #define fscache_resources_valid(cres) ((cres)->cache_priv) +#define fscache_cookie_enabled(cookie) (cookie && !test_bit(FSCACHE_COOKIE_DISABLED, &cookie->flags)) #else #define __fscache_available (0) #define fscache_available() (0) #define fscache_volume_valid(volume) (0) #define fscache_cookie_valid(cookie) (0) #define fscache_resources_valid(cres) (false) +#define fscache_cookie_enabled(cookie) (0) #endif struct fscache_cookie; @@ -43,6 +45,8 @@ struct fscache_cookie; #define FSCACHE_ADV_WRITE_NOCACHE 0x02 /* Don't cache if written to locally */ #define FSCACHE_ADV_FALLBACK_IO 0x04 /* Going to use the fallback I/O API (dangerous) */ +#define FSCACHE_INVAL_DIO_WRITE 0x01 /* Invalidate due to DIO write */ + enum fscache_want_stage { FSCACHE_WANT_PARAMS, FSCACHE_WANT_WRITE, @@ -120,6 +124,7 @@ struct fscache_cookie { #define FSCACHE_COOKIE_NO_DATA_TO_READ 3 /* T if this cookie has nothing to read */ #define FSCACHE_COOKIE_NEEDS_UPDATE 4 /* T if attrs have been updated */ #define FSCACHE_COOKIE_HAS_BEEN_CACHED 5 /* T if cookie needs withdraw-on-relinq */ +#define FSCACHE_COOKIE_DISABLED 6 /* T if cookie has been disabled */ #define FSCACHE_COOKIE_NACC_ELEVATED 8 /* T if n_accesses is incremented */ #define FSCACHE_COOKIE_DO_RELINQUISH 9 /* T if this cookie needs relinquishment */ #define FSCACHE_COOKIE_DO_WITHDRAW 10 /* T if this cookie needs withdrawing */ @@ -352,7 +357,7 @@ static inline void fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data, const loff_t *object_size) { - if (fscache_cookie_valid(cookie)) + if (fscache_cookie_enabled(cookie)) __fscache_update_cookie(cookie, aux_data, object_size); } @@ -410,7 +415,7 @@ static inline void fscache_invalidate(struct fscache_cookie *cookie, const void *aux_data, loff_t size, unsigned int flags) { - if (fscache_cookie_valid(cookie)) + if (fscache_cookie_enabled(cookie)) __fscache_invalidate(cookie, aux_data, size, flags); } @@ -449,7 +454,7 @@ static inline int fscache_begin_read_operation(struct netfs_cache_resources *cres, struct fscache_cookie *cookie) { - if (fscache_cookie_valid(cookie)) + if (fscache_cookie_enabled(cookie)) return __fscache_begin_read_operation(cres, cookie); return -ENOBUFS; } @@ -578,7 +583,7 @@ static inline void fscache_clear_inode_writeback(struct fscache_cookie *cookie, static inline int fscache_fallback_read_page(struct fscache_cookie *cookie, struct page *page) { - if (fscache_cookie_valid(cookie)) + if (fscache_cookie_enabled(cookie)) return __fscache_fallback_read_page(cookie, page); return -ENOBUFS; } @@ -598,7 +603,7 @@ int fscache_fallback_read_page(struct fscache_cookie *cookie, struct page *page) static inline int fscache_fallback_write_page(struct fscache_cookie *cookie, struct page *page) { - if (fscache_cookie_valid(cookie)) + if (fscache_cookie_enabled(cookie)) return __fscache_fallback_write_page(cookie, page); return -ENOBUFS; } From patchwork Mon Oct 18 15:01:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567123 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0A743C4332F for ; Mon, 18 Oct 2021 15:02:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E358E60E0C for ; Mon, 18 Oct 2021 15:02:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233925AbhJRPEq (ORCPT ); Mon, 18 Oct 2021 11:04:46 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:27606 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233820AbhJRPEE (ORCPT ); Mon, 18 Oct 2021 11:04:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569312; 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=yningHCiF+JNcaDdJUvwrvzRunm5YGgC/t3Jjc4joZU=; b=XseBlPnNYbw8owc1E01FA7fpGqKaLhbCtiPc2L7UOFGX5pHG4Ze/+8oM788FS/AIGW95mL 6simKnA82Pmxi9RnBEUkuApkObl4Ghu5KV7LC2dLijUzfKzvhNcusPOEaqxLzDkP5O7Oin tLg78SwhTna4iPI4cvJAYCTOfEAShVg= 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-140-HgCP1VLlPdO0Eavo72OJyw-1; Mon, 18 Oct 2021 11:01:49 -0400 X-MC-Unique: HgCP1VLlPdO0Eavo72OJyw-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3B39F872FEF; Mon, 18 Oct 2021 15:01:47 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id B5405380; Mon, 18 Oct 2021 15:01:43 +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 45/67] cachefiles: Simplify the file lookup/creation/check code From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:01:42 +0100 Message-ID: <163456930292.2614702.7454348292713792435.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Simplify the code that does file lookup, creation and checking. Signed-off-by: David Howells --- fs/cachefiles/interface.c | 4 - fs/cachefiles/internal.h | 11 + fs/cachefiles/io.c | 2 fs/cachefiles/namei.c | 276 ++++++++++++++++++++----------------- fs/cachefiles/xattr.c | 6 - include/trace/events/cachefiles.h | 2 6 files changed, 160 insertions(+), 141 deletions(-) diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 96a703d5f62c..38ae34b7aaf4 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -79,7 +79,7 @@ static bool cachefiles_lookup_cookie(struct fscache_cookie *cookie) /* look up the key, creating any missing bits */ cachefiles_begin_secure(cache, &saved_cred); - success = cachefiles_walk_to_object(object); + success = cachefiles_look_up_object(object); cachefiles_end_secure(cache, saved_cred); if (!success) @@ -222,7 +222,7 @@ static void cachefiles_clean_up_object(struct cachefiles_object *object, cachefiles_commit_object(object, cache); } - cachefiles_unmark_inode_in_use(object); + cachefiles_unmark_inode_in_use(object, object->file); if (object->file) { fput(object->file); object->file = NULL; diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index 6cc22c85c8f2..a2d2ed2f19eb 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -58,8 +58,7 @@ struct cachefiles_object { u8 d_name_len; /* Length of filename */ u8 key_hash; /* Hash of object key */ unsigned long flags; -#define CACHEFILES_OBJECT_IS_NEW 0 /* Set if object is new */ -#define CACHEFILES_OBJECT_USING_TMPFILE 1 /* Have an unlinked tmpfile */ +#define CACHEFILES_OBJECT_USING_TMPFILE 0 /* Have an unlinked tmpfile */ }; extern struct kmem_cache *cachefiles_object_jar; @@ -171,7 +170,8 @@ extern bool cachefiles_cook_key(struct cachefiles_object *object); /* * namei.c */ -extern void cachefiles_unmark_inode_in_use(struct cachefiles_object *object); +extern void cachefiles_unmark_inode_in_use(struct cachefiles_object *object, + struct file *file); extern int cachefiles_bury_object(struct cachefiles_cache *cache, struct cachefiles_object *object, struct dentry *dir, @@ -179,7 +179,7 @@ extern int cachefiles_bury_object(struct cachefiles_cache *cache, enum fscache_why_object_killed why); extern int cachefiles_delete_object(struct cachefiles_object *object, enum fscache_why_object_killed why); -extern bool cachefiles_walk_to_object(struct cachefiles_object *object); +extern bool cachefiles_look_up_object(struct cachefiles_object *object); extern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, struct dentry *dir, const char *name); @@ -224,7 +224,8 @@ void cachefiles_withdraw_volume(struct cachefiles_volume *volume); * xattr.c */ extern int cachefiles_set_object_xattr(struct cachefiles_object *object); -extern int cachefiles_check_auxdata(struct cachefiles_object *object); +extern int cachefiles_check_auxdata(struct cachefiles_object *object, + struct file *file); extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, struct dentry *dentry); diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index 67ea9f44931f..9b3b55a94e66 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -525,7 +525,7 @@ bool cachefiles_begin_operation(struct netfs_cache_resources *cres, if (!cachefiles_cres_file(cres)) { cres->ops = &cachefiles_netfs_cache_ops; - if (object) { + if (object->file) { spin_lock(&object->lock); if (!cres->cache_priv2 && object->file) cres->cache_priv2 = get_file(object->file); diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 0edf1276768b..989df918570b 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -21,9 +21,10 @@ /* * Mark the backing file as being a cache file if it's not already in use so. */ -static bool cachefiles_mark_inode_in_use(struct cachefiles_object *object) +static bool cachefiles_mark_inode_in_use(struct cachefiles_object *object, + struct dentry *dentry) { - struct inode *inode = file_inode(object->file); + struct inode *inode = d_backing_inode(dentry); bool can_use = false; _enter(",%x", object->debug_id); @@ -45,9 +46,10 @@ static bool cachefiles_mark_inode_in_use(struct cachefiles_object *object) /* * Unmark a backing inode. */ -void cachefiles_unmark_inode_in_use(struct cachefiles_object *object) +void cachefiles_unmark_inode_in_use(struct cachefiles_object *object, + struct file *file) { - struct inode *inode = file_inode(object->file); + struct inode *inode = file_inode(file); if (!inode) return; @@ -61,10 +63,11 @@ void cachefiles_unmark_inode_in_use(struct cachefiles_object *object) /* * Mark an object as being inactive. */ -static void cachefiles_mark_object_inactive(struct cachefiles_object *object) +static void cachefiles_mark_object_inactive(struct cachefiles_object *object, + struct file *file) { struct cachefiles_cache *cache = object->volume->cache; - blkcnt_t i_blocks = file_inode(object->file)->i_blocks; + blkcnt_t i_blocks = file_inode(file)->i_blocks; /* This object can now be culled, so we need to let the daemon know * that there is something it can remove if it needs to. @@ -232,191 +235,180 @@ int cachefiles_bury_object(struct cachefiles_cache *cache, return 0; } +static int cachefiles_unlink(struct cachefiles_object *object, + struct dentry *fan, struct dentry *dentry, + enum fscache_why_object_killed why) +{ + struct path path = { + .mnt = object->volume->cache->mnt, + .dentry = fan, + }; + int ret; + + trace_cachefiles_unlink(object, dentry, why); + ret = security_path_unlink(&path, dentry); + if (ret == 0) + ret = vfs_unlink(&init_user_ns, d_backing_inode(fan), dentry, NULL); + return ret; +} + /* - * delete an object representation from the cache + * Delete a cache file. */ int cachefiles_delete_object(struct cachefiles_object *object, enum fscache_why_object_killed why) { struct cachefiles_volume *volume = object->volume; + struct dentry *dentry = object->file->f_path.dentry; struct dentry *fan = volume->fanout[(u8)object->key_hash]; + int ret; _enter(",OBJ%x{%pD}", object->debug_id, object->file); + /* Stop the dentry being negated if it's only pinned by a file struct. */ + dget(dentry); + inode_lock_nested(d_backing_inode(fan), I_MUTEX_PARENT); - return cachefiles_bury_object(volume->cache, object, fan, - object->file->f_path.dentry, why); + ret = cachefiles_unlink(object, fan, dentry, why); + inode_unlock(d_backing_inode(fan)); + dput(dentry); + + if (ret < 0 && ret != -ENOENT) + cachefiles_io_error(volume->cache, "Unlink failed"); + return ret; } /* - * Check the attributes on a file we've just opened and delete it if it's out - * of date. + * Create a new file. */ -static int cachefiles_check_open_object(struct cachefiles_object *object, - struct dentry *fan) +static bool cachefiles_create_file(struct cachefiles_object *object) { + struct file *file; int ret; - if (!cachefiles_mark_inode_in_use(object)) - return -EBUSY; - - _enter("%pD", object->file); - - ret = cachefiles_check_auxdata(object); - if (ret == -ESTALE) - goto stale; + ret = cachefiles_has_space(object->volume->cache, 1, 0); if (ret < 0) - goto error_unmark; + return false; - /* Always update the atime on an object we've just looked up (this is - * used to keep track of culling, and atimes are only updated by read, - * write and readdir but not lookup or open). - */ - touch_atime(&object->file->f_path); - return 0; - -stale: - set_bit(CACHEFILES_OBJECT_IS_NEW, &object->flags); - fscache_cookie_lookup_negative(object->cookie); - cachefiles_unmark_inode_in_use(object); - inode_lock_nested(d_inode(fan), I_MUTEX_PARENT); - ret = cachefiles_bury_object(object->volume->cache, object, fan, - object->file->f_path.dentry, - FSCACHE_OBJECT_IS_STALE); - if (ret < 0) - return ret; - cachefiles_mark_object_inactive(object); - _debug("redo lookup"); - return -ESTALE; + file = cachefiles_create_tmpfile(object); + if (IS_ERR(file)) + return false; -error_unmark: - cachefiles_unmark_inode_in_use(object); - return ret; + set_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &object->cookie->flags); + set_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags); + _debug("create -> %pD{ino=%lu}", file, file_inode(file)->i_ino); + object->file = file; + return true; } /* - * Look up a file, creating it if necessary. + * Open an existing file, checking its attributes and replacing it if it is + * stale. */ -static int cachefiles_open_file(struct cachefiles_object *object, - struct dentry *fan) +static bool cachefiles_open_file(struct cachefiles_object *object, + struct dentry *dentry) { struct cachefiles_cache *cache = object->volume->cache; - struct dentry *dentry; struct file *file; struct path path; int ret; - _enter("%pd %s", fan, object->d_name); + _enter("%pd", dentry); - dentry = lookup_positive_unlocked(object->d_name, fan, object->d_name_len); - trace_cachefiles_lookup(object, dentry); - if (dentry == ERR_PTR(-ENOENT)) { - set_bit(CACHEFILES_OBJECT_IS_NEW, &object->flags); - fscache_cookie_lookup_negative(object->cookie); - - ret = cachefiles_has_space(cache, 1, 0); - if (ret < 0) - goto error; + if (!cachefiles_mark_inode_in_use(object, dentry)) + return false; - file = cachefiles_create_tmpfile(object); - if (IS_ERR(file)) { - ret = PTR_ERR(file); - goto error; - } + /* We need to open a file interface onto a data file now as we can't do + * it on demand because writeback called from do_exit() sees + * current->fs == NULL - which breaks d_path() called from ext4 open. + */ + path.mnt = cache->mnt; + path.dentry = dentry; + file = open_with_fake_path(&path, O_RDWR | O_LARGEFILE | O_DIRECT, + d_backing_inode(dentry), cache->cache_cred); + if (IS_ERR(file)) + goto error; - set_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &object->cookie->flags); - set_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags); - _debug("create -> %pD{ino=%lu}", file, file_inode(file)->i_ino); - goto out; + if (unlikely(!file->f_op->read_iter) || + unlikely(!file->f_op->write_iter)) { + pr_notice("Cache does not support read_iter and write_iter\n"); + goto error_fput; } + _debug("file -> %pd positive", dentry); - if (IS_ERR(dentry)) { - ret = PTR_ERR(dentry); - goto error; - } + ret = cachefiles_check_auxdata(object, file); + if (ret < 0) + goto check_failed; - if (!d_is_reg(dentry)) { - pr_err("%pd is not a file\n", dentry); - dput(dentry); - ret = -EIO; - goto error; - } else { - clear_bit(CACHEFILES_OBJECT_IS_NEW, &object->flags); + object->file = file; - /* We need to open a file interface onto a data file now as we - * can't do it on demand because writeback called from - * do_exit() sees current->fs == NULL - which breaks d_path() - * called from ext4 open. - */ - path.mnt = cache->mnt; - path.dentry = dentry; - file = open_with_fake_path(&path, O_RDWR | O_LARGEFILE | O_DIRECT, - d_backing_inode(dentry), cache->cache_cred); + /* Always update the atime on an object we've just looked up (this is + * used to keep track of culling, and atimes are only updated by read, + * write and readdir but not lookup or open). + */ + touch_atime(&file->f_path); + dput(dentry); + return true; + +check_failed: + fscache_cookie_lookup_negative(object->cookie); + cachefiles_unmark_inode_in_use(object, file); + cachefiles_mark_object_inactive(object, file); + if (ret == -ESTALE) { + fput(file); dput(dentry); - if (IS_ERR(file)) { - ret = PTR_ERR(file); - goto error; - } - if (unlikely(!file->f_op->read_iter) || - unlikely(!file->f_op->write_iter)) { - pr_notice("Cache does not support read_iter and write_iter\n"); - ret = -EIO; - goto error_fput; - } - _debug("file -> %pd positive", dentry); + return cachefiles_create_file(object); } - -out: - object->file = file; - return 0; error_fput: fput(file); error: - return ret; + dput(dentry); + return false; } /* * walk from the parent object to the child object through the backing * filesystem, creating directories as we go */ -bool cachefiles_walk_to_object(struct cachefiles_object *object) +bool cachefiles_look_up_object(struct cachefiles_object *object) { - struct cachefiles_volume *volume = object->cookie->volume->cache_priv; - struct dentry *fan; + struct cachefiles_volume *volume = object->volume; + struct dentry *dentry, *fan = volume->fanout[(u8)object->key_hash]; int ret; _enter("OBJ%x,%s,", object->debug_id, object->d_name); -lookup_again: - /* Open path "cache/vol/fanout/file". */ - fan = volume->fanout[(u8)object->key_hash]; - ret = cachefiles_open_file(object, fan); - if (ret < 0) - goto lookup_error; + /* Look up path "cache/vol/fanout/file". */ + dentry = lookup_positive_unlocked(object->d_name, fan, object->d_name_len); + trace_cachefiles_lookup(object, dentry); + if (IS_ERR(dentry)) { + if (dentry == ERR_PTR(-ENOENT)) + goto new_file; + if (dentry == ERR_PTR(-EIO)) + cachefiles_io_error_obj(object, "Lookup failed"); + return false; + } - if (!test_bit(CACHEFILES_OBJECT_IS_NEW, &object->flags)) { - ret = cachefiles_check_open_object(object, fan); + if (!d_is_reg(dentry)) { + pr_err("%pd is not a file\n", dentry); + inode_lock_nested(d_inode(fan), I_MUTEX_PARENT); + ret = cachefiles_bury_object(volume->cache, object, fan, dentry, + FSCACHE_OBJECT_IS_WEIRD); + dput(dentry); if (ret < 0) - goto check_error; - } else { - ret = -EBUSY; - if (!cachefiles_mark_inode_in_use(object)) - goto check_error; + return false; + goto new_file; } - clear_bit(CACHEFILES_OBJECT_IS_NEW, &object->flags); + if (!cachefiles_open_file(object, dentry)) + return false; + _leave(" = t [%lu]", file_inode(object->file)->i_ino); return true; -check_error: - fput(object->file); - object->file = NULL; - if (ret == -ESTALE) - goto lookup_again; -lookup_error: - if (ret == -EIO) - cachefiles_io_error_obj(object, "Lookup failed"); - return false; +new_file: + fscache_cookie_lookup_negative(object->cookie); + return cachefiles_create_file(object); } /* @@ -709,6 +701,11 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object) trace_cachefiles_tmpfile(object, d_backing_inode(path.dentry)); + if (!cachefiles_mark_inode_in_use(object, path.dentry)) { + file = ERR_PTR(-EBUSY); + goto out_dput; + } + if (ni_size > 0) { trace_cachefiles_trunc(object, d_backing_inode(path.dentry), 0, ni_size, cachefiles_trunc_expand_tmpfile); @@ -757,6 +754,24 @@ bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache, goto out_unlock; } + if (!d_is_negative(dentry)) { + if (d_backing_inode(dentry) == file_inode(object->file)) { + success = true; + goto out_dput; + } + + ret = cachefiles_unlink(object, fan, dentry, FSCACHE_OBJECT_IS_STALE); + if (ret < 0) + goto out_dput; + + dput(dentry); + dentry = lookup_one_len(object->d_name, fan, object->d_name_len); + if (IS_ERR(dentry)) { + _debug("lookup fail %ld", PTR_ERR(dentry)); + goto out_unlock; + } + } + ret = vfs_link(object->file->f_path.dentry, &init_user_ns, d_inode(fan), dentry, NULL); if (ret < 0) { @@ -770,6 +785,7 @@ bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache, success = true; } +out_dput: dput(dentry); out_unlock: inode_unlock(d_inode(fan)); diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c index b77bbb6c4a17..50b2a4588946 100644 --- a/fs/cachefiles/xattr.c +++ b/fs/cachefiles/xattr.c @@ -74,10 +74,10 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object) /* * check the consistency between the backing cache and the FS-Cache cookie */ -int cachefiles_check_auxdata(struct cachefiles_object *object) +int cachefiles_check_auxdata(struct cachefiles_object *object, struct file *file) { struct cachefiles_xattr *buf; - struct dentry *dentry = object->file->f_path.dentry; + struct dentry *dentry = file->f_path.dentry; unsigned int len = object->cookie->aux_len, tlen; const void *p = fscache_get_aux(object->cookie); enum cachefiles_coherency_trace why; @@ -105,7 +105,7 @@ int cachefiles_check_auxdata(struct cachefiles_object *object) ret = 0; } - trace_cachefiles_coherency(object, file_inode(object->file)->i_ino, 0, why); + trace_cachefiles_coherency(object, file_inode(file)->i_ino, 0, why); kfree(buf); return ret; } diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h index c0632ee8cf69..a7b31b248f2d 100644 --- a/include/trace/events/cachefiles.h +++ b/include/trace/events/cachefiles.h @@ -35,6 +35,7 @@ enum cachefiles_obj_ref_trace { enum fscache_why_object_killed { FSCACHE_OBJECT_IS_STALE, + FSCACHE_OBJECT_IS_WEIRD, FSCACHE_OBJECT_INVALIDATED, FSCACHE_OBJECT_NO_SPACE, FSCACHE_OBJECT_WAS_RETIRED, @@ -78,6 +79,7 @@ enum cachefiles_prepare_read_trace { */ #define cachefiles_obj_kill_traces \ EM(FSCACHE_OBJECT_IS_STALE, "stale") \ + EM(FSCACHE_OBJECT_IS_WEIRD, "weird") \ EM(FSCACHE_OBJECT_INVALIDATED, "inval") \ EM(FSCACHE_OBJECT_NO_SPACE, "no_space") \ EM(FSCACHE_OBJECT_WAS_RETIRED, "was_retired") \ From patchwork Mon Oct 18 15:01:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567121 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8F9B6C4321E for ; Mon, 18 Oct 2021 15:02:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7C898610A3 for ; Mon, 18 Oct 2021 15:02:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232402AbhJRPEq (ORCPT ); Mon, 18 Oct 2021 11:04:46 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:30137 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233867AbhJRPEN (ORCPT ); Mon, 18 Oct 2021 11:04:13 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569322; 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=fpsHhxv8h1VlDaZzVY4rXIgEcTs8pJdyOkQWcL2oPB4=; b=TB9IMLsMjhexgLgYe5aIMqwZ0dvTX4QjeDU6n2yPHW5PswVPZLrGjgdOUF4nHyuw+OegGv 2aaAgyAogc6piW89Iv5rZm27sBGg9MBcXlApx2URQYUZtmKWAK9TP5ggkJw4GaP3jy6JIe bulrny8SgOA6e6bLnP8P3svMfQgQhog= 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-9-alfWoaFEP6y--Mpp1gBuyw-1; Mon, 18 Oct 2021 11:01:58 -0400 X-MC-Unique: alfWoaFEP6y--Mpp1gBuyw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 90E9BBAF88; Mon, 18 Oct 2021 15:01:56 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5A7465C1D0; Mon, 18 Oct 2021 15:01:53 +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 46/67] fscache: Provide resize operation From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:01:52 +0100 Message-ID: <163456931245.2614702.16508050783449263388.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Provide a cache operation to resize an object. This is intended to be run synchronously rather than being deferred as it really needs to run inside the inode lock on the netfs inode from ->setattr() to correctly order with respect to other truncates and writes. Signed-off-by: David Howells --- fs/cachefiles/interface.c | 93 ++++++++++++++++++++++++---------------- fs/fscache/io.c | 25 +++++++++++ fs/fscache/stats.c | 6 ++- include/linux/fscache-cache.h | 4 ++ include/linux/fscache.h | 18 ++++++++ include/trace/events/fscache.h | 23 ++++++++++ 6 files changed, 130 insertions(+), 39 deletions(-) diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 38ae34b7aaf4..f90f6ddd07a5 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "internal.h" @@ -134,55 +135,72 @@ struct cachefiles_object *cachefiles_grab_object(struct cachefiles_object *objec } /* - * update the auxiliary data for an object object on disk + * Shorten the backing object to discard any dirty data and free up + * any unused granules. */ -static void cachefiles_update_object(struct cachefiles_object *object) +static bool cachefiles_shorten_object(struct cachefiles_object *object, + struct file *file, loff_t new_size) { struct cachefiles_cache *cache = object->volume->cache; - const struct cred *saved_cred; - struct file *file = object->file; - loff_t object_size, i_size; + struct inode *inode = file_inode(file); + loff_t i_size, dio_size; int ret; - _enter("{OBJ%x}", object->debug_id); + dio_size = round_up(new_size, CACHEFILES_DIO_BLOCK_SIZE); + i_size = i_size_read(inode); - cachefiles_begin_secure(cache, &saved_cred); + trace_cachefiles_trunc(object, inode, i_size, dio_size, + cachefiles_trunc_shrink); + ret = vfs_truncate(&file->f_path, dio_size); + if (ret < 0) { + cachefiles_io_error_obj(object, "Trunc-to-size failed %d", ret); + cachefiles_remove_object_xattr(cache, file->f_path.dentry); + return false; + } - object_size = object->cookie->object_size; - i_size = i_size_read(file_inode(file)); - if (i_size > object_size) { - _debug("trunc %llx -> %llx", i_size, object_size); - trace_cachefiles_trunc(object, file_inode(file), - i_size, object_size, - cachefiles_trunc_shrink); - ret = vfs_truncate(&file->f_path, object_size); + if (new_size < dio_size) { + trace_cachefiles_trunc(object, inode, dio_size, new_size, + cachefiles_trunc_dio_adjust); + ret = vfs_fallocate(file, FALLOC_FL_ZERO_RANGE, + new_size, dio_size); if (ret < 0) { - cachefiles_io_error_obj(object, "Trunc-to-size failed"); + cachefiles_io_error_obj(object, "Trunc-to-dio-size failed %d", ret); cachefiles_remove_object_xattr(cache, file->f_path.dentry); - goto out; - } - - object_size = round_up(object_size, CACHEFILES_DIO_BLOCK_SIZE); - i_size = i_size_read(file_inode(file)); - _debug("trunc %llx -> %llx", i_size, object_size); - if (i_size < object_size) { - trace_cachefiles_trunc(object, file_inode(file), - i_size, object_size, - cachefiles_trunc_dio_adjust); - ret = vfs_truncate(&file->f_path, object_size); - if (ret < 0) { - cachefiles_io_error_obj(object, "Trunc-to-dio-size failed"); - cachefiles_remove_object_xattr(cache, file->f_path.dentry); - goto out; - } + return false; } } - cachefiles_set_object_xattr(object); + return true; +} -out: - cachefiles_end_secure(cache, saved_cred); - _leave(""); +/* + * Resize the backing object. + */ +static void cachefiles_resize_cookie(struct netfs_cache_resources *cres, + loff_t new_size) +{ + struct cachefiles_object *object = cachefiles_cres_object(cres); + struct cachefiles_cache *cache = object->volume->cache; + struct fscache_cookie *cookie = object->cookie; + const struct cred *saved_cred; + struct file *file = cachefiles_cres_file(cres); + loff_t old_size = cookie->object_size; + + _enter("%llu->%llu", old_size, new_size); + + if (new_size < old_size) { + cachefiles_begin_secure(cache, &saved_cred); + cachefiles_shorten_object(object, file, new_size); + cachefiles_end_secure(cache, saved_cred); + object->cookie->object_size = new_size; + return; + } + + /* The file is being expanded. We don't need to do anything + * particularly. cookie->initial_size doesn't change and so the point + * at which we have to download before doesn't change. + */ + cookie->object_size = new_size; } /* @@ -196,7 +214,7 @@ static void cachefiles_commit_object(struct cachefiles_object *object, if (test_and_clear_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &object->cookie->flags)) update = true; if (update) - cachefiles_update_object(object); + cachefiles_set_object_xattr(object); if (test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) cachefiles_commit_tmpfile(cache, object); @@ -440,5 +458,6 @@ const struct fscache_cache_ops cachefiles_cache_ops = { .lookup_cookie = cachefiles_lookup_cookie, .withdraw_cookie = cachefiles_withdraw_cookie, .invalidate_cookie = cachefiles_invalidate_cookie, + .resize_cookie = cachefiles_resize_cookie, .begin_operation = cachefiles_begin_operation, }; diff --git a/fs/fscache/io.c b/fs/fscache/io.c index ad9798f0c850..8b1a865a0847 100644 --- a/fs/fscache/io.c +++ b/fs/fscache/io.c @@ -253,3 +253,28 @@ int fscache_set_page_dirty(struct page *page, struct fscache_cookie *cookie) return 1; } EXPORT_SYMBOL(fscache_set_page_dirty); + +/* + * Change the size of a backing object. + */ +void __fscache_resize_cookie(struct fscache_cookie *cookie, loff_t new_size) +{ + struct netfs_cache_resources cres; + + trace_fscache_resize(cookie, new_size); + if (fscache_begin_operation(&cres, cookie, FSCACHE_WANT_WRITE, + fscache_access_io_resize) == 0) { + fscache_stat(&fscache_n_resizes); + set_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &cookie->flags); + + /* We cannot defer a resize as we need to do it inside the + * netfs's inode lock so that we're serialised with respect to + * writes. + */ + cookie->volume->cache->ops->resize_cookie(&cres, new_size); + fscache_end_operation(&cres); + } else { + fscache_stat(&fscache_n_resizes_null); + } +} +EXPORT_SYMBOL(__fscache_resize_cookie); diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c index 44b3b901e191..b1174d0dac3e 100644 --- a/fs/fscache/stats.c +++ b/fs/fscache/stats.c @@ -97,8 +97,10 @@ int fscache_stats_show(struct seq_file *m, void *v) seq_printf(m, "Invals : n=%u\n", atomic_read(&fscache_n_invalidates)); - seq_printf(m, "Updates: n=%u\n", - atomic_read(&fscache_n_updates)); + seq_printf(m, "Updates: n=%u rsz=%u rsn=%u\n", + atomic_read(&fscache_n_updates), + atomic_read(&fscache_n_resizes), + atomic_read(&fscache_n_resizes_null)); seq_printf(m, "Relinqs: n=%u rtr=%u drop=%u\n", atomic_read(&fscache_n_relinquishes), diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index 22064611d182..2e7265e24df6 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -66,6 +66,10 @@ struct fscache_cache_ops { /* Withdraw an object without any cookie access counts held */ void (*withdraw_cookie)(struct fscache_cookie *cookie); + /* Change the size of a data object */ + void (*resize_cookie)(struct netfs_cache_resources *cres, + loff_t new_size); + /* Invalidate an object */ bool (*invalidate_cookie)(struct fscache_cookie *cookie); diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 08663ad7feed..8148193045cd 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -164,6 +164,7 @@ extern struct fscache_cookie *__fscache_acquire_cookie( extern void __fscache_use_cookie(struct fscache_cookie *, bool); extern void __fscache_unuse_cookie(struct fscache_cookie *, const void *, const loff_t *); extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool); +extern void __fscache_resize_cookie(struct fscache_cookie *, loff_t); extern void __fscache_invalidate(struct fscache_cookie *, const void *, loff_t, unsigned int); #ifdef FSCACHE_USE_NEW_IO_API extern int __fscache_begin_read_operation(struct netfs_cache_resources *, struct fscache_cookie *); @@ -361,6 +362,23 @@ void fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data, __fscache_update_cookie(cookie, aux_data, object_size); } +/** + * fscache_resize_cookie - Request that a cache object be resized + * @cookie: The cookie representing the cache object + * @new_size: The new size of the object (may be NULL) + * + * Request that the size of an object be changed. + * + * See Documentation/filesystems/caching/netfs-api.txt for a complete + * description. + */ +static inline +void fscache_resize_cookie(struct fscache_cookie *cookie, loff_t new_size) +{ + if (fscache_cookie_enabled(cookie)) + __fscache_resize_cookie(cookie, new_size); +} + /** * fscache_pin_cookie - Pin a data-storage cache object in its cache * @cookie: The cookie representing the cache object diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h index adde3bb61f0f..9554b43e6fdf 100644 --- a/include/trace/events/fscache.h +++ b/include/trace/events/fscache.h @@ -429,6 +429,29 @@ TRACE_EVENT(fscache_invalidate, __entry->cookie, __entry->new_size) ); +TRACE_EVENT(fscache_resize, + TP_PROTO(struct fscache_cookie *cookie, loff_t new_size), + + TP_ARGS(cookie, new_size), + + TP_STRUCT__entry( + __field(unsigned int, cookie ) + __field(loff_t, old_size ) + __field(loff_t, new_size ) + ), + + TP_fast_assign( + __entry->cookie = cookie->debug_id; + __entry->old_size = cookie->object_size; + __entry->new_size = new_size; + ), + + TP_printk("c=%08x os=%08llx sz=%08llx", + __entry->cookie, + __entry->old_size, + __entry->new_size) + ); + #endif /* _TRACE_FSCACHE_H */ /* This part must be outside protection */ From patchwork Mon Oct 18 15:02:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567129 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F2054C433EF for ; Mon, 18 Oct 2021 15:03:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D9A0B60E0C for ; Mon, 18 Oct 2021 15:03:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233056AbhJRPFx (ORCPT ); Mon, 18 Oct 2021 11:05:53 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:37438 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233353AbhJRPEg (ORCPT ); Mon, 18 Oct 2021 11:04:36 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569334; 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=UhcaIo/ficWK/PPSZVzJujLXQ8djt/id9tCh3dUyTWg=; b=ZIFLOUW5bpLsAeDWNfhpvLfroG6jhlqYvvoq1q55Hd81DQft8CaiasO2+QMHssaehPoML1 9dLCymP9dxiHrKWd8zCKXA702rJoZcGQraVwyW0OlfDsgI9UT/4FFccSUzyWWjr+udOScM f6E/zP1kx/yWqHunqz+pCg4G3D29FTI= 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-389-CyF1J0hxMHmBDKdcq6LdIg-1; Mon, 18 Oct 2021 11:02:11 -0400 X-MC-Unique: CyF1J0hxMHmBDKdcq6LdIg-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CDD67801FCE; Mon, 18 Oct 2021 15:02:08 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id A731D62A44; Mon, 18 Oct 2021 15:02:02 +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 47/67] cachefiles: Put more information in the xattr attached to the cache file From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:02:01 +0100 Message-ID: <163456932180.2614702.9793858366854318097.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Put some more information into the xattr attached to a cache file including the size of the object (i_size may get rounded to a block size for DIO purposes), the point after which the server has no data and a content mapping type. Note that the new cache and the old cache will see each other's cache files as being incoherent and discard them. Signed-off-by: David Howells --- fs/cachefiles/interface.c | 1 + fs/cachefiles/internal.h | 11 +++++++++++ fs/cachefiles/xattr.c | 25 +++++++++++++++++++------ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index f90f6ddd07a5..751b0fec4591 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -420,6 +420,7 @@ static bool cachefiles_invalidate_cookie(struct fscache_cookie *cookie) old_file = object->file; object->file = new_file; + object->content_info = CACHEFILES_CONTENT_NO_DATA; set_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags); set_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &object->cookie->flags); diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index a2d2ed2f19eb..1d3e37bca087 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -31,6 +31,16 @@ extern unsigned cachefiles_debug; #define cachefiles_gfp (__GFP_RECLAIM | __GFP_NORETRY | __GFP_NOMEMALLOC) +enum cachefiles_content { + /* These values are saved on disk */ + CACHEFILES_CONTENT_NO_DATA = 0, /* No content stored */ + CACHEFILES_CONTENT_SINGLE = 1, /* Content is monolithic, all is present */ + CACHEFILES_CONTENT_ALL = 2, /* Content is all present, no map */ + CACHEFILES_CONTENT_BACKFS_MAP = 3, /* Content is piecemeal, mapped through backing fs */ + CACHEFILES_CONTENT_DIRTY = 4, /* Content is dirty (only seen on disk) */ + nr__cachefiles_content +}; + /* * Cached volume representation. */ @@ -59,6 +69,7 @@ struct cachefiles_object { u8 key_hash; /* Hash of object key */ unsigned long flags; #define CACHEFILES_OBJECT_USING_TMPFILE 0 /* Have an unlinked tmpfile */ + enum cachefiles_content content_info:8; /* Info about content presence */ }; extern struct kmem_cache *cachefiles_object_jar; diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c index 50b2a4588946..ba3d050a5174 100644 --- a/fs/cachefiles/xattr.c +++ b/fs/cachefiles/xattr.c @@ -18,8 +18,11 @@ #define CACHEFILES_COOKIE_TYPE_DATA 1 struct cachefiles_xattr { - uint8_t type; - uint8_t data[]; + __be64 object_size; /* Actual size of the object */ + __be64 zero_point; /* Size after which server has no data not written by us */ + __u8 type; /* Type of object */ + __u8 content; /* Content presence (enum cachefiles_content) */ + __u8 data[]; /* netfs coherency data */ } __packed; static const char cachefiles_xattr_cache[] = @@ -46,7 +49,10 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object) if (!buf) return -ENOMEM; - buf->type = CACHEFILES_COOKIE_TYPE_DATA; + buf->object_size = cpu_to_be64(object->cookie->object_size); + buf->zero_point = 0; + buf->type = CACHEFILES_COOKIE_TYPE_DATA; + buf->content = object->content_info; if (len > 0) memcpy(buf->data, fscache_get_aux(object->cookie), len); @@ -54,7 +60,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object) buf, sizeof(struct cachefiles_xattr) + len, 0); if (ret < 0) { trace_cachefiles_coherency(object, file_inode(file)->i_ino, - 0, + buf->content, cachefiles_coherency_set_fail); if (ret != -ENOMEM) cachefiles_io_error_obj( @@ -62,7 +68,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object) "Failed to set xattr with error %d", ret); } else { trace_cachefiles_coherency(object, file_inode(file)->i_ino, - 0, + buf->content, cachefiles_coherency_set_ok); } @@ -100,12 +106,19 @@ int cachefiles_check_auxdata(struct cachefiles_object *object, struct file *file why = cachefiles_coherency_check_type; } else if (memcmp(buf->data, p, len) != 0) { why = cachefiles_coherency_check_aux; + } else if (be64_to_cpu(buf->object_size) != object->cookie->object_size) { + why = cachefiles_coherency_check_objsize; + } else if (buf->content == CACHEFILES_CONTENT_DIRTY) { + // TODO: Begin conflict resolution + pr_warn("Dirty object in cache\n"); + why = cachefiles_coherency_check_dirty; } else { why = cachefiles_coherency_check_ok; ret = 0; } - trace_cachefiles_coherency(object, file_inode(file)->i_ino, 0, why); + trace_cachefiles_coherency(object, file_inode(file)->i_ino, + buf->content, why); kfree(buf); return ret; } From patchwork Mon Oct 18 15:02:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567125 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 06B97C4167B for ; Mon, 18 Oct 2021 15:02:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E69D660E0C for ; Mon, 18 Oct 2021 15:02:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233426AbhJRPEr (ORCPT ); Mon, 18 Oct 2021 11:04:47 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:28090 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232940AbhJRPEj (ORCPT ); Mon, 18 Oct 2021 11:04:39 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569347; 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=fCVZMS1f+Fc9xqMTz/jhF/KB+eLizY8P0By1uDIP188=; b=eTkctxXCaDg4ycqZ86I5qPHxhKHWYbAUFIDL76igm7qSQiRDwKNLjTGeQyoDl+lb6wTdLu VS7FmuCmHeBIA1vhG9l6iAsJYEC/T6ltQKiY6/8GQEueKKrDNiQsYIbodAPD8V62QfrYGp 9W7wF0+6U0iQUIAKUVDCVt+gZZoSn9E= 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-359-Ul4T-zXEPGq-sz71ZmwD3g-1; Mon, 18 Oct 2021 11:02:24 -0400 X-MC-Unique: Ul4T-zXEPGq-sz71ZmwD3g-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CA8E3100CCC0; Mon, 18 Oct 2021 15:02:21 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id BE7D74DA31; Mon, 18 Oct 2021 15:02:14 +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 48/67] fscache: Implement "will_modify" parameter on fscache_use_cookie() From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:02:14 +0100 Message-ID: <163456933400.2614702.3593094196519659430.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Implement the "will_modify" parameter passed to fscache_use_cookie(). Setting this to true will henceforth cause the affected object to be marked as dirty on disk, subject to conflict resolution in the event that power failure or a crash occurs or the filesystem operates in disconnected mode. The dirty flag is removed when the cache object is discarded from memory. A cache hook is provided to prepare for writing - and this can be used to mark the object on disk. Signed-off-by: David Howells --- fs/cachefiles/interface.c | 3 +++ fs/cachefiles/internal.h | 2 +- fs/cachefiles/xattr.c | 20 ++++++++++++++++++++ fs/fscache/cookie.c | 30 +++++++++++++++++++++++++++++- include/linux/fscache-cache.h | 3 +++ include/linux/fscache.h | 2 ++ include/trace/events/cachefiles.h | 4 ++-- 7 files changed, 60 insertions(+), 4 deletions(-) diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 751b0fec4591..96f30eba585a 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -211,6 +211,8 @@ static void cachefiles_commit_object(struct cachefiles_object *object, { bool update = false; + if (test_and_clear_bit(FSCACHE_COOKIE_LOCAL_WRITE, &object->cookie->flags)) + update = true; if (test_and_clear_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &object->cookie->flags)) update = true; if (update) @@ -461,4 +463,5 @@ const struct fscache_cache_ops cachefiles_cache_ops = { .invalidate_cookie = cachefiles_invalidate_cookie, .resize_cookie = cachefiles_resize_cookie, .begin_operation = cachefiles_begin_operation, + .prepare_to_write = cachefiles_prepare_to_write, }; diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index 1d3e37bca087..83cf2ca3a763 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -239,7 +239,7 @@ extern int cachefiles_check_auxdata(struct cachefiles_object *object, struct file *file); extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, struct dentry *dentry); - +extern void cachefiles_prepare_to_write(struct fscache_cookie *cookie); /* * error handling diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c index ba3d050a5174..30adca42883b 100644 --- a/fs/cachefiles/xattr.c +++ b/fs/cachefiles/xattr.c @@ -53,6 +53,8 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object) buf->zero_point = 0; buf->type = CACHEFILES_COOKIE_TYPE_DATA; buf->content = object->content_info; + if (test_bit(FSCACHE_COOKIE_LOCAL_WRITE, &object->cookie->flags)) + buf->content = CACHEFILES_CONTENT_DIRTY; if (len > 0) memcpy(buf->data, fscache_get_aux(object->cookie), len); @@ -145,3 +147,21 @@ int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, _leave(" = %d", ret); return ret; } + +/* + * Stick a marker on the cache object to indicate that it's dirty. + */ +void cachefiles_prepare_to_write(struct fscache_cookie *cookie) +{ + const struct cred *saved_cred; + struct cachefiles_object *object = cookie->cache_priv; + struct cachefiles_cache *cache = object->volume->cache; + + _enter("c=%08x", object->cookie->debug_id); + + if (!test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) { + cachefiles_begin_secure(cache, &saved_cred); + cachefiles_set_object_xattr(object); + cachefiles_end_secure(cache, saved_cred); + } +} diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 70bfbd269652..1420027cfe97 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -402,12 +402,20 @@ struct fscache_cookie *__fscache_acquire_cookie( } EXPORT_SYMBOL(__fscache_acquire_cookie); +/* + * Prepare a cache object to be written to. + */ +static void fscache_prepare_to_write(struct fscache_cookie *cookie) +{ + cookie->volume->cache->ops->prepare_to_write(cookie); +} + /* * Look up a cookie to the cache. */ static void fscache_lookup_cookie(struct fscache_cookie *cookie) { - bool changed_stage = false, need_withdraw = false; + bool changed_stage = false, need_withdraw = false, prep_write = false; _enter(""); @@ -429,6 +437,7 @@ static void fscache_lookup_cookie(struct fscache_cookie *cookie) spin_lock(&cookie->lock); if (cookie->stage != FSCACHE_COOKIE_STAGE_RELINQUISHING) { + prep_write = test_bit(FSCACHE_COOKIE_LOCAL_WRITE, &cookie->flags); __fscache_set_cookie_stage(cookie, FSCACHE_COOKIE_STAGE_ACTIVE); fscache_see_cookie(cookie, fscache_cookie_see_active); changed_stage = true; @@ -436,6 +445,8 @@ static void fscache_lookup_cookie(struct fscache_cookie *cookie) spin_unlock(&cookie->lock); if (changed_stage) wake_up_cookie_stage(cookie); + if (prep_write) + fscache_prepare_to_write(cookie); out: fscache_end_cookie_access(cookie, fscache_access_lookup_cookie_end); @@ -467,6 +478,10 @@ void __fscache_use_cookie(struct fscache_cookie *cookie, bool will_modify) stage = cookie->stage; switch (stage) { case FSCACHE_COOKIE_STAGE_QUIESCENT: + if (will_modify) { + set_bit(FSCACHE_COOKIE_LOCAL_WRITE, &cookie->flags); + set_bit(FSCACHE_COOKIE_DO_PREP_TO_WRITE, &cookie->flags); + } if (!fscache_begin_volume_access(cookie->volume, fscache_access_lookup_cookie)) break; @@ -484,8 +499,18 @@ void __fscache_use_cookie(struct fscache_cookie *cookie, bool will_modify) case FSCACHE_COOKIE_STAGE_LOOKING_UP: case FSCACHE_COOKIE_STAGE_CREATING: + if (will_modify) + set_bit(FSCACHE_COOKIE_LOCAL_WRITE, &cookie->flags); + break; case FSCACHE_COOKIE_STAGE_ACTIVE: case FSCACHE_COOKIE_STAGE_INVALIDATING: + if (will_modify && + !test_and_set_bit(FSCACHE_COOKIE_LOCAL_WRITE, &cookie->flags)) { + set_bit(FSCACHE_COOKIE_DO_PREP_TO_WRITE, &cookie->flags); + queue = true; + } + break; + case FSCACHE_COOKIE_STAGE_FAILED: case FSCACHE_COOKIE_STAGE_WITHDRAWING: break; @@ -551,6 +576,8 @@ static void __fscache_cookie_worker(struct fscache_cookie *cookie) again: switch (READ_ONCE(cookie->stage)) { case FSCACHE_COOKIE_STAGE_ACTIVE: + if (test_and_clear_bit(FSCACHE_COOKIE_DO_PREP_TO_WRITE, &cookie->flags)) + fscache_prepare_to_write(cookie); break; case FSCACHE_COOKIE_STAGE_LOOKING_UP: @@ -591,6 +618,7 @@ static void __fscache_cookie_worker(struct fscache_cookie *cookie) clear_bit(FSCACHE_COOKIE_NEEDS_UPDATE, &cookie->flags); clear_bit(FSCACHE_COOKIE_DO_WITHDRAW, &cookie->flags); clear_bit(FSCACHE_COOKIE_DO_COMMIT, &cookie->flags); + clear_bit(FSCACHE_COOKIE_DO_PREP_TO_WRITE, &cookie->flags); set_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags); fscache_set_cookie_stage(cookie, FSCACHE_COOKIE_STAGE_QUIESCENT); break; diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index 2e7265e24df6..889ae37fae0f 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -76,6 +76,9 @@ struct fscache_cache_ops { /* Begin an operation for the netfs lib */ bool (*begin_operation)(struct netfs_cache_resources *cres, enum fscache_want_stage want_stage); + + /* Prepare to write to a live cache object */ + void (*prepare_to_write)(struct fscache_cookie *cookie); }; static inline enum fscache_cache_state fscache_cache_state(const struct fscache_cache *cache) diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 8148193045cd..8ab691e52cc5 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -125,10 +125,12 @@ struct fscache_cookie { #define FSCACHE_COOKIE_NEEDS_UPDATE 4 /* T if attrs have been updated */ #define FSCACHE_COOKIE_HAS_BEEN_CACHED 5 /* T if cookie needs withdraw-on-relinq */ #define FSCACHE_COOKIE_DISABLED 6 /* T if cookie has been disabled */ +#define FSCACHE_COOKIE_LOCAL_WRITE 7 /* T if cookie has been modified locally */ #define FSCACHE_COOKIE_NACC_ELEVATED 8 /* T if n_accesses is incremented */ #define FSCACHE_COOKIE_DO_RELINQUISH 9 /* T if this cookie needs relinquishment */ #define FSCACHE_COOKIE_DO_WITHDRAW 10 /* T if this cookie needs withdrawing */ #define FSCACHE_COOKIE_DO_COMMIT 11 /* T if this cookie needs committing */ +#define FSCACHE_COOKIE_DO_PREP_TO_WRITE 12 /* T if cookie needs write preparation */ enum fscache_cookie_stage stage; u8 advice; /* FSCACHE_ADV_* */ diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h index a7b31b248f2d..11447b20fc83 100644 --- a/include/trace/events/cachefiles.h +++ b/include/trace/events/cachefiles.h @@ -340,7 +340,7 @@ TRACE_EVENT(cachefiles_mark_inactive, TRACE_EVENT(cachefiles_coherency, TP_PROTO(struct cachefiles_object *obj, ino_t ino, - int content, + enum cachefiles_content content, enum cachefiles_coherency_trace why), TP_ARGS(obj, ino, content, why), @@ -349,7 +349,7 @@ TRACE_EVENT(cachefiles_coherency, TP_STRUCT__entry( __field(unsigned int, obj ) __field(enum cachefiles_coherency_trace, why ) - __field(int, content ) + __field(enum cachefiles_content, content ) __field(u64, ino ) ), From patchwork Mon Oct 18 15:02:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567205 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BB8F0C433F5 for ; Mon, 18 Oct 2021 15:04:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A10C36103D for ; Mon, 18 Oct 2021 15:04:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233530AbhJRPGu (ORCPT ); Mon, 18 Oct 2021 11:06:50 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:57658 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233049AbhJRPFh (ORCPT ); Mon, 18 Oct 2021 11:05:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569406; 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=ta+4wHdynNPy0bFW+9M1HIOAo1s/OgHB0kjMN761Lqw=; b=OdqdoSUv9A7bVaCiGg2cecCKNZzCOyloqDbG6pBZN0Fj9oE9VROQPq4/NWnAxotVvOsFfu UKjHVsHp98paG8GrhBj9jva/KeC0pujmq5fWaGmDJu/vcWoMvWL5xqGYSgLPFmnQwZDAzq EyyeijUVApSbiCHXj6pWNbRrC5gW150= 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-12-hNT8YbiVPr2lt9d5R-wRbQ-1; Mon, 18 Oct 2021 11:03:21 -0400 X-MC-Unique: hNT8YbiVPr2lt9d5R-wRbQ-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 75F231018720; Mon, 18 Oct 2021 15:03:17 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id E0E675DF21; Mon, 18 Oct 2021 15:02:27 +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 49/67] fscache: Add support for writing to the cache From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:02:27 +0100 Message-ID: <163456934704.2614702.13459517221637847782.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Add a pair of helpers for use by a netfs to write data to the cache. Signed-off-by: David Howells --- fs/fscache/io.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/fscache.h | 58 +++++++++++++++++++++++++++ 2 files changed, 158 insertions(+) diff --git a/fs/fscache/io.c b/fs/fscache/io.c index 8b1a865a0847..3910cba65545 100644 --- a/fs/fscache/io.c +++ b/fs/fscache/io.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "internal.h" /** @@ -278,3 +279,102 @@ void __fscache_resize_cookie(struct fscache_cookie *cookie, loff_t new_size) } } EXPORT_SYMBOL(__fscache_resize_cookie); + +struct fscache_write_request { + struct netfs_cache_resources cache_resources; + struct address_space *mapping; + loff_t start; + size_t len; + netfs_io_terminated_t term_func; + void *term_func_priv; +}; + +void __fscache_clear_page_bits(struct address_space *mapping, + loff_t start, size_t len) +{ + pgoff_t first = start / PAGE_SIZE; + pgoff_t last = (start + len - 1) / PAGE_SIZE; + struct page *page; + + if (len) { + XA_STATE(xas, &mapping->i_pages, first); + + rcu_read_lock(); + xas_for_each(&xas, page, last) { + end_page_fscache(page); + } + rcu_read_unlock(); + } +} +EXPORT_SYMBOL(__fscache_clear_page_bits); + +/* + * Deal with the completion of writing the data to the cache. + */ +static void fscache_wreq_done(void *priv, ssize_t transferred_or_error, + bool was_async) +{ + struct fscache_write_request *wreq = priv; + + fscache_clear_page_bits(wreq->mapping, wreq->start, wreq->len); + + if (wreq->term_func) + wreq->term_func(wreq->term_func_priv, transferred_or_error, + was_async); + fscache_end_operation(&wreq->cache_resources); + kfree(wreq); +} + +void __fscache_write_to_cache(struct fscache_cookie *cookie, + struct address_space *mapping, + loff_t start, size_t len, loff_t i_size, + netfs_io_terminated_t term_func, + void *term_func_priv) +{ + struct fscache_write_request *wreq; + struct netfs_cache_resources *cres; + struct iov_iter iter; + int ret = -ENOBUFS; + + if (!fscache_cookie_valid(cookie) || len == 0) + goto abandon; + + _enter("%llx,%zx", start, len); + + wreq = kzalloc(sizeof(struct fscache_write_request), GFP_NOFS); + if (!wreq) + goto abandon; + wreq->mapping = mapping; + wreq->start = start; + wreq->len = len; + wreq->term_func = term_func; + wreq->term_func_priv = term_func_priv; + + cres = &wreq->cache_resources; + if (fscache_begin_operation(cres, cookie, FSCACHE_WANT_WRITE, + fscache_access_io_write) < 0) + goto abandon_free; + + ret = cres->ops->prepare_write(cres, &start, &len, i_size, false); + if (ret < 0) + goto abandon_end; + + /* TODO: Consider clearing page bits now for space the write isn't + * covering. This is more complicated than it appears when THPs are + * taken into account. + */ + + iov_iter_xarray(&iter, WRITE, &mapping->i_pages, start, len); + fscache_write(cres, start, &iter, fscache_wreq_done, wreq); + return; + +abandon_end: + return fscache_wreq_done(wreq, ret, false); +abandon_free: + kfree(wreq); +abandon: + fscache_clear_page_bits(mapping, start, len); + if (term_func) + term_func(term_func_priv, ret, false); +} +EXPORT_SYMBOL(__fscache_write_to_cache); diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 8ab691e52cc5..fe4d588641da 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -176,6 +176,10 @@ extern int __fscache_fallback_read_page(struct fscache_cookie *, struct page *); extern int __fscache_fallback_write_page(struct fscache_cookie *, struct page *); #endif +extern void __fscache_write_to_cache(struct fscache_cookie *, struct address_space *, + loff_t, size_t, loff_t, netfs_io_terminated_t, void *); +extern void __fscache_clear_page_bits(struct address_space *, loff_t, size_t); + /** * fscache_acquire_volume - Register a volume as desiring caching services * @volume_key: An identification string for the volume @@ -543,6 +547,60 @@ int fscache_write(struct netfs_cache_resources *cres, return ops->write(cres, start_pos, iter, term_func, term_func_priv); } +/** + * fscache_clear_page_bits - Clear the PG_fscache bits from a set of pages + * @mapping: The netfs inode to use as the source + * @start: The start position in @mapping + * @len: The amount of data to unlock + * + * Clear the PG_fscache flag from a sequence of pages and wake up anyone who's + * waiting. + */ +static inline void fscache_clear_page_bits(struct address_space *mapping, + loff_t start, size_t len) +{ + if (fscache_available()) + __fscache_clear_page_bits(mapping, start, len); +} + +/** + * fscache_write_to_cache - Save a write to the cache and clear PG_fscache + * @cookie: The cookie representing the cache object + * @mapping: The netfs inode to use as the source + * @start: The start position in @mapping + * @len: The amount of data to write back + * @i_size: The new size of the inode + * @term_func: The function to call upon completion + * @term_func_priv: The private data for @term_func + * + * Helper function for a netfs to write dirty data from an inode into the cache + * object that's backing it. + * + * @start and @len describe the range of the data. This does not need to be + * page-aligned, but to satisfy DIO requirements, the cache may expand it up to + * the page boundaries on either end. All the pages covering the range must be + * marked with PG_fscache. + * + * If given, @term_func will be called upon completion and supplied with + * @term_func_priv. Note that the PG_fscache flags will have been cleared by + * this point, so the netfs must retain its own pin on the mapping. + */ +static inline void fscache_write_to_cache(struct fscache_cookie *cookie, + struct address_space *mapping, + loff_t start, size_t len, loff_t i_size, + netfs_io_terminated_t term_func, + void *term_func_priv) +{ + if (fscache_available()) { + __fscache_write_to_cache(cookie, mapping, start, len, i_size, + term_func, term_func_priv); + } else { + fscache_clear_page_bits(mapping, start, len); + if (term_func) + term_func(term_func_priv, -ENOBUFS, false); + } + +} #endif /* FSCACHE_USE_NEW_IO_API */ #if __fscache_available From patchwork Mon Oct 18 15:03:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567207 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89DF5C433F5 for ; Mon, 18 Oct 2021 15:04:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 70D5E60E0C for ; Mon, 18 Oct 2021 15:04:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232772AbhJRPGx (ORCPT ); Mon, 18 Oct 2021 11:06:53 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:32341 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232684AbhJRPF5 (ORCPT ); Mon, 18 Oct 2021 11:05:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569425; 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=K6n7Lxx/u+7TeXaM45gQ3O34r9vcGaUxwGu9AnBokAQ=; b=dGZzg8+oxaFJNbjjnIzZfchWt4jRFNvwnG+iI502HsYFS6VArkgfCI0xSHsqS/onmQSuQ8 b3vWnJNXprO7i/UzqP4M9toL1fQDmS5YNWS6suLr+vnSJt1m5WaUsUyfOlf5Ogc+QhJoLD BFvcpCposJ1MdXrUH/5uOvv3JwlMCro= 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-276-3SzqldG0NTe8vAbqLe2UXg-1; Mon, 18 Oct 2021 11:03:43 -0400 X-MC-Unique: 3SzqldG0NTe8vAbqLe2UXg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 85B2710168DE; Mon, 18 Oct 2021 15:03:41 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7723A60CCC; Mon, 18 Oct 2021 15:03:23 +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 50/67] fscache: Make fscache_clear_page_bits() conditional on cookie From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:03:22 +0100 Message-ID: <163456940271.2614702.17009440990784553871.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Make fscache_clear_page_bits() conditional on cookie not being NULL, rather than merely conditional on CONFIG_FSCACHE=[ym]. The problem with the latter is if a filesystem, say afs, has CONFIG_AFS_FSCACHE=n but calls into this function - in which it linkage will fail if CONFIG_FSCACHE is less than CONFIG_AFS. Analogous problems can affect other filesystems, e.g. 9p. Making fscache_clear_page_bits() conditional on the cookie achieves two things: (1) If cookie optimised down to constant NULL, the rest of the function is thrown away and the slow path is never called. (2) __fscache_clear_page_bits() isn't called if there's no cookie - and so, in such a case, the pages won't iterated over attempting to clear PG_fscache bits that haven't been set. Signed-off-by: David Howells --- fs/fscache/io.c | 5 +++-- include/linux/fscache.h | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/fs/fscache/io.c b/fs/fscache/io.c index 3910cba65545..bc8d1ac0e85c 100644 --- a/fs/fscache/io.c +++ b/fs/fscache/io.c @@ -316,7 +316,8 @@ static void fscache_wreq_done(void *priv, ssize_t transferred_or_error, { struct fscache_write_request *wreq = priv; - fscache_clear_page_bits(wreq->mapping, wreq->start, wreq->len); + fscache_clear_page_bits(fscache_cres_cookie(&wreq->cache_resources), + wreq->mapping, wreq->start, wreq->len); if (wreq->term_func) wreq->term_func(wreq->term_func_priv, transferred_or_error, @@ -373,7 +374,7 @@ void __fscache_write_to_cache(struct fscache_cookie *cookie, abandon_free: kfree(wreq); abandon: - fscache_clear_page_bits(mapping, start, len); + fscache_clear_page_bits(cookie, mapping, start, len); if (term_func) term_func(term_func_priv, ret, false); } diff --git a/include/linux/fscache.h b/include/linux/fscache.h index fe4d588641da..847c076d05a6 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -549,6 +549,7 @@ int fscache_write(struct netfs_cache_resources *cres, /** * fscache_clear_page_bits - Clear the PG_fscache bits from a set of pages + * @cookie: The cookie representing the cache object * @mapping: The netfs inode to use as the source * @start: The start position in @mapping * @len: The amount of data to unlock @@ -556,10 +557,11 @@ int fscache_write(struct netfs_cache_resources *cres, * Clear the PG_fscache flag from a sequence of pages and wake up anyone who's * waiting. */ -static inline void fscache_clear_page_bits(struct address_space *mapping, +static inline void fscache_clear_page_bits(struct fscache_cookie *cookie, + struct address_space *mapping, loff_t start, size_t len) { - if (fscache_available()) + if (fscache_cookie_valid(cookie)) __fscache_clear_page_bits(mapping, start, len); } @@ -595,7 +597,7 @@ static inline void fscache_write_to_cache(struct fscache_cookie *cookie, __fscache_write_to_cache(cookie, mapping, start, len, i_size, term_func, term_func_priv); } else { - fscache_clear_page_bits(mapping, start, len); + fscache_clear_page_bits(cookie, mapping, start, len); if (term_func) term_func(term_func_priv, -ENOBUFS, false); } From patchwork Mon Oct 18 15:03:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567209 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01EBDC433FE for ; Mon, 18 Oct 2021 15:05:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D7BE76103D for ; Mon, 18 Oct 2021 15:05:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232815AbhJRPHY (ORCPT ); Mon, 18 Oct 2021 11:07:24 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:52151 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233898AbhJRPGK (ORCPT ); Mon, 18 Oct 2021 11:06:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569438; 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=HO9YymjW83uus3ZxQrl12j24vv8cDVvU6mSOVZgOUCA=; b=cNUn2Jdaz/jG0/LgpD+vbN49U7HsMx0+jRerQ4raLegInh0fk1jBknzZycxv4dVgiZXfO6 EgI8JSC/rGQCJO+4bGZUwCW+mR5Jgov7DO0KCmazdN1FSH0I16CtLJYndPx0oDuTbnobH/ cIydJRx3oOgNOtnphcL+7VRXau/0xLI= 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-234-LvlXEboLNE6rtTEDUmVbKQ-1; Mon, 18 Oct 2021 11:03:52 -0400 X-MC-Unique: LvlXEboLNE6rtTEDUmVbKQ-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BB9E510168C0; Mon, 18 Oct 2021 15:03:50 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id A2D3057CA4; Mon, 18 Oct 2021 15:03:47 +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 51/67] fscache: Make fscache_write_to_cache() conditional on cookie From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:03:46 +0100 Message-ID: <163456942676.2614702.13709221260564510952.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Make fscache_write_to_cache() conditional on cookie not being NULL, rather than merely conditional on CONFIG_FSCACHE=[ym]. The problem with the latter is if a filesystem, say afs, has CONFIG_AFS_FSCACHE=n but calls into this function - linkage will fail if CONFIG_FSCACHE is less than CONFIG_AFS. Analogous problems can affect other filesystems, e.g. 9p. Making fscache_write_to_cache() conditional on the cookie achieves two things: (1) If cookie optimises down to constant NULL, term_func is called directly and may be inlined and the slow path is never called. (2) __fscache_write_to_cache() isn't called if cookie is dynamically NULL - and so, in such a case, term_func is called immediately. Signed-off-by: David Howells --- include/linux/fscache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 847c076d05a6..ba192567d099 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -593,7 +593,7 @@ static inline void fscache_write_to_cache(struct fscache_cookie *cookie, netfs_io_terminated_t term_func, void *term_func_priv) { - if (fscache_available()) { + if (fscache_cookie_valid(cookie)) { __fscache_write_to_cache(cookie, mapping, start, len, i_size, term_func, term_func_priv); } else { From patchwork Mon Oct 18 15:03:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567211 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 40CBAC433EF for ; Mon, 18 Oct 2021 15:05:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2AB4F6103D for ; Mon, 18 Oct 2021 15:05:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232580AbhJRPHc (ORCPT ); Mon, 18 Oct 2021 11:07:32 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:55070 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233672AbhJRPGU (ORCPT ); Mon, 18 Oct 2021 11:06:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569449; 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=rRc0OWpsCdR+RZihH2WSjAzCV3g5/DtjogslM+6pstI=; b=DYdsbnkeFuh9M/XNFL4EWi89S9R/BVZipIFabFEfdPq6G0ruvRmfwT+vY0re2fEqkDozfS +tN26QmNw8Ok792RetizHcTDxfjL2/5upYJ7fioEPTxl172b5HVIMiJ5qCLs2ewnLriHrL Ihgg8sxnJHy4vT+sU018tB2mbIL4h1w= 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-20-cq7nWjpeMxOYF50ZfuSarQ-1; Mon, 18 Oct 2021 11:04:05 -0400 X-MC-Unique: cq7nWjpeMxOYF50ZfuSarQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 296871018720; Mon, 18 Oct 2021 15:04:03 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id E5238641A7; Mon, 18 Oct 2021 15:03:56 +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 52/67] afs: Copy local writes to the cache when writing to the server From: David Howells To: linux-cachefs@redhat.com Cc: Marc Dionne , linux-afs@lists.infradead.org, dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:03:56 +0100 Message-ID: <163456943601.2614702.8101114886699133954.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org When writing to the server from afs_writepage() or afs_writepages(), copy the data to the cache object too. To make this possible, the cookie must have its active users count incremented when the page is dirtied and kept incremented until we manage to clean up all the pages. This allows the writeback to take place after the last file struct is released. Signed-off-by: David Howells cc: Marc Dionne cc: linux-afs@lists.infradead.org --- fs/afs/file.c | 6 ++++ fs/afs/inode.c | 8 +++-- fs/afs/internal.h | 5 +++ fs/afs/super.c | 1 + fs/afs/write.c | 79 +++++++++++++++++++++++++++++++++++++++++++++-------- 5 files changed, 84 insertions(+), 15 deletions(-) diff --git a/fs/afs/file.c b/fs/afs/file.c index 5e674a503c1b..4af7ef607cf6 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -402,6 +402,12 @@ static void afs_readahead(struct readahead_control *ractl) netfs_readahead(ractl, &afs_req_ops, NULL); } +int afs_write_inode(struct inode *inode, struct writeback_control *wbc) +{ + fscache_unpin_writeback(wbc, afs_vnode_cache(AFS_FS_I(inode))); + return 0; +} + /* * Adjust the dirty region of the page on truncation or full invalidation, * getting rid of the markers altogether if the region is entirely invalidated. diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 32038ccbce67..311df66c64d0 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -761,9 +761,8 @@ int afs_drop_inode(struct inode *inode) */ void afs_evict_inode(struct inode *inode) { - struct afs_vnode *vnode; - - vnode = AFS_FS_I(inode); + struct afs_vnode_cache_aux aux; + struct afs_vnode *vnode = AFS_FS_I(inode); _enter("{%llx:%llu.%d}", vnode->fid.vid, @@ -775,6 +774,9 @@ void afs_evict_inode(struct inode *inode) ASSERTCMP(inode->i_ino, ==, vnode->fid.vnode); truncate_inode_pages_final(&inode->i_data); + + afs_set_cache_aux(vnode, &aux); + fscache_clear_inode_writeback(afs_vnode_cache(vnode), inode, &aux); clear_inode(inode); while (!list_empty(&vnode->wb_keys)) { diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 6c591b7c55f1..07d34291bf4f 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -1072,6 +1072,7 @@ extern int afs_release(struct inode *, struct file *); extern int afs_fetch_data(struct afs_vnode *, struct afs_read *); extern struct afs_read *afs_alloc_read(gfp_t); extern void afs_put_read(struct afs_read *); +extern int afs_write_inode(struct inode *, struct writeback_control *); static inline struct afs_read *afs_get_read(struct afs_read *req) { @@ -1519,7 +1520,11 @@ extern int afs_check_volume_status(struct afs_volume *, struct afs_operation *); /* * write.c */ +#ifdef CONFIG_AFS_FSCACHE extern int afs_set_page_dirty(struct page *); +#else +#define afs_set_page_dirty __set_page_dirty_nobuffers +#endif extern int afs_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata); diff --git a/fs/afs/super.c b/fs/afs/super.c index d110def8aa8e..af7cbd9949c5 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -55,6 +55,7 @@ int afs_net_id; static const struct super_operations afs_super_ops = { .statfs = afs_statfs, .alloc_inode = afs_alloc_inode, + .write_inode = afs_write_inode, .drop_inode = afs_drop_inode, .destroy_inode = afs_destroy_inode, .free_inode = afs_free_inode, diff --git a/fs/afs/write.c b/fs/afs/write.c index e1cb19cb6314..a540da6ad423 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c @@ -12,17 +12,29 @@ #include #include #include -#include #include "internal.h" +static void afs_write_to_cache(struct afs_vnode *vnode, loff_t start, size_t len, + loff_t i_size); + +#ifdef CONFIG_AFS_FSCACHE /* - * mark a page as having been made dirty and thus needing writeback + * Mark a page as having been made dirty and thus needing writeback. We also + * need to pin the cache object to write back to. */ int afs_set_page_dirty(struct page *page) { - _enter(""); - return __set_page_dirty_nobuffers(page); + return fscache_set_page_dirty(page, afs_vnode_cache(AFS_FS_I(page->mapping->host))); +} +static void afs_set_page_fscache(struct page *page) +{ + set_page_fscache(page); +} +#else +static void afs_set_page_fscache(struct page *page) +{ } +#endif /* * Prepare to perform part of a write to a page. Note that len may extend @@ -114,7 +126,7 @@ int afs_write_end(struct file *file, struct address_space *mapping, unsigned long priv; unsigned int f, from = offset_in_thp(page, pos); unsigned int t, to = from + copied; - loff_t i_size, maybe_i_size; + loff_t i_size, write_end_pos; _enter("{%llx:%llu},{%lx}", vnode->fid.vid, vnode->fid.vnode, page->index); @@ -132,15 +144,16 @@ int afs_write_end(struct file *file, struct address_space *mapping, if (copied == 0) goto out; - maybe_i_size = pos + copied; + write_end_pos = pos + copied; i_size = i_size_read(&vnode->vfs_inode); - if (maybe_i_size > i_size) { + if (write_end_pos > i_size) { write_seqlock(&vnode->cb_lock); i_size = i_size_read(&vnode->vfs_inode); - if (maybe_i_size > i_size) - afs_set_i_size(vnode, maybe_i_size); + if (write_end_pos > i_size) + afs_set_i_size(vnode, write_end_pos); write_sequnlock(&vnode->cb_lock); + fscache_update_cookie(afs_vnode_cache(vnode), NULL, &write_end_pos); } if (PagePrivate(page)) { @@ -482,7 +495,8 @@ static void afs_extend_writeback(struct address_space *mapping, put_page(page); break; } - if (!PageDirty(page) || PageWriteback(page)) { + if (!PageDirty(page) || PageWriteback(page) || + PageFsCache(page)) { unlock_page(page); put_page(page); break; @@ -530,6 +544,7 @@ static void afs_extend_writeback(struct address_space *mapping, BUG(); if (test_set_page_writeback(page)) BUG(); + afs_set_page_fscache(page); *_count -= thp_nr_pages(page); unlock_page(page); @@ -564,6 +579,7 @@ static ssize_t afs_write_back_from_locked_page(struct address_space *mapping, if (test_set_page_writeback(page)) BUG(); + afs_set_page_fscache(page); count -= thp_nr_pages(page); @@ -603,12 +619,19 @@ static ssize_t afs_write_back_from_locked_page(struct address_space *mapping, if (start < i_size) { _debug("write back %x @%llx [%llx]", len, start, i_size); + /* Speculatively write to the cache. We have to fix this up + * later if the store fails. + */ + afs_write_to_cache(vnode, start, len, i_size); + iov_iter_xarray(&iter, WRITE, &mapping->i_pages, start, len); ret = afs_store_data(vnode, &iter, start, false); } else { _debug("write discard %x @%llx [%llx]", len, start, i_size); /* The dirty region was entirely beyond the EOF. */ + fscache_clear_page_bits(afs_vnode_cache(vnode), + mapping, start, len); afs_pages_written_back(vnode, start, len); ret = 0; } @@ -666,6 +689,10 @@ int afs_writepage(struct page *page, struct writeback_control *wbc) _enter("{%lx},", page->index); +#ifdef CONFIG_AFS_FSCACHE + wait_on_page_fscache(page); +#endif + start = page->index * PAGE_SIZE; ret = afs_write_back_from_locked_page(page->mapping, wbc, page, start, LLONG_MAX - start); @@ -728,10 +755,14 @@ static int afs_writepages_region(struct address_space *mapping, continue; } - if (PageWriteback(page)) { + if (PageWriteback(page) || PageFsCache(page)) { unlock_page(page); - if (wbc->sync_mode != WB_SYNC_NONE) + if (wbc->sync_mode != WB_SYNC_NONE) { wait_on_page_writeback(page); +#ifdef CONFIG_AFS_FSCACHE + wait_on_page_fscache(page); +#endif + } put_page(page); continue; } @@ -984,3 +1015,27 @@ int afs_launder_page(struct page *page) wait_on_page_fscache(page); return ret; } + +/* + * Deal with the completion of writing the data to the cache. + */ +static void afs_write_to_cache_done(void *priv, ssize_t transferred_or_error, + bool was_async) +{ + struct afs_vnode *vnode = priv; + + if (IS_ERR_VALUE(transferred_or_error) && + transferred_or_error != -ENOBUFS) + afs_invalidate_cache(vnode, 0); +} + +/* + * Save the write to the cache also. + */ +static void afs_write_to_cache(struct afs_vnode *vnode, + loff_t start, size_t len, loff_t i_size) +{ + fscache_write_to_cache(afs_vnode_cache(vnode), + vnode->vfs_inode.i_mapping, start, len, i_size, + afs_write_to_cache_done, vnode); +} From patchwork Mon Oct 18 15:04:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567213 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 84BE9C433F5 for ; Mon, 18 Oct 2021 15:05:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6C183610A1 for ; Mon, 18 Oct 2021 15:05:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232183AbhJRPIA (ORCPT ); Mon, 18 Oct 2021 11:08:00 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:45402 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233642AbhJRPHK (ORCPT ); Mon, 18 Oct 2021 11:07:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569498; 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=34+aPebgzzHxYJ84OQLGkAmjt/20nxAv2uPWKUz1+/c=; b=D3OjzVwR+I2Tg2eqrB5PBp0RA/PpRwlCV/DUVgljL9vdqYJEWvrELpqI5YUlpgvzQbr+h1 +e2fXCGn4CYyOOOPzT2GUNd70ProFyZEQEx0Wvf+yjV3lNkn8FrHxqELBGFGBAQSnyaKaf LQlrqERLV2mrO7oCQ/YkRVFsSwJrZLk= 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-596-ouOaMab7MBK4Y2RN2Uc4WA-1; Mon, 18 Oct 2021 11:04:53 -0400 X-MC-Unique: ouOaMab7MBK4Y2RN2Uc4WA-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 21E2E80982E; Mon, 18 Oct 2021 15:04:51 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id B868F108D7; Mon, 18 Oct 2021 15:04:09 +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 53/67] afs: Invoke fscache_resize_cookie() when handling ATTR_SIZE for setattr From: David Howells To: linux-cachefs@redhat.com Cc: Marc Dionne , linux-afs@lists.infradead.org, dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:04:08 +0100 Message-ID: <163456944892.2614702.6257175032771958470.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Invoke fscache_resize_cookie() to adjust the size of the backing cache object when setattr is called with ATTR_SIZE. This discards any data that then lies beyond the revised EOF and frees up space. Signed-off-by: David Howells cc: Marc Dionne cc: linux-afs@lists.infradead.org --- fs/afs/inode.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 311df66c64d0..c4af4fda37dd 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -829,6 +829,9 @@ static void afs_setattr_edit_file(struct afs_operation *op) if (size < i_size) truncate_pagecache(inode, size); + if (size != i_size) + fscache_resize_cookie(afs_vnode_cache(vp->vnode), + vp->scb.status.size); } } @@ -872,6 +875,8 @@ int afs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, attr->ia_valid &= ~ATTR_SIZE; } + fscache_use_cookie(afs_vnode_cache(vnode), true); + /* flush any dirty data outstanding on a regular file */ if (S_ISREG(vnode->vfs_inode.i_mode)) filemap_write_and_wait(vnode->vfs_inode.i_mapping); @@ -903,6 +908,7 @@ int afs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, out_unlock: up_write(&vnode->validate_lock); + fscache_unuse_cookie(afs_vnode_cache(vnode), NULL, NULL); _leave(" = %d", ret); return ret; } From patchwork Mon Oct 18 15:04:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567215 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EEDF2C433EF for ; Mon, 18 Oct 2021 15:05:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D500C610A1 for ; Mon, 18 Oct 2021 15:05:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231676AbhJRPIG (ORCPT ); Mon, 18 Oct 2021 11:08:06 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:58258 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233352AbhJRPHX (ORCPT ); Mon, 18 Oct 2021 11:07:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569511; 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=awbJf1qi+AjflO5r5/tdZDW0h34mY/1A+ED+H3+96GA=; b=PCWaltYDEMwRwlf8wXqZteghQyJwmuD9oCShLldzrQiRZYpWcv76RUBAFXYmebtQSnEvia 5t4pRqcHVk5Mad/cVOsA62WsDNetvJ+DEhoNhB/P6ym5fYJ95QZPbCNFZonlRPUBww1wDy QuYEkUVzAHcJ4nzMxqSkZsgtJBEe21g= 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-443-1YjU_XZfMoSeu8aXA63h0w-1; Mon, 18 Oct 2021 11:05:10 -0400 X-MC-Unique: 1YjU_XZfMoSeu8aXA63h0w-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9D0BA1018723; Mon, 18 Oct 2021 15:05:06 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1F3C95D6D7; Mon, 18 Oct 2021 15:04:56 +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 54/67] afs: Add O_DIRECT read support From: David Howells To: linux-cachefs@redhat.com Cc: Marc Dionne , linux-afs@lists.infradead.org, dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:04:56 +0100 Message-ID: <163456949634.2614702.977164796285038310.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Add synchronous O_DIRECT read support to AFS (no AIO yet). It can theoretically handle reads up to the maximum size describable by loff_t - and given an iterator with sufficiently capacity to handle that and given support on the server. Signed-off-by: David Howells cc: Marc Dionne cc: linux-afs@lists.infradead.org --- fs/afs/file.c | 59 +++++++++++++++++++++++++++++++++++++++++++ fs/afs/fsclient.c | 18 +++++++++---- fs/afs/internal.h | 2 + fs/afs/write.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++- fs/afs/yfsclient.c | 12 ++++++--- 5 files changed, 153 insertions(+), 10 deletions(-) diff --git a/fs/afs/file.c b/fs/afs/file.c index 4af7ef607cf6..5db1e7d29ad5 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -28,6 +28,7 @@ static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter); static void afs_vm_open(struct vm_area_struct *area); static void afs_vm_close(struct vm_area_struct *area); static vm_fault_t afs_vm_map_pages(struct vm_fault *vmf, pgoff_t start_pgoff, pgoff_t end_pgoff); +static ssize_t afs_direct_IO(struct kiocb *iocb, struct iov_iter *iter); const struct file_operations afs_file_operations = { .open = afs_open, @@ -56,6 +57,7 @@ const struct address_space_operations afs_fs_aops = { .launder_page = afs_launder_page, .releasepage = afs_releasepage, .invalidatepage = afs_invalidatepage, + .direct_IO = afs_direct_IO, .write_begin = afs_write_begin, .write_end = afs_write_end, .writepage = afs_writepage, @@ -601,3 +603,60 @@ static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) return generic_file_read_iter(iocb, iter); } + +/* + * Direct file read operation for an AFS file. + * + * TODO: To support AIO, the pages in the iterator have to be copied and + * refs taken on them. Then -EIOCBQUEUED needs to be returned. + * iocb->ki_complete must then be called upon completion of the operation. + */ +static ssize_t afs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter) +{ + struct file *file = iocb->ki_filp; + struct afs_vnode *vnode = AFS_FS_I(file_inode(file)); + struct afs_read *req; + ssize_t ret, transferred; + + _enter("%llx,%zx", iocb->ki_pos, iov_iter_count(iter)); + + req = afs_alloc_read(GFP_KERNEL); + if (!req) + return -ENOMEM; + + req->vnode = vnode; + req->key = key_get(afs_file_key(file)); + req->pos = iocb->ki_pos; + req->len = iov_iter_count(iter); + req->iter = iter; + + task_io_account_read(req->len); + + // TODO nfs_start_io_direct(inode); + ret = afs_fetch_data(vnode, req); + if (ret == 0) + transferred = req->actual_len; + afs_put_read(req); + + // TODO nfs_end_io_direct(inode); + + if (ret == 0) + ret = transferred; + + BUG_ON(ret == -EIOCBQUEUED); // TODO + //if (iocb->ki_complete) + // iocb->ki_complete(iocb, ret, 0); // only if ret == -EIOCBQUEUED + + _leave(" = %zu", ret); + return ret; +} + +/* + * Do direct I/O. + */ +static ssize_t afs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) +{ + if (iov_iter_rw(iter) == READ) + return afs_file_direct_read(iocb, iter); + return afs_file_direct_write(iocb, iter); +} diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index 4943413d9c5f..290d4d391a0e 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c @@ -439,7 +439,7 @@ static void afs_fs_fetch_data64(struct afs_operation *op) bp[3] = htonl(vp->fid.unique); bp[4] = htonl(upper_32_bits(req->pos)); bp[5] = htonl(lower_32_bits(req->pos)); - bp[6] = 0; + bp[6] = htonl(upper_32_bits(req->len)); bp[7] = htonl(lower_32_bits(req->len)); trace_afs_make_fs_call(call, &vp->fid); @@ -1057,6 +1057,7 @@ static void afs_fs_store_data64(struct afs_operation *op) struct afs_vnode_param *vp = &op->file[0]; struct afs_call *call; __be32 *bp; + u32 mask = 0; _enter(",%x,{%llx:%llu},,", key_serial(op->key), vp->fid.vid, vp->fid.vnode); @@ -1069,6 +1070,9 @@ static void afs_fs_store_data64(struct afs_operation *op) call->write_iter = op->store.write_iter; + if (op->flags & AFS_OPERATION_SET_MTIME) + mask |= AFS_SET_MTIME; + /* marshall the parameters */ bp = call->request; *bp++ = htonl(FSSTOREDATA64); @@ -1076,8 +1080,8 @@ static void afs_fs_store_data64(struct afs_operation *op) *bp++ = htonl(vp->fid.vnode); *bp++ = htonl(vp->fid.unique); - *bp++ = htonl(AFS_SET_MTIME); /* mask */ - *bp++ = htonl(op->mtime.tv_sec); /* mtime */ + *bp++ = htonl(mask); + *bp++ = htonl(op->mtime.tv_sec); *bp++ = 0; /* owner */ *bp++ = 0; /* group */ *bp++ = 0; /* unix mode */ @@ -1102,6 +1106,7 @@ void afs_fs_store_data(struct afs_operation *op) struct afs_vnode_param *vp = &op->file[0]; struct afs_call *call; __be32 *bp; + u32 mask = 0; _enter(",%x,{%llx:%llu},,", key_serial(op->key), vp->fid.vid, vp->fid.vnode); @@ -1122,6 +1127,9 @@ void afs_fs_store_data(struct afs_operation *op) call->write_iter = op->store.write_iter; + if (op->flags & AFS_OPERATION_SET_MTIME) + mask |= AFS_SET_MTIME; + /* marshall the parameters */ bp = call->request; *bp++ = htonl(FSSTOREDATA); @@ -1129,8 +1137,8 @@ void afs_fs_store_data(struct afs_operation *op) *bp++ = htonl(vp->fid.vnode); *bp++ = htonl(vp->fid.unique); - *bp++ = htonl(AFS_SET_MTIME); /* mask */ - *bp++ = htonl(op->mtime.tv_sec); /* mtime */ + *bp++ = htonl(mask); + *bp++ = htonl(op->mtime.tv_sec); *bp++ = 0; /* owner */ *bp++ = 0; /* group */ *bp++ = 0; /* unix mode */ diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 07d34291bf4f..d3fb9b3845bc 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -863,6 +863,7 @@ struct afs_operation { #define AFS_OPERATION_TRIED_ALL 0x0400 /* Set if we've tried all the fileservers */ #define AFS_OPERATION_RETRY_SERVER 0x0800 /* Set if we should retry the current server */ #define AFS_OPERATION_DIR_CONFLICT 0x1000 /* Set if we detected a 3rd-party dir change */ +#define AFS_OPERATION_SET_MTIME 0x2000 /* Set if we should try to store the mtime */ }; /* @@ -1538,6 +1539,7 @@ extern int afs_fsync(struct file *, loff_t, loff_t, int); extern vm_fault_t afs_page_mkwrite(struct vm_fault *vmf); extern void afs_prune_wb_keys(struct afs_vnode *); extern int afs_launder_page(struct page *); +extern ssize_t afs_file_direct_write(struct kiocb *, struct iov_iter *); /* * xattr.c diff --git a/fs/afs/write.c b/fs/afs/write.c index a540da6ad423..281f0e93e2c6 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c @@ -406,7 +406,7 @@ static int afs_store_data(struct afs_vnode *vnode, struct iov_iter *iter, loff_t op->store.i_size = max(pos + size, i_size); op->store.laundering = laundering; op->mtime = vnode->vfs_inode.i_mtime; - op->flags |= AFS_OPERATION_UNINTR; + op->flags |= AFS_OPERATION_SET_MTIME | AFS_OPERATION_UNINTR; op->ops = &afs_store_data_operation; try_next_key: @@ -1039,3 +1039,73 @@ static void afs_write_to_cache(struct afs_vnode *vnode, vnode->vfs_inode.i_mapping, start, len, i_size, afs_write_to_cache_done, vnode); } + +static void afs_dio_store_data_success(struct afs_operation *op) +{ + struct afs_vnode *vnode = op->file[0].vnode; + + op->ctime = op->file[0].scb.status.mtime_client; + afs_vnode_commit_status(op, &op->file[0]); + if (op->error == 0) { + afs_stat_v(vnode, n_stores); + atomic_long_add(op->store.size, &afs_v2net(vnode)->n_store_bytes); + } +} + +static const struct afs_operation_ops afs_dio_store_data_operation = { + .issue_afs_rpc = afs_fs_store_data, + .issue_yfs_rpc = yfs_fs_store_data, + .success = afs_dio_store_data_success, +}; + +/* + * Direct file write operation for an AFS file. + * + * TODO: To support AIO, the pages in the iterator have to be copied and + * refs taken on them. Then -EIOCBQUEUED needs to be returned. + * iocb->ki_complete must then be called upon completion of the operation. + */ +ssize_t afs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter) +{ + struct file *file = iocb->ki_filp; + struct afs_vnode *vnode = AFS_FS_I(file_inode(file)); + struct afs_operation *op; + loff_t size = iov_iter_count(iter), i_size; + ssize_t ret; + + _enter("%s{%llx:%llu.%u},%llx,%llx", + vnode->volume->name, + vnode->fid.vid, + vnode->fid.vnode, + vnode->fid.unique, + size, iocb->ki_pos); + + op = afs_alloc_operation(afs_file_key(file), vnode->volume); + if (IS_ERR(op)) + return -ENOMEM; + + i_size = i_size_read(&vnode->vfs_inode); + + afs_op_set_vnode(op, 0, vnode); + op->file[0].dv_delta = 1; + op->file[0].set_size = true; + op->store.write_iter = iter; + op->store.pos = iocb->ki_pos; + op->store.size = size; + op->store.i_size = max(iocb->ki_pos + size, i_size); + op->ops = &afs_dio_store_data_operation; + + //if (!is_sync_kiocb(iocb)) { + + ret = afs_do_sync_operation(op); + if (ret == 0) + ret = size; + + afs_invalidate_cache(vnode, FSCACHE_INVAL_DIO_WRITE); + + //if (iocb->ki_complete) + // iocb->ki_complete(iocb, ret, 0); // only if ret == -EIOCBQUEUED + + _leave(" = %zd", ret); + return ret; +} diff --git a/fs/afs/yfsclient.c b/fs/afs/yfsclient.c index 2b35cba8ad62..a8c4e230002d 100644 --- a/fs/afs/yfsclient.c +++ b/fs/afs/yfsclient.c @@ -95,12 +95,16 @@ static __be32 *xdr_encode_YFSStoreStatus_mode(__be32 *bp, mode_t mode) return bp + xdr_size(x); } -static __be32 *xdr_encode_YFSStoreStatus_mtime(__be32 *bp, const struct timespec64 *t) +static __be32 *xdr_encode_YFSStoreStatus_mtime(__be32 *bp, struct afs_operation *op) { struct yfs_xdr_YFSStoreStatus *x = (void *)bp; - s64 mtime = linux_to_yfs_time(t); + s64 mtime = linux_to_yfs_time(&op->mtime); + u32 mask = 0; - x->mask = htonl(AFS_SET_MTIME); + if (op->flags & AFS_OPERATION_SET_MTIME) + mask |= AFS_SET_MTIME; + + x->mask = htonl(mask); x->mode = htonl(0); x->mtime_client = u64_to_xdr(mtime); x->owner = u64_to_xdr(0); @@ -1103,7 +1107,7 @@ void yfs_fs_store_data(struct afs_operation *op) bp = xdr_encode_u32(bp, YFSSTOREDATA64); bp = xdr_encode_u32(bp, 0); /* RPC flags */ bp = xdr_encode_YFSFid(bp, &vp->fid); - bp = xdr_encode_YFSStoreStatus_mtime(bp, &op->mtime); + bp = xdr_encode_YFSStoreStatus_mtime(bp, op); bp = xdr_encode_u64(bp, op->store.pos); bp = xdr_encode_u64(bp, op->store.size); bp = xdr_encode_u64(bp, op->store.i_size); From patchwork Mon Oct 18 15:05:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567219 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC6DEC433F5 for ; Mon, 18 Oct 2021 15:06:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9A45D60E0C for ; Mon, 18 Oct 2021 15:06:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232094AbhJRPJH (ORCPT ); Mon, 18 Oct 2021 11:09:07 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:22462 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231775AbhJRPHo (ORCPT ); Mon, 18 Oct 2021 11:07:44 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569532; 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=lCtXt/S98B8O04e5eLfCRcYEGlq2GeHKHWlj3+Qmlnw=; b=dSG9lLilqzKM9fuQ8O4Fw/z8dv7uwZNHWVctLdMobhbJapuyq3uYQmMdPdB8o6fCXn9UPR u3zzA9RmUdNC9Zh2sHS1TN+kX0A0o3XPErCq483N0A7LNWQOSzZIl7Drsz6IxzvQXcVGuX EHs1BqZjeQ64TJHnhic2YFiyL5KEDjw= 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-428-eqeM14vVO2quZOXq8ExUyA-1; Mon, 18 Oct 2021 11:05:29 -0400 X-MC-Unique: eqeM14vVO2quZOXq8ExUyA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7272910151E0; Mon, 18 Oct 2021 15:05:27 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id A12FE57CA4; Mon, 18 Oct 2021 15:05:12 +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 55/67] afs: Skip truncation on the server of data we haven't written yet From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:05:11 +0100 Message-ID: <163456951186.2614702.16840420880926305225.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Don't send a truncation RPC to the server if we're only shortening data that's in the pagecache and is beyond the server's EOF. Also don't automatically force writeback on setattr, but do wait to store RPCs that are in the region to be removed on a shortening truncation. Signed-off-by: David Howells --- fs/afs/inode.c | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/fs/afs/inode.c b/fs/afs/inode.c index c4af4fda37dd..4c66a2b86add 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -848,42 +848,67 @@ static const struct afs_operation_ops afs_setattr_operation = { int afs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, struct iattr *attr) { + const unsigned int supported = + ATTR_SIZE | ATTR_MODE | ATTR_UID | ATTR_GID | + ATTR_MTIME | ATTR_MTIME_SET | ATTR_TIMES_SET | ATTR_TOUCH; struct afs_operation *op; struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry)); + struct inode *inode = &vnode->vfs_inode; + loff_t i_size; int ret; _enter("{%llx:%llu},{n=%pd},%x", vnode->fid.vid, vnode->fid.vnode, dentry, attr->ia_valid); - if (!(attr->ia_valid & (ATTR_SIZE | ATTR_MODE | ATTR_UID | ATTR_GID | - ATTR_MTIME | ATTR_MTIME_SET | ATTR_TIMES_SET | - ATTR_TOUCH))) { + if (!(attr->ia_valid & supported)) { _leave(" = 0 [unsupported]"); return 0; } + i_size = i_size_read(inode); if (attr->ia_valid & ATTR_SIZE) { - if (!S_ISREG(vnode->vfs_inode.i_mode)) + if (!S_ISREG(inode->i_mode)) return -EISDIR; - ret = inode_newsize_ok(&vnode->vfs_inode, attr->ia_size); + ret = inode_newsize_ok(inode, attr->ia_size); if (ret) return ret; - if (attr->ia_size == i_size_read(&vnode->vfs_inode)) + if (attr->ia_size == i_size) attr->ia_valid &= ~ATTR_SIZE; } fscache_use_cookie(afs_vnode_cache(vnode), true); - /* flush any dirty data outstanding on a regular file */ - if (S_ISREG(vnode->vfs_inode.i_mode)) - filemap_write_and_wait(vnode->vfs_inode.i_mapping); - /* Prevent any new writebacks from starting whilst we do this. */ down_write(&vnode->validate_lock); + if ((attr->ia_valid & ATTR_SIZE) && S_ISREG(inode->i_mode)) { + loff_t size = attr->ia_size; + + /* Wait for any outstanding writes to the server to complete */ + loff_t from = min(size, i_size); + loff_t to = max(size, i_size); + ret = filemap_fdatawait_range(inode->i_mapping, from, to); + if (ret < 0) + goto out_unlock; + + /* Don't talk to the server if we're just shortening in-memory + * writes that haven't gone to the server yet. + */ + if (!(attr->ia_valid & (supported & ~ATTR_SIZE & ~ATTR_MTIME)) && + attr->ia_size < i_size && + attr->ia_size > vnode->status.size) { + truncate_pagecache(inode, attr->ia_size); + fscache_resize_cookie(afs_vnode_cache(vnode), + attr->ia_size); + i_size_write(inode, attr->ia_size); + ret = 0; + goto out_unlock; + } + } + op = afs_alloc_operation(((attr->ia_valid & ATTR_FILE) ? afs_file_key(attr->ia_file) : NULL), vnode->volume); From patchwork Mon Oct 18 15:05:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567221 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2EE49C4332F for ; Mon, 18 Oct 2021 15:06:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 13A5660E0C for ; Mon, 18 Oct 2021 15:06:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232117AbhJRPJI (ORCPT ); Mon, 18 Oct 2021 11:09:08 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:22237 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233092AbhJRPIE (ORCPT ); Mon, 18 Oct 2021 11:08:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569552; 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=XmPiML3uG821PVI2wOxhR6XbrMl1/IZxCyEQC1pxf2Y=; b=ENfz0Zn9mMlpH1mN+z0c8hP3NNyQv0VwUN7ow3AsrhChfANBiCpBJfYvG7deL2mKaAVy7x EVbqd/6OosVmRF6e3trl0N/qheO8rmgx0pQ8FuemqB9Eq9ZIWA7zHe/5aEV+kIsoBLkWPo giI1+vyp3kTQtpmwnDN9og2gNYy1cGI= 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-221-gvU46tYSPJWxM_EDE4T5Qw-1; Mon, 18 Oct 2021 11:05:49 -0400 X-MC-Unique: gvU46tYSPJWxM_EDE4T5Qw-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 14C6480DDE4; Mon, 18 Oct 2021 15:05:47 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 97529100E809; Mon, 18 Oct 2021 15:05:33 +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 56/67] afs: Make afs_write_begin() return the THP subpage From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:05:32 +0100 Message-ID: <163456953268.2614702.4818196302635334339.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org generic_perform_write() can't handle a THP, so we have to return the subpage of that THP from afs_write_begin() and then convert it back into the head on entry to afs_write_end(). Signed-off-by: David Howells --- fs/afs/write.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/afs/write.c b/fs/afs/write.c index 281f0e93e2c6..5cd417e95029 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c @@ -90,7 +90,7 @@ int afs_write_begin(struct file *file, struct address_space *mapping, goto flush_conflicting_write; } - *_page = page; + *_page = find_subpage(page, pos / PAGE_SIZE); _leave(" = 0"); return 0; @@ -120,9 +120,10 @@ int afs_write_begin(struct file *file, struct address_space *mapping, */ int afs_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, - struct page *page, void *fsdata) + struct page *subpage, void *fsdata) { struct afs_vnode *vnode = AFS_FS_I(file_inode(file)); + struct page *page = thp_head(subpage); unsigned long priv; unsigned int f, from = offset_in_thp(page, pos); unsigned int t, to = from + copied; From patchwork Mon Oct 18 15:05:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567217 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F3733C433EF for ; Mon, 18 Oct 2021 15:06:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DB32A60E0C for ; Mon, 18 Oct 2021 15:06:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233280AbhJRPIr (ORCPT ); Mon, 18 Oct 2021 11:08:47 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:21524 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233935AbhJRPIg (ORCPT ); Mon, 18 Oct 2021 11:08:36 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569584; 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=veiaXltL6VCtrjdWipdEmPq2N2GsVmVphqdEUrpeTnQ=; b=WyVZ/QZt1gvi/RMv1BLtz97ZsJnUtbLXXtbgO5cLbrvqCA9AzA7DgU2QDHZ6nlbFKN7vYo dTVCM2kNm6XgcgT1Ea8kJ5lLygeTTEs4jOPYcrOzf70GwlzfFFl6AvqHCWF5MIbiC4rBKW pXUdKrl4yogr7U2/g3PMb1z6Q59v6Dw= 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-278-Ey0meNAIMT-wBxUNPFUEoA-1; Mon, 18 Oct 2021 11:06:21 -0400 X-MC-Unique: Ey0meNAIMT-wBxUNPFUEoA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 754B0DF8A4; Mon, 18 Oct 2021 15:06:19 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2E37C60E1C; Mon, 18 Oct 2021 15:05:53 +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 57/67] cachefiles, afs: Drive FSCACHE_COOKIE_NO_DATA_TO_READ From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:05:52 +0100 Message-ID: <163456955230.2614702.5960779119312105796.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Drive the FSCACHE_COOKIE_NO_DATA_TO_READ bit to skip reads on cache files that can't have any data available to read. This needs clearing once we've written some data and then released the netfs page that contained it. Signed-off-by: David Howells --- fs/afs/file.c | 1 + fs/cachefiles/io.c | 1 + fs/fscache/cookie.c | 2 ++ include/linux/fscache.h | 16 ++++++++++++++++ 4 files changed, 20 insertions(+) diff --git a/fs/afs/file.c b/fs/afs/file.c index 5db1e7d29ad5..7fe57f210259 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -506,6 +506,7 @@ static int afs_releasepage(struct page *page, gfp_t gfp_flags) return false; wait_on_page_fscache(page); } + fscache_note_page_release(afs_vnode_cache(vnode)); #endif if (PagePrivate(page)) { diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index 9b3b55a94e66..5e3579800689 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -195,6 +195,7 @@ static void cachefiles_write_complete(struct kiocb *iocb, long ret, long ret2) __sb_writers_acquired(inode->i_sb, SB_FREEZE_WRITE); __sb_end_write(inode->i_sb, SB_FREEZE_WRITE); + set_bit(FSCACHE_COOKIE_HAVE_DATA, &ki->object->cookie->flags); if (ki->term_func) ki->term_func(ki->term_func_priv, ret, ki->was_async); cachefiles_put_kiocb(ki); diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 1420027cfe97..369f9258bb50 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -263,6 +263,8 @@ static struct fscache_cookie *fscache_alloc_cookie( cookie->key_len = index_key_len; cookie->aux_len = aux_data_len; cookie->object_size = object_size; + if (object_size == 0) + __set_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags); if (fscache_set_key(cookie, index_key, index_key_len) < 0) goto nomem; diff --git a/include/linux/fscache.h b/include/linux/fscache.h index ba192567d099..d18b7d3564ab 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -131,6 +131,7 @@ struct fscache_cookie { #define FSCACHE_COOKIE_DO_WITHDRAW 10 /* T if this cookie needs withdrawing */ #define FSCACHE_COOKIE_DO_COMMIT 11 /* T if this cookie needs committing */ #define FSCACHE_COOKIE_DO_PREP_TO_WRITE 12 /* T if cookie needs write preparation */ +#define FSCACHE_COOKIE_HAVE_DATA 13 /* T if this cookie has data stored */ enum fscache_cookie_stage stage; u8 advice; /* FSCACHE_ADV_* */ @@ -643,7 +644,22 @@ static inline void fscache_clear_inode_writeback(struct fscache_cookie *cookie, loff_t i_size = i_size_read(inode); fscache_unuse_cookie(cookie, aux, &i_size); } +} +/** + * fscache_note_page_release - Note that a netfs page got released + * @cookie: The cookie corresponding to the file + * + * Note that a page that has been copied to the cache has been released. This + * means that future reads will need to look in the cache to see if it's there. + */ +static inline +void fscache_note_page_release(struct fscache_cookie *cookie) +{ + if (cookie && + test_bit(FSCACHE_COOKIE_HAVE_DATA, &cookie->flags) && + test_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags)) + clear_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags); } #ifdef FSCACHE_USE_FALLBACK_IO_API From patchwork Mon Oct 18 15:06:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567223 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4560CC4332F for ; Mon, 18 Oct 2021 15:07:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3397960EE9 for ; Mon, 18 Oct 2021 15:07:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232231AbhJRPJ1 (ORCPT ); Mon, 18 Oct 2021 11:09:27 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:40584 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232815AbhJRPJL (ORCPT ); Mon, 18 Oct 2021 11:09:11 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569619; 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=SpDU7Yd4WeGgEtFtDrVHZCDDE0kPzrjNK8Y5Mkoa7iA=; b=h/68BCw/knY+ngFUp5podSusFlWF+atSKTeSN61JGHtDgks455LF1H0W2/W19LFgUh6yr3 LI8jbQLeQWQ330pX9xeAKUMfCDubpRfNqQ4yW8E1hxCJ4Zc7BOUQKoxNNmJC2G8YhKDnCU YyE/ZnPFbnK7P6H6q6+O3kib9bWCo6A= 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-594-CrAbGunJNI-ur0pcdh5kmA-1; Mon, 18 Oct 2021 11:06:56 -0400 X-MC-Unique: CrAbGunJNI-ur0pcdh5kmA-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 CF2CD10151E0; Mon, 18 Oct 2021 15:06:53 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7F64A60D30; Mon, 18 Oct 2021 15:06:25 +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 58/67] NFS: Convert fscache_acquire_cookie and fscache_relinquish_cookie From: David Howells To: linux-cachefs@redhat.com Cc: Dave Wysochanski , Trond Myklebust , Anna Schumaker , linux-nfs@vger.kernel.org, dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:06:24 +0100 Message-ID: <163456958468.2614702.7692988896929155656.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org From: Dave Wysochanski The new FS-Cache netfs API changes the cookie API slightly. The changes to fscache_acquire_cookie are: * remove struct fscache_cookie_def * add 'type' of cookie (was member of fscache_cookie_def) * add 'name' of cookie (was member of fscache_cookie_def) * add 'advice' flags (tells cache how to handle object); set to 0 * add 'preferred_cache' tag (if NULL, derive from parent) * remove 'netfs_data' * remove 'enable' (See fscache_use_cookie()) The changes to fscache_relinquish_cookie are: * remove 'aux_data' Signed-off-by: Dave Wysochanski Signed-off-by: David Howells cc: Trond Myklebust cc: Anna Schumaker cc: linux-nfs@vger.kernel.org --- fs/nfs/fscache-index.c | 68 ------------------------------------------------ fs/nfs/fscache.c | 44 ++++++++++++++++++++----------- fs/nfs/fscache.h | 3 -- 3 files changed, 29 insertions(+), 86 deletions(-) diff --git a/fs/nfs/fscache-index.c b/fs/nfs/fscache-index.c index 4bd5ce736193..b4fdacd955f3 100644 --- a/fs/nfs/fscache-index.c +++ b/fs/nfs/fscache-index.c @@ -44,71 +44,3 @@ void nfs_fscache_unregister(void) { fscache_unregister_netfs(&nfs_fscache_netfs); } - -/* - * Define the server object for FS-Cache. This is used to describe a server - * object to fscache_acquire_cookie(). It is keyed by the NFS protocol and - * server address parameters. - */ -const struct fscache_cookie_def nfs_fscache_server_index_def = { - .name = "NFS.server", - .type = FSCACHE_COOKIE_TYPE_INDEX, -}; - -/* - * Define the superblock object for FS-Cache. This is used to describe a - * superblock object to fscache_acquire_cookie(). It is keyed by all the NFS - * parameters that might cause a separate superblock. - */ -const struct fscache_cookie_def nfs_fscache_super_index_def = { - .name = "NFS.super", - .type = FSCACHE_COOKIE_TYPE_INDEX, -}; - -/* - * Consult the netfs about the state of an object - * - This function can be absent if the index carries no state data - * - The netfs data from the cookie being used as the target is - * presented, as is the auxiliary data - */ -static -enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data, - const void *data, - uint16_t datalen, - loff_t object_size) -{ - struct nfs_fscache_inode_auxdata auxdata; - struct nfs_inode *nfsi = cookie_netfs_data; - - if (datalen != sizeof(auxdata)) - return FSCACHE_CHECKAUX_OBSOLETE; - - memset(&auxdata, 0, sizeof(auxdata)); - auxdata.mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec; - auxdata.mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec; - auxdata.ctime_sec = nfsi->vfs_inode.i_ctime.tv_sec; - auxdata.ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec; - - if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4) - auxdata.change_attr = inode_peek_iversion_raw(&nfsi->vfs_inode); - - if (memcmp(data, &auxdata, datalen) != 0) - return FSCACHE_CHECKAUX_OBSOLETE; - - return FSCACHE_CHECKAUX_OKAY; -} - -/* - * Define the inode object for FS-Cache. This is used to describe an inode - * object to fscache_acquire_cookie(). It is keyed by the NFS file handle for - * an inode. - * - * Coherency is managed by comparing the copies of i_size, i_mtime and i_ctime - * held in the cache auxiliary data for the data storage object with those in - * the inode struct in memory. - */ -const struct fscache_cookie_def nfs_fscache_inode_object_def = { - .name = "NFS.fh", - .type = FSCACHE_COOKIE_TYPE_DATAFILE, - .check_aux = nfs_fscache_inode_check_aux, -}; diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index 68e266a37675..514d50d079a2 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c @@ -81,10 +81,15 @@ void nfs_fscache_get_client_cookie(struct nfs_client *clp) /* create a cache index for looking up filehandles */ clp->fscache = fscache_acquire_cookie(nfs_fscache_netfs.primary_index, - &nfs_fscache_server_index_def, - &key, len, - NULL, 0, - clp, 0, true); + FSCACHE_COOKIE_TYPE_INDEX, + "NFS.server", + 0, /* advice */ + NULL, /* preferred_cache */ + &key, /* index_key */ + len, + NULL, /* aux_data */ + 0, + 0); dfprintk(FSCACHE, "NFS: get client cookie (0x%p/0x%p)\n", clp, clp->fscache); } @@ -97,7 +102,7 @@ void nfs_fscache_release_client_cookie(struct nfs_client *clp) dfprintk(FSCACHE, "NFS: releasing client cookie (0x%p/0x%p)\n", clp, clp->fscache); - fscache_relinquish_cookie(clp->fscache, NULL, false); + fscache_relinquish_cookie(clp->fscache, false); clp->fscache = NULL; } @@ -185,11 +190,15 @@ void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, int /* create a cache index for looking up filehandles */ nfss->fscache = fscache_acquire_cookie(nfss->nfs_client->fscache, - &nfs_fscache_super_index_def, - &key->key, + FSCACHE_COOKIE_TYPE_INDEX, + "NFS.super", + 0, /* advice */ + NULL, /* preferred_cache */ + &key->key, /* index_key */ sizeof(key->key) + ulen, - NULL, 0, - nfss, 0, true); + NULL, /* aux_data */ + 0, + 0); dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n", nfss, nfss->fscache); return; @@ -213,7 +222,7 @@ void nfs_fscache_release_super_cookie(struct super_block *sb) dfprintk(FSCACHE, "NFS: releasing superblock cookie (0x%p/0x%p)\n", nfss, nfss->fscache); - fscache_relinquish_cookie(nfss->fscache, NULL, false); + fscache_relinquish_cookie(nfss->fscache, false); nfss->fscache = NULL; if (nfss->fscache_key) { @@ -254,10 +263,15 @@ void nfs_fscache_init_inode(struct inode *inode) nfs_fscache_update_auxdata(&auxdata, nfsi); nfsi->fscache = fscache_acquire_cookie(NFS_SB(inode->i_sb)->fscache, - &nfs_fscache_inode_object_def, - nfsi->fh.data, nfsi->fh.size, - &auxdata, sizeof(auxdata), - nfsi, nfsi->vfs_inode.i_size, false); + FSCACHE_COOKIE_TYPE_DATAFILE, + "NFS.fh", + 0, /* advice */ + NULL, /* preferred_cache */ + nfsi->fh.data, /* index_key */ + nfsi->fh.size, + &auxdata, /* aux_data */ + sizeof(auxdata), + i_size_read(&nfsi->vfs_inode)); } /* @@ -272,7 +286,7 @@ void nfs_fscache_clear_inode(struct inode *inode) dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n", nfsi, cookie); nfs_fscache_update_auxdata(&auxdata, nfsi); - fscache_relinquish_cookie(cookie, &auxdata, false); + fscache_relinquish_cookie(cookie, false); nfsi->fscache = NULL; } diff --git a/fs/nfs/fscache.h b/fs/nfs/fscache.h index 679055720dae..1e30fcb45665 100644 --- a/fs/nfs/fscache.h +++ b/fs/nfs/fscache.h @@ -74,9 +74,6 @@ struct nfs_fscache_inode_auxdata { * fscache-index.c */ extern struct fscache_netfs nfs_fscache_netfs; -extern const struct fscache_cookie_def nfs_fscache_server_index_def; -extern const struct fscache_cookie_def nfs_fscache_super_index_def; -extern const struct fscache_cookie_def nfs_fscache_inode_object_def; extern int nfs_fscache_register(void); extern void nfs_fscache_unregister(void); From patchwork Mon Oct 18 15:06:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567225 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C90D0C433F5 for ; Mon, 18 Oct 2021 15:08:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A464B60F94 for ; Mon, 18 Oct 2021 15:08:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232601AbhJRPKS (ORCPT ); Mon, 18 Oct 2021 11:10:18 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:55952 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232815AbhJRPKH (ORCPT ); Mon, 18 Oct 2021 11:10:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569676; 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=S7tYvoqJuZNp85jt5vuBHAbTrQ0z769O2KLpPImxuDo=; b=NRCtYsk9hadMgwj1xeMEmooHEQWHNe76kO20drBjyBYNPizaiSo3piLt+V1oRGbNjGRuRr TeVcBRkOmCzUYVtB4cgbXGUPFJbUmRRezeDdr25SUlKv848F8nMbB5VSkC/8M5igJ3HX0W yc4tJpPNyUtEvY8EDBZB4+A2jBX9TCI= 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-593-02JGHUnMOKqBhV6EK9P_0g-1; Mon, 18 Oct 2021 11:07:52 -0400 X-MC-Unique: 02JGHUnMOKqBhV6EK9P_0g-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 847E780A5C0; Mon, 18 Oct 2021 15:07:50 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1CB6C5DF56; Mon, 18 Oct 2021 15:06:59 +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 59/67] NFS: Convert fscache_enable_cookie and fscache_disable_cookie From: David Howells To: linux-cachefs@redhat.com Cc: Dave Wysochanski , Trond Myklebust , Anna Schumaker , linux-nfs@vger.kernel.org, dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:06:59 +0100 Message-ID: <163456961924.2614702.6166404296569864407.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org From: Dave Wysochanski The new FS-Cache API removes the fscache_enable_cookie() and fscache_disable_cookie() in favor of the new APIs fscache_use_cookie() and fscache_unuse_cookie(), so update these areas as needed. For NFS, we enable fscache on an inode only if the inode is open readonly and not if the inode is open for write. Use the new APIs and change the existing logic slightly and make a decision whether to "use" an inode based fscache cookie one time, by gating the call to fscache_use_cookie() and fscache_unuse_cookie() by the NFS_INO_FSCACHE flag on the nfs_inode. Signed-off-by: Dave Wysochanski Signed-off-by: David Howells cc: Trond Myklebust cc: Anna Schumaker cc: linux-nfs@vger.kernel.org --- fs/nfs/fscache.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index 514d50d079a2..5e584f2e84a9 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c @@ -285,7 +285,10 @@ void nfs_fscache_clear_inode(struct inode *inode) dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n", nfsi, cookie); - nfs_fscache_update_auxdata(&auxdata, nfsi); + if (test_and_clear_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags)) { + nfs_fscache_update_auxdata(&auxdata, nfsi); + fscache_unuse_cookie(cookie, &auxdata, NULL); + } fscache_relinquish_cookie(cookie, false); nfsi->fscache = NULL; } @@ -325,18 +328,17 @@ void nfs_fscache_open_file(struct inode *inode, struct file *filp) if (!fscache_cookie_valid(cookie)) return; - nfs_fscache_update_auxdata(&auxdata, nfsi); - if (inode_is_open_for_write(inode)) { - dfprintk(FSCACHE, "NFS: nfsi 0x%p disabling cache\n", nfsi); - clear_bit(NFS_INO_FSCACHE, &nfsi->flags); - fscache_disable_cookie(cookie, &auxdata, true); + if (test_and_clear_bit(NFS_INO_FSCACHE, &nfsi->flags)) { + dfprintk(FSCACHE, "NFS: nfsi 0x%p disabling cache\n", nfsi); + nfs_fscache_update_auxdata(&auxdata, nfsi); + fscache_unuse_cookie(cookie, &auxdata, NULL); + } } else { - dfprintk(FSCACHE, "NFS: nfsi 0x%p enabling cache\n", nfsi); - fscache_enable_cookie(cookie, &auxdata, nfsi->vfs_inode.i_size, - nfs_fscache_can_enable, inode); - if (fscache_cookie_enabled(cookie)) - set_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags); + if (!test_and_set_bit(NFS_INO_FSCACHE, &nfsi->flags)) { + dfprintk(FSCACHE, "NFS: nfsi 0x%p enabling cache\n", nfsi); + fscache_use_cookie(cookie, false); + } } } EXPORT_SYMBOL_GPL(nfs_fscache_open_file); From patchwork Mon Oct 18 15:07:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567227 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A22FAC4332F for ; Mon, 18 Oct 2021 15:08:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8C95F60F94 for ; Mon, 18 Oct 2021 15:08:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233243AbhJRPK1 (ORCPT ); Mon, 18 Oct 2021 11:10:27 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:57898 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232200AbhJRPKS (ORCPT ); Mon, 18 Oct 2021 11:10:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569686; 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=t73E6Idu4u1vCUOOGXXOi3HSd+pcMMvFk0UXb/xsBn0=; b=c0rq659yPOr6LITX9EECuzTZg2WX1SrJyBD+14Jbho2NxYscnJ6xRYdRmOgswDGbiAQ7Sy 9tdyhhFsRxguF+2uJ51ZKOlp8I5ecvqSckL/Z/wYKFsDvNmTGnVQem5RuW2IBCbybqN27w QoqxAR/UIVkDK5aHZUYeuSywgFznGRM= 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-9-yPMScjPbPVuSvx7bNndAeQ-1; Mon, 18 Oct 2021 11:08:02 -0400 X-MC-Unique: yPMScjPbPVuSvx7bNndAeQ-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 0FCEB1926DA2; Mon, 18 Oct 2021 15:08:00 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8768478B20; Mon, 18 Oct 2021 15:07:56 +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 60/67] NFS: Convert fscache invalidation and update aux_data and i_size From: David Howells To: linux-cachefs@redhat.com Cc: Dave Wysochanski , Trond Myklebust , Anna Schumaker , linux-nfs@vger.kernel.org, dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:07:55 +0100 Message-ID: <163456967575.2614702.17908978920093430374.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org From: Dave Wysochanski Convert nfs_fscache_invalidate to the new FS-Cache API. Also, now when invalidating an fscache cookie, be sure to pass the latest i_size as well as aux_data to fscache. A few APIs no longer exist so remove them. We can call directly to wait_on_page_fscache() because it checks whether a page is an fscache page before waiting on it. Since the current NFS fscache implementation is only enabled when a file is open for read, handle writes with invalidation. If a write extends the size of the file and fscache is enabled, we must invalidate the object with the new size. We must also invalidate fscache when doing a direct write to avoid issues seen specifically with NFSv4.x when direct writes are followed by non-direct (buffered) reads. Note that we cannot call fscache_invalidate() while holding inode->i_lock. Signed-off-by: Dave Wysochanski Signed-off-by: David Howells cc: Trond Myklebust cc: Anna Schumaker cc: linux-nfs@vger.kernel.org --- fs/nfs/direct.c | 2 ++ fs/nfs/file.c | 7 ++++++- fs/nfs/fscache.c | 20 -------------------- fs/nfs/fscache.h | 32 ++++++++++++++++++++++---------- fs/nfs/inode.c | 4 ++-- fs/nfs/write.c | 1 + 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 2e894fec036b..8b4839ef4b0c 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -59,6 +59,7 @@ #include "internal.h" #include "iostat.h" #include "pnfs.h" +#include "fscache.h" #define NFSDBG_FACILITY NFSDBG_VFS @@ -959,6 +960,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter) } else { result = requested; } + nfs_fscache_invalidate(inode, FSCACHE_INVAL_DIO_WRITE); out_release: nfs_direct_req_release(dreq); out: diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 209dac208477..0a7f1e9f1203 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -436,6 +436,7 @@ static int nfs_release_page(struct page *page, gfp_t gfp) if (!(gfp & __GFP_DIRECT_RECLAIM) || !(gfp & __GFP_FS)) return false; wait_on_page_fscache(page); + fscache_note_page_release(nfs_i_fscache(page->mapping->host)); } return true; } @@ -559,7 +560,11 @@ static vm_fault_t nfs_vm_page_mkwrite(struct vm_fault *vmf) sb_start_pagefault(inode->i_sb); /* make sure the cache has finished storing the page */ - wait_on_page_fscache(page); + if (PageFsCache(page) && + wait_on_page_fscache_killable(vmf->page) < 0) { + ret = VM_FAULT_RETRY; + goto out; + } wait_on_bit_action(&NFS_I(inode)->flags, NFS_INO_INVALIDATING, nfs_wait_bit_killable, TASK_KILLABLE); diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index 5e584f2e84a9..8250a029759e 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c @@ -234,19 +234,6 @@ void nfs_fscache_release_super_cookie(struct super_block *sb) } } -static void nfs_fscache_update_auxdata(struct nfs_fscache_inode_auxdata *auxdata, - struct nfs_inode *nfsi) -{ - memset(auxdata, 0, sizeof(*auxdata)); - auxdata->mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec; - auxdata->mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec; - auxdata->ctime_sec = nfsi->vfs_inode.i_ctime.tv_sec; - auxdata->ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec; - - if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4) - auxdata->change_attr = inode_peek_iversion_raw(&nfsi->vfs_inode); -} - /* * Initialise the per-inode cache cookie pointer for an NFS inode. */ @@ -293,13 +280,6 @@ void nfs_fscache_clear_inode(struct inode *inode) nfsi->fscache = NULL; } -static bool nfs_fscache_can_enable(void *data) -{ - struct inode *inode = data; - - return !inode_is_open_for_write(inode); -} - /* * Enable or disable caching for a file that is being opened as appropriate. * The cookie is allocated when the inode is initialised, but is not enabled at diff --git a/fs/nfs/fscache.h b/fs/nfs/fscache.h index 1e30fcb45665..cc94b257059b 100644 --- a/fs/nfs/fscache.h +++ b/fs/nfs/fscache.h @@ -13,6 +13,7 @@ #include #define FSCACHE_USE_FALLBACK_IO_API #include +#include #ifdef CONFIG_NFS_FSCACHE @@ -118,20 +119,32 @@ static inline void nfs_readpage_to_fscache(struct inode *inode, __nfs_readpage_to_fscache(inode, page); } -/* - * Invalidate the contents of fscache for this inode. This will not sleep. - */ -static inline void nfs_fscache_invalidate(struct inode *inode) +static inline void nfs_fscache_update_auxdata(struct nfs_fscache_inode_auxdata *auxdata, + struct nfs_inode *nfsi) { - fscache_invalidate(NFS_I(inode)->fscache); + memset(auxdata, 0, sizeof(*auxdata)); + auxdata->mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec; + auxdata->mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec; + auxdata->ctime_sec = nfsi->vfs_inode.i_ctime.tv_sec; + auxdata->ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec; + + if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4) + auxdata->change_attr = inode_peek_iversion_raw(&nfsi->vfs_inode); } /* - * Wait for an object to finish being invalidated. + * Invalidate the contents of fscache for this inode. This will not sleep. */ -static inline void nfs_fscache_wait_on_invalidate(struct inode *inode) +static inline void nfs_fscache_invalidate(struct inode *inode, int flags) { - fscache_wait_on_invalidate(NFS_I(inode)->fscache); + struct nfs_fscache_inode_auxdata auxdata; + struct nfs_inode *nfsi = NFS_I(inode); + + if (nfsi->fscache) { + nfs_fscache_update_auxdata(&auxdata, nfsi); + fscache_invalidate(nfsi->fscache, &auxdata, + i_size_read(&nfsi->vfs_inode), flags); + } } /* @@ -167,8 +180,7 @@ static inline void nfs_readpage_to_fscache(struct inode *inode, struct page *page) {} -static inline void nfs_fscache_invalidate(struct inode *inode) {} -static inline void nfs_fscache_wait_on_invalidate(struct inode *inode) {} +static inline void nfs_fscache_invalidate(struct inode *inode, int flags) {} static inline const char *nfs_server_fscache_state(struct nfs_server *server) { diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 853213b3a209..370c49b98646 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -209,7 +209,7 @@ void nfs_set_cache_invalid(struct inode *inode, unsigned long flags) if (!nfs_has_xattr_cache(nfsi)) flags &= ~NFS_INO_INVALID_XATTR; if (flags & NFS_INO_INVALID_DATA) - nfs_fscache_invalidate(inode); + nfs_fscache_invalidate(inode, 0); if (inode->i_mapping->nrpages == 0) flags &= ~(NFS_INO_INVALID_DATA|NFS_INO_DATA_INVAL_DEFER); flags &= ~(NFS_INO_REVAL_PAGECACHE | NFS_INO_REVAL_FORCED); @@ -1281,6 +1281,7 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map { int ret; + nfs_fscache_invalidate(inode, 0); if (mapping->nrpages != 0) { if (S_ISREG(inode->i_mode)) { ret = nfs_sync_mapping(mapping); @@ -1292,7 +1293,6 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map return ret; } nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE); - nfs_fscache_wait_on_invalidate(inode); dfprintk(PAGECACHE, "NFS: (%s/%Lu) data cache invalidated\n", inode->i_sb->s_id, diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 466266a96b2a..cbbf400db126 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -293,6 +293,7 @@ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int c nfs_inc_stats(inode, NFSIOS_EXTENDWRITE); out: spin_unlock(&inode->i_lock); + nfs_fscache_invalidate(inode, 0); } /* A writeback failed: mark the page as bad, and invalidate the page cache */ From patchwork Mon Oct 18 15:08:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567229 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 065ECC4332F for ; Mon, 18 Oct 2021 15:08:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E03A760E0C for ; Mon, 18 Oct 2021 15:08:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232260AbhJRPKj (ORCPT ); Mon, 18 Oct 2021 11:10:39 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:20698 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232879AbhJRPK0 (ORCPT ); Mon, 18 Oct 2021 11:10:26 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569695; 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=0pGBnm1g4km6YgrB3SsrB6ENpmXEGy+4slofjdve3RY=; b=FaeM+tHZiy9xKpK7PWsJ7rbt5AAt+AYEisSpa1YYue7pH9+50x2oGrVbbrgXLpsxDumJQV pHbjY5ZWXbZVR+DtXTK6Kvf6CJIBGVLMEr5pqPgNRhEzvWNGgsuG5Qq30ARoZdHG2M5k1f xdVHd6bZkFAnnXmQCY1jW+fI1xM6d2A= 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-253-UTCjc-rnPiObuhR-HTGF3g-1; Mon, 18 Oct 2021 11:08:12 -0400 X-MC-Unique: UTCjc-rnPiObuhR-HTGF3g-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BFE0610168D7; Mon, 18 Oct 2021 15:08:09 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1E5B460C17; Mon, 18 Oct 2021 15:08:05 +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 61/67] nfs: Convert to new fscache volume/cookie API From: David Howells To: linux-cachefs@redhat.com Cc: Dave Wysochanski , Trond Myklebust , Anna Schumaker , linux-nfs@vger.kernel.org, dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:08:05 +0100 Message-ID: <163456968528.2614702.4840261218695966606.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Change the nfs filesystem to support fscache's indexing rewrite and reenable caching in nfs. The following changes have been made: (1) The fscache_netfs struct is no more, and there's no need to register the filesystem as a whole. (2) The session cookie is now an fscache_volume cookie, allocated with fscache_acquire_volume(). That takes three parameters: a string representing the "volume" in the index, a string naming the cache to use (or NULL) and a u64 that conveys coherency metadata for the volume. For nfs, I've made it render the volume name string as: "nfs,,,
,,,*<,param>[,]" (3) The fscache_cookie_def is no more and needed information is passed directly to fscache_acquire_cookie(). The cache no longer calls back into the filesystem, but rather metadata changes are indicated at other times. fscache_acquire_cookie() is passed the same keying and coherency information as before. Signed-off-by: David Howells cc: Dave Wysochanski cc: Trond Myklebust cc: Anna Schumaker cc: linux-nfs@vger.kernel.org --- fs/nfs/Kconfig | 2 fs/nfs/Makefile | 2 fs/nfs/client.c | 4 - fs/nfs/fscache-index.c | 46 --------- fs/nfs/fscache.c | 220 ++++++++++++++------------------------------- fs/nfs/fscache.h | 56 ----------- fs/nfs/inode.c | 7 - fs/nfs/super.c | 7 + include/linux/nfs_fs_sb.h | 9 -- 9 files changed, 74 insertions(+), 279 deletions(-) delete mode 100644 fs/nfs/fscache-index.c diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig index a8b73c90aa00..14a72224b657 100644 --- a/fs/nfs/Kconfig +++ b/fs/nfs/Kconfig @@ -170,7 +170,7 @@ config ROOT_NFS config NFS_FSCACHE bool "Provide NFS client caching support" - depends on NFS_FS=m && FSCACHE_OLD || NFS_FS=y && FSCACHE_OLD=y + depends on NFS_FS=m && FSCACHE || NFS_FS=y && FSCACHE=y help Say Y here if you want NFS data to be cached locally on disc through the general filesystem cache manager diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile index 22d11fdc6deb..5f6db37f461e 100644 --- a/fs/nfs/Makefile +++ b/fs/nfs/Makefile @@ -12,7 +12,7 @@ nfs-y := client.o dir.o file.o getroot.o inode.o super.o \ export.o sysfs.o fs_context.o nfs-$(CONFIG_ROOT_NFS) += nfsroot.o nfs-$(CONFIG_SYSCTL) += sysctl.o -nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o +nfs-$(CONFIG_NFS_FSCACHE) += fscache.o obj-$(CONFIG_NFS_V2) += nfsv2.o nfsv2-y := nfs2super.o proc.o nfs2xdr.o diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 23e165d5ec9c..8f35e26d8a29 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -183,8 +183,6 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init) clp->cl_net = get_net(cl_init->net); clp->cl_principal = "*"; - nfs_fscache_get_client_cookie(clp); - return clp; error_cleanup: @@ -238,8 +236,6 @@ static void pnfs_init_server(struct nfs_server *server) */ void nfs_free_client(struct nfs_client *clp) { - nfs_fscache_release_client_cookie(clp); - /* -EIO all pending I/O */ if (!IS_ERR(clp->cl_rpcclient)) rpc_shutdown_client(clp->cl_rpcclient); diff --git a/fs/nfs/fscache-index.c b/fs/nfs/fscache-index.c deleted file mode 100644 index b4fdacd955f3..000000000000 --- a/fs/nfs/fscache-index.c +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* NFS FS-Cache index structure definition - * - * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "internal.h" -#include "fscache.h" - -#define NFSDBG_FACILITY NFSDBG_FSCACHE - -/* - * Define the NFS filesystem for FS-Cache. Upon registration FS-Cache sticks - * the cookie for the top-level index object for NFS into here. The top-level - * index can than have other cache objects inserted into it. - */ -struct fscache_netfs nfs_fscache_netfs = { - .name = "nfs", - .version = 0, -}; - -/* - * Register NFS for caching - */ -int nfs_fscache_register(void) -{ - return fscache_register_netfs(&nfs_fscache_netfs); -} - -/* - * Unregister NFS for caching - */ -void nfs_fscache_unregister(void) -{ - fscache_unregister_netfs(&nfs_fscache_netfs); -} diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index 8250a029759e..c15bdf3606eb 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c @@ -22,24 +22,18 @@ #define NFSDBG_FACILITY NFSDBG_FSCACHE -static struct rb_root nfs_fscache_keys = RB_ROOT; -static DEFINE_SPINLOCK(nfs_fscache_keys_lock); +#define NFS_MAX_KEY_LEN 1000 -/* - * Layout of the key for an NFS server cache object. - */ -struct nfs_server_key { - struct { - uint16_t nfsversion; /* NFS protocol version */ - uint32_t minorversion; /* NFSv4 minor version */ - uint16_t family; /* address family */ - __be16 port; /* IP port */ - } hdr; - union { - struct in_addr ipv4_addr; /* IPv4 address */ - struct in6_addr ipv6_addr; /* IPv6 address */ - }; -} __packed; +static bool nfs_append_int(char *key, int *_len, unsigned long long x) +{ + if (*_len > NFS_MAX_KEY_LEN) + return false; + if (x == 0) + key[(*_len)++] = ','; + else + *_len += sprintf(key + *_len, ",%llx", x); + return true; +} /* * Get the per-client index cookie for an NFS client if the appropriate mount @@ -47,68 +41,43 @@ struct nfs_server_key { * - We always try and get an index cookie for the client, but get filehandle * cookies on a per-superblock basis, depending on the mount flags */ -void nfs_fscache_get_client_cookie(struct nfs_client *clp) +static bool nfs_fscache_get_client_key(struct nfs_client *clp, + char *key, int *_len) { const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &clp->cl_addr; const struct sockaddr_in *sin = (struct sockaddr_in *) &clp->cl_addr; - struct nfs_server_key key; - uint16_t len = sizeof(key.hdr); - memset(&key, 0, sizeof(key)); - key.hdr.nfsversion = clp->rpc_ops->version; - key.hdr.minorversion = clp->cl_minorversion; - key.hdr.family = clp->cl_addr.ss_family; + *_len += snprintf(key + *_len, NFS_MAX_KEY_LEN - *_len, + ",%u.%u,%x", + clp->rpc_ops->version, + clp->cl_minorversion, + clp->cl_addr.ss_family); switch (clp->cl_addr.ss_family) { case AF_INET: - key.hdr.port = sin->sin_port; - key.ipv4_addr = sin->sin_addr; - len += sizeof(key.ipv4_addr); - break; + if (!nfs_append_int(key, _len, sin->sin_port) || + !nfs_append_int(key, _len, sin->sin_addr.s_addr)) + return false; + return true; case AF_INET6: - key.hdr.port = sin6->sin6_port; - key.ipv6_addr = sin6->sin6_addr; - len += sizeof(key.ipv6_addr); - break; + if (!nfs_append_int(key, _len, sin6->sin6_port) || + !nfs_append_int(key, _len, sin6->sin6_addr.s6_addr32[0]) || + !nfs_append_int(key, _len, sin6->sin6_addr.s6_addr32[1]) || + !nfs_append_int(key, _len, sin6->sin6_addr.s6_addr32[2]) || + !nfs_append_int(key, _len, sin6->sin6_addr.s6_addr32[3])) + return false; + return true; default: printk(KERN_WARNING "NFS: Unknown network family '%d'\n", clp->cl_addr.ss_family); - clp->fscache = NULL; - return; + return false; } - - /* create a cache index for looking up filehandles */ - clp->fscache = fscache_acquire_cookie(nfs_fscache_netfs.primary_index, - FSCACHE_COOKIE_TYPE_INDEX, - "NFS.server", - 0, /* advice */ - NULL, /* preferred_cache */ - &key, /* index_key */ - len, - NULL, /* aux_data */ - 0, - 0); - dfprintk(FSCACHE, "NFS: get client cookie (0x%p/0x%p)\n", - clp, clp->fscache); } /* - * Dispose of a per-client cookie - */ -void nfs_fscache_release_client_cookie(struct nfs_client *clp) -{ - dfprintk(FSCACHE, "NFS: releasing client cookie (0x%p/0x%p)\n", - clp, clp->fscache); - - fscache_relinquish_cookie(clp->fscache, false); - clp->fscache = NULL; -} - -/* - * Get the cache cookie for an NFS superblock. We have to handle - * uniquification here because the cache doesn't do it for us. + * Get the cache cookie for an NFS superblock. * * The default uniquifier is just an empty string, but it may be overridden * either by the 'fsc=xxx' option to mount, or by inheriting it from the parent @@ -116,100 +85,53 @@ void nfs_fscache_release_client_cookie(struct nfs_client *clp) */ void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, int ulen) { - struct nfs_fscache_key *key, *xkey; struct nfs_server *nfss = NFS_SB(sb); - struct rb_node **p, *parent; - int diff; + unsigned int len = 3; + char *key; - nfss->fscache_key = NULL; - nfss->fscache = NULL; - if (!uniq) { - uniq = ""; - ulen = 1; + if (uniq) { + nfss->fscache_uniq = kmemdup_nul(uniq, ulen, GFP_KERNEL); + if (!nfss->fscache_uniq) + return; } - key = kzalloc(sizeof(*key) + ulen, GFP_KERNEL); + key = kmalloc(NFS_MAX_KEY_LEN + 24, GFP_KERNEL); if (!key) return; - key->nfs_client = nfss->nfs_client; - key->key.super.s_flags = sb->s_flags & NFS_SB_MASK; - key->key.nfs_server.flags = nfss->flags; - key->key.nfs_server.rsize = nfss->rsize; - key->key.nfs_server.wsize = nfss->wsize; - key->key.nfs_server.acregmin = nfss->acregmin; - key->key.nfs_server.acregmax = nfss->acregmax; - key->key.nfs_server.acdirmin = nfss->acdirmin; - key->key.nfs_server.acdirmax = nfss->acdirmax; - key->key.nfs_server.fsid = nfss->fsid; - key->key.rpc_auth.au_flavor = nfss->client->cl_auth->au_flavor; - - key->key.uniq_len = ulen; - memcpy(key->key.uniquifier, uniq, ulen); - - spin_lock(&nfs_fscache_keys_lock); - p = &nfs_fscache_keys.rb_node; - parent = NULL; - while (*p) { - parent = *p; - xkey = rb_entry(parent, struct nfs_fscache_key, node); - - if (key->nfs_client < xkey->nfs_client) - goto go_left; - if (key->nfs_client > xkey->nfs_client) - goto go_right; - - diff = memcmp(&key->key, &xkey->key, sizeof(key->key)); - if (diff < 0) - goto go_left; - if (diff > 0) - goto go_right; - - if (key->key.uniq_len == 0) - goto non_unique; - diff = memcmp(key->key.uniquifier, - xkey->key.uniquifier, - key->key.uniq_len); - if (diff < 0) - goto go_left; - if (diff > 0) - goto go_right; - goto non_unique; - - go_left: - p = &(*p)->rb_left; - continue; - go_right: - p = &(*p)->rb_right; + memcpy(key, "nfs", 3); + if (!nfs_fscache_get_client_key(nfss->nfs_client, key, &len) || + !nfs_append_int(key, &len, nfss->fsid.major) || + !nfs_append_int(key, &len, nfss->fsid.minor) || + !nfs_append_int(key, &len, sb->s_flags & NFS_SB_MASK) || + !nfs_append_int(key, &len, nfss->flags) || + !nfs_append_int(key, &len, nfss->rsize) || + !nfs_append_int(key, &len, nfss->wsize) || + !nfs_append_int(key, &len, nfss->acregmin) || + !nfs_append_int(key, &len, nfss->acregmax) || + !nfs_append_int(key, &len, nfss->acdirmin) || + !nfs_append_int(key, &len, nfss->acdirmax) || + !nfs_append_int(key, &len, nfss->client->cl_auth->au_flavor)) + goto out; + + if (ulen > 0) { + if (ulen > NFS_MAX_KEY_LEN - len) + goto out; + key[len++] = ','; + memcpy(key + len, uniq, ulen); + len += ulen; } - - rb_link_node(&key->node, parent, p); - rb_insert_color(&key->node, &nfs_fscache_keys); - spin_unlock(&nfs_fscache_keys_lock); - nfss->fscache_key = key; + key[len] = 0; /* create a cache index for looking up filehandles */ - nfss->fscache = fscache_acquire_cookie(nfss->nfs_client->fscache, - FSCACHE_COOKIE_TYPE_INDEX, - "NFS.super", - 0, /* advice */ + nfss->fscache = fscache_acquire_volume(key, NULL, /* preferred_cache */ - &key->key, /* index_key */ - sizeof(key->key) + ulen, - NULL, /* aux_data */ - 0, - 0); + 0 /* coherency_data */); dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n", nfss, nfss->fscache); - return; -non_unique: - spin_unlock(&nfs_fscache_keys_lock); +out: kfree(key); - nfss->fscache_key = NULL; - nfss->fscache = NULL; - printk(KERN_WARNING "NFS:" - " Cache request denied due to non-unique superblock keys\n"); } /* @@ -222,16 +144,9 @@ void nfs_fscache_release_super_cookie(struct super_block *sb) dfprintk(FSCACHE, "NFS: releasing superblock cookie (0x%p/0x%p)\n", nfss, nfss->fscache); - fscache_relinquish_cookie(nfss->fscache, false); + fscache_relinquish_volume(nfss->fscache, 0, false); nfss->fscache = NULL; - - if (nfss->fscache_key) { - spin_lock(&nfs_fscache_keys_lock); - rb_erase(&nfss->fscache_key->node, &nfs_fscache_keys); - spin_unlock(&nfs_fscache_keys_lock); - kfree(nfss->fscache_key); - nfss->fscache_key = NULL; - } + kfree(nfss->fscache_uniq); } /* @@ -250,10 +165,7 @@ void nfs_fscache_init_inode(struct inode *inode) nfs_fscache_update_auxdata(&auxdata, nfsi); nfsi->fscache = fscache_acquire_cookie(NFS_SB(inode->i_sb)->fscache, - FSCACHE_COOKIE_TYPE_DATAFILE, - "NFS.fh", - 0, /* advice */ - NULL, /* preferred_cache */ + FSCACHE_ADV_FALLBACK_IO, nfsi->fh.data, /* index_key */ nfsi->fh.size, &auxdata, /* aux_data */ diff --git a/fs/nfs/fscache.h b/fs/nfs/fscache.h index cc94b257059b..0cf2fbe30051 100644 --- a/fs/nfs/fscache.h +++ b/fs/nfs/fscache.h @@ -17,43 +17,6 @@ #ifdef CONFIG_NFS_FSCACHE -/* - * set of NFS FS-Cache objects that form a superblock key - */ -struct nfs_fscache_key { - struct rb_node node; - struct nfs_client *nfs_client; /* the server */ - - /* the elements of the unique key - as used by nfs_compare_super() and - * nfs_compare_mount_options() to distinguish superblocks */ - struct { - struct { - unsigned long s_flags; /* various flags - * (& NFS_MS_MASK) */ - } super; - - struct { - struct nfs_fsid fsid; - int flags; - unsigned int rsize; /* read size */ - unsigned int wsize; /* write size */ - unsigned int acregmin; /* attr cache timeouts */ - unsigned int acregmax; - unsigned int acdirmin; - unsigned int acdirmax; - } nfs_server; - - struct { - rpc_authflavor_t au_flavor; - } rpc_auth; - - /* uniquifier - can be used if nfs_server.flags includes - * NFS_MOUNT_UNSHARED */ - u8 uniq_len; - char uniquifier[0]; - } key; -}; - /* * Definition of the auxiliary data attached to NFS inode storage objects * within the cache. @@ -71,20 +34,9 @@ struct nfs_fscache_inode_auxdata { u64 change_attr; }; -/* - * fscache-index.c - */ -extern struct fscache_netfs nfs_fscache_netfs; - -extern int nfs_fscache_register(void); -extern void nfs_fscache_unregister(void); - /* * fscache.c */ -extern void nfs_fscache_get_client_cookie(struct nfs_client *); -extern void nfs_fscache_release_client_cookie(struct nfs_client *); - extern void nfs_fscache_get_super_cookie(struct super_block *, const char *, int); extern void nfs_fscache_release_super_cookie(struct super_block *); @@ -120,7 +72,7 @@ static inline void nfs_readpage_to_fscache(struct inode *inode, } static inline void nfs_fscache_update_auxdata(struct nfs_fscache_inode_auxdata *auxdata, - struct nfs_inode *nfsi) + struct nfs_inode *nfsi) { memset(auxdata, 0, sizeof(*auxdata)); auxdata->mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec; @@ -158,12 +110,6 @@ static inline const char *nfs_server_fscache_state(struct nfs_server *server) } #else /* CONFIG_NFS_FSCACHE */ -static inline int nfs_fscache_register(void) { return 0; } -static inline void nfs_fscache_unregister(void) {} - -static inline void nfs_fscache_get_client_cookie(struct nfs_client *clp) {} -static inline void nfs_fscache_release_client_cookie(struct nfs_client *clp) {} - static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {} static inline void nfs_fscache_init_inode(struct inode *inode) {} diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 370c49b98646..1cfc8f5c9fe2 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -2361,10 +2361,6 @@ static int __init init_nfs_fs(void) if (err < 0) goto out9; - err = nfs_fscache_register(); - if (err < 0) - goto out8; - err = nfsiod_start(); if (err) goto out7; @@ -2416,8 +2412,6 @@ static int __init init_nfs_fs(void) out6: nfsiod_stop(); out7: - nfs_fscache_unregister(); -out8: unregister_pernet_subsys(&nfs_net_ops); out9: nfs_sysfs_exit(); @@ -2432,7 +2426,6 @@ static void __exit exit_nfs_fs(void) nfs_destroy_readpagecache(); nfs_destroy_inodecache(); nfs_destroy_nfspagecache(); - nfs_fscache_unregister(); unregister_pernet_subsys(&nfs_net_ops); rpc_proc_unregister(&init_net, "nfs"); unregister_nfs_fs(); diff --git a/fs/nfs/super.c b/fs/nfs/super.c index e65c83494c05..e73d4adba50f 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1206,7 +1206,6 @@ static void nfs_get_cache_cookie(struct super_block *sb, char *uniq = NULL; int ulen = 0; - nfss->fscache_key = NULL; nfss->fscache = NULL; if (!ctx) @@ -1216,9 +1215,9 @@ static void nfs_get_cache_cookie(struct super_block *sb, struct nfs_server *mnt_s = NFS_SB(ctx->clone_data.sb); if (!(mnt_s->options & NFS_OPTION_FSCACHE)) return; - if (mnt_s->fscache_key) { - uniq = mnt_s->fscache_key->key.uniquifier; - ulen = mnt_s->fscache_key->key.uniq_len; + if (mnt_s->fscache_uniq) { + uniq = mnt_s->fscache_uniq; + ulen = strlen(uniq); } } else { if (!(ctx->options & NFS_OPTION_FSCACHE)) diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 2a9acbfe00f0..77b2dba27bbb 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -120,11 +120,6 @@ struct nfs_client { * This is used to generate the mv0 callback address. */ char cl_ipaddr[48]; - -#ifdef CONFIG_NFS_FSCACHE - struct fscache_cookie *fscache; /* client index cache cookie */ -#endif - struct net *cl_net; struct list_head pending_cb_stateids; }; @@ -194,8 +189,8 @@ struct nfs_server { struct nfs_auth_info auth_info; /* parsed auth flavors */ #ifdef CONFIG_NFS_FSCACHE - struct nfs_fscache_key *fscache_key; /* unique key for superblock */ - struct fscache_cookie *fscache; /* superblock cookie */ + struct fscache_volume *fscache; /* superblock cookie */ + char *fscache_uniq; /* Uniquifier (or NULL) */ #endif u32 pnfs_blksize; /* layout_blksize attr */ From patchwork Mon Oct 18 15:08:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567231 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 54DF2C433F5 for ; Mon, 18 Oct 2021 15:08:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3D4BF60E0C for ; Mon, 18 Oct 2021 15:08:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233392AbhJRPKr (ORCPT ); Mon, 18 Oct 2021 11:10:47 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:26684 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233092AbhJRPKh (ORCPT ); Mon, 18 Oct 2021 11:10:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569705; 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=sJ6TD7yzFcL8r7fG3ynQWEYtkdJGrOusqo5rQfuHuJ8=; b=fGljUyPH2oniG5YQC9o4UusZ6bLB1mHUwc77u2TaL9kfaZxUUhJ2EGOLy96G+bBvhyM78d QVeqBEh8cziMA5cZmmJ5krq5NBSi7YfN3LmZuT4wVF71LHulSUYdsF+7RYbUhCJRhxz09b tUifL/wJ6N5MnGM1a2Ynf1kAzQUr0Nw= 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-1-2F0-sXV6NpiPhRi1cSw4tw-1; Mon, 18 Oct 2021 11:08:21 -0400 X-MC-Unique: 2F0-sXV6NpiPhRi1cSw4tw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7EF09107B0F6; Mon, 18 Oct 2021 15:08:19 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id D014F5D6D7; Mon, 18 Oct 2021 15:08:15 +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 62/67] 9p: Use fscache indexing rewrite and reenable caching From: David Howells To: linux-cachefs@redhat.com Cc: Eric Van Hensbergen , Latchesar Ionkov , Dominique Martinet , v9fs-developer@lists.sourceforge.net, dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:08:15 +0100 Message-ID: <163456969500.2614702.10435422879127080632.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Change the 9p filesystem to take account of the changes to fscache's indexing rewrite and reenable caching in 9p. The following changes have been made: (1) The fscache_netfs struct is no more, and there's no need to register the filesystem as a whole. (2) The session cookie is now an fscache_volume cookie, allocated with fscache_acquire_volume(). That takes three parameters: a string representing the "volume" in the index, a string naming the cache to use (or NULL) and a u64 that conveys coherency metadata for the volume. For 9p, I've made it render the volume name string as: "9p,," where the cachetag is replaced by the aname if it wasn't supplied. This probably needs rethinking a bit as the aname can have slashes in it. It might be better to hash the cachetag and use the hash or I could substitute commas for the slashes or something. (3) The fscache_cookie_def is no more and needed information is passed directly to fscache_acquire_cookie(). The cache no longer calls back into the filesystem, but rather metadata changes are indicated at other times. fscache_acquire_cookie() is passed the same keying and coherency information as before. (4) The functions to set/reset/flush cookies are removed and fscache_use_cookie() and fscache_unuse_cookie() are used instead. fscache_use_cookie() is passed a flag to indicate if the cookie is opened for writing. fscache_unuse_cookie() is passed updates for the metadata if we changed it (ie. if the file was opened for writing). These are called when the file is opened or closed. (5) wait_on_page_bit[_killable]() is replaced with the specific wait functions for the bits waited upon. (6) I've got rid of some of the 9p-specific cache helper functions and called things like fscache_relinquish_cookie() directly as they'll optimise away if v9fs_inode_cookie() returns an unconditional NULL (which will be the case if CONFIG_9P_FSCACHE=n). (7) v9fs_vfs_setattr() is made to call fscache_resize() to change the size of the cache object. Notes: (A) We should call fscache_invalidate() if we detect that the server's copy of a file got changed by a third party, but I don't know where to do that. We don't need to do that when allocating the cookie as we get a check-and-invalidate when we initially bind to the cache object. (B) The copy-to-cache-on-writeback side of things will be handled in separate patch. Signed-off-by: David Howells cc: Eric Van Hensbergen cc: Latchesar Ionkov cc: Dominique Martinet cc: v9fs-developer@lists.sourceforge.net --- fs/9p/Kconfig | 2 - fs/9p/cache.c | 184 ++++++------------------------------------------ fs/9p/cache.h | 23 +----- fs/9p/v9fs.c | 14 +--- fs/9p/v9fs.h | 13 +++ fs/9p/vfs_dir.c | 13 +++ fs/9p/vfs_file.c | 7 +- fs/9p/vfs_inode.c | 22 +++--- fs/9p/vfs_inode_dotl.c | 3 + 9 files changed, 71 insertions(+), 210 deletions(-) diff --git a/fs/9p/Kconfig b/fs/9p/Kconfig index b11c15c30bac..d7bc93447c85 100644 --- a/fs/9p/Kconfig +++ b/fs/9p/Kconfig @@ -14,7 +14,7 @@ config 9P_FS if 9P_FS config 9P_FSCACHE bool "Enable 9P client caching support" - depends on 9P_FS=m && FSCACHE_OLD || 9P_FS=y && FSCACHE_OLD=y + depends on 9P_FS=m && FSCACHE || 9P_FS=y && FSCACHE=y help Choose Y here to enable persistent, read-only local caching support for 9p clients using FS-Cache diff --git a/fs/9p/cache.c b/fs/9p/cache.c index 077f0a40aa01..99662920699d 100644 --- a/fs/9p/cache.c +++ b/fs/9p/cache.c @@ -16,89 +16,26 @@ #include "v9fs.h" #include "cache.h" -#define CACHETAG_LEN 11 - -struct fscache_netfs v9fs_cache_netfs = { - .name = "9p", - .version = 0, -}; - -/* - * v9fs_random_cachetag - Generate a random tag to be associated - * with a new cache session. - * - * The value of jiffies is used for a fairly randomly cache tag. - */ - -static -int v9fs_random_cachetag(struct v9fs_session_info *v9ses) -{ - v9ses->cachetag = kmalloc(CACHETAG_LEN, GFP_KERNEL); - if (!v9ses->cachetag) - return -ENOMEM; - - return scnprintf(v9ses->cachetag, CACHETAG_LEN, "%lu", jiffies); -} - -const struct fscache_cookie_def v9fs_cache_session_index_def = { - .name = "9P.session", - .type = FSCACHE_COOKIE_TYPE_INDEX, -}; - -void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses) +void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses, + const char *dev_name) { - /* If no cache session tag was specified, we generate a random one. */ - if (!v9ses->cachetag) { - if (v9fs_random_cachetag(v9ses) < 0) { - v9ses->fscache = NULL; - kfree(v9ses->cachetag); - v9ses->cachetag = NULL; - return; - } - } + char *name, *p; - v9ses->fscache = fscache_acquire_cookie(v9fs_cache_netfs.primary_index, - &v9fs_cache_session_index_def, - v9ses->cachetag, - strlen(v9ses->cachetag), - NULL, 0, - v9ses, 0, true); - p9_debug(P9_DEBUG_FSC, "session %p get cookie %p\n", - v9ses, v9ses->fscache); -} - -void v9fs_cache_session_put_cookie(struct v9fs_session_info *v9ses) -{ - p9_debug(P9_DEBUG_FSC, "session %p put cookie %p\n", - v9ses, v9ses->fscache); - fscache_relinquish_cookie(v9ses->fscache, NULL, false); - v9ses->fscache = NULL; -} - -static enum -fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data, - const void *buffer, - uint16_t buflen, - loff_t object_size) -{ - const struct v9fs_inode *v9inode = cookie_netfs_data; - - if (buflen != sizeof(v9inode->qid.version)) - return FSCACHE_CHECKAUX_OBSOLETE; + name = kasprintf(GFP_KERNEL, "9p,%s,%s", + dev_name, v9ses->cachetag ?: v9ses->aname); + if (!name) + return; - if (memcmp(buffer, &v9inode->qid.version, - sizeof(v9inode->qid.version))) - return FSCACHE_CHECKAUX_OBSOLETE; + for (p = name; *p; p++) + if (*p == '/') + *p = ';'; - return FSCACHE_CHECKAUX_OKAY; + v9ses->fscache = fscache_acquire_volume(name, NULL, 0); + p9_debug(P9_DEBUG_FSC, "session %p get volume %p (%s)\n", + v9ses, v9ses->fscache, name); + kfree(name); } -const struct fscache_cookie_def v9fs_cache_inode_index_def = { - .name = "9p.inode", - .type = FSCACHE_COOKIE_TYPE_DATAFILE, - .check_aux = v9fs_cache_inode_check_aux, -}; - void v9fs_cache_inode_get_cookie(struct inode *inode) { struct v9fs_inode *v9inode; @@ -108,94 +45,19 @@ void v9fs_cache_inode_get_cookie(struct inode *inode) return; v9inode = V9FS_I(inode); - if (v9inode->fscache) + if (WARN_ON(v9inode->fscache)) return; v9ses = v9fs_inode2v9ses(inode); - v9inode->fscache = fscache_acquire_cookie(v9ses->fscache, - &v9fs_cache_inode_index_def, - &v9inode->qid.path, - sizeof(v9inode->qid.path), - &v9inode->qid.version, - sizeof(v9inode->qid.version), - v9inode, - i_size_read(&v9inode->vfs_inode), - true); + v9inode->fscache = + fscache_acquire_cookie(v9fs_session_cache(v9ses), + 0, + &v9inode->qid.path, + sizeof(v9inode->qid.path), + &v9inode->qid.version, + sizeof(v9inode->qid.version), + i_size_read(&v9inode->vfs_inode)); p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n", inode, v9inode->fscache); } - -void v9fs_cache_inode_put_cookie(struct inode *inode) -{ - struct v9fs_inode *v9inode = V9FS_I(inode); - - if (!v9inode->fscache) - return; - p9_debug(P9_DEBUG_FSC, "inode %p put cookie %p\n", - inode, v9inode->fscache); - - fscache_relinquish_cookie(v9inode->fscache, &v9inode->qid.version, - false); - v9inode->fscache = NULL; -} - -void v9fs_cache_inode_flush_cookie(struct inode *inode) -{ - struct v9fs_inode *v9inode = V9FS_I(inode); - - if (!v9inode->fscache) - return; - p9_debug(P9_DEBUG_FSC, "inode %p flush cookie %p\n", - inode, v9inode->fscache); - - fscache_relinquish_cookie(v9inode->fscache, NULL, true); - v9inode->fscache = NULL; -} - -void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *filp) -{ - struct v9fs_inode *v9inode = V9FS_I(inode); - - if (!v9inode->fscache) - return; - - mutex_lock(&v9inode->fscache_lock); - - if ((filp->f_flags & O_ACCMODE) != O_RDONLY) - v9fs_cache_inode_flush_cookie(inode); - else - v9fs_cache_inode_get_cookie(inode); - - mutex_unlock(&v9inode->fscache_lock); -} - -void v9fs_cache_inode_reset_cookie(struct inode *inode) -{ - struct v9fs_inode *v9inode = V9FS_I(inode); - struct v9fs_session_info *v9ses; - struct fscache_cookie *old; - - if (!v9inode->fscache) - return; - - old = v9inode->fscache; - - mutex_lock(&v9inode->fscache_lock); - fscache_relinquish_cookie(v9inode->fscache, NULL, true); - - v9ses = v9fs_inode2v9ses(inode); - v9inode->fscache = fscache_acquire_cookie(v9ses->fscache, - &v9fs_cache_inode_index_def, - &v9inode->qid.path, - sizeof(v9inode->qid.path), - &v9inode->qid.version, - sizeof(v9inode->qid.version), - v9inode, - i_size_read(&v9inode->vfs_inode), - true); - p9_debug(P9_DEBUG_FSC, "inode %p revalidating cookie old %p new %p\n", - inode, old, v9inode->fscache); - - mutex_unlock(&v9inode->fscache_lock); -} diff --git a/fs/9p/cache.h b/fs/9p/cache.h index cfafa89b972c..e485049eec85 100644 --- a/fs/9p/cache.h +++ b/fs/9p/cache.h @@ -13,21 +13,10 @@ #ifdef CONFIG_9P_FSCACHE -extern struct fscache_netfs v9fs_cache_netfs; -extern const struct fscache_cookie_def v9fs_cache_session_index_def; -extern const struct fscache_cookie_def v9fs_cache_inode_index_def; - -extern void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses); -extern void v9fs_cache_session_put_cookie(struct v9fs_session_info *v9ses); +extern void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses, + const char *dev_name); extern void v9fs_cache_inode_get_cookie(struct inode *inode); -extern void v9fs_cache_inode_put_cookie(struct inode *inode); -extern void v9fs_cache_inode_flush_cookie(struct inode *inode); -extern void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *filp); -extern void v9fs_cache_inode_reset_cookie(struct inode *inode); - -extern int __v9fs_cache_register(void); -extern void __v9fs_cache_unregister(void); #else /* CONFIG_9P_FSCACHE */ @@ -35,13 +24,5 @@ static inline void v9fs_cache_inode_get_cookie(struct inode *inode) { } -static inline void v9fs_cache_inode_put_cookie(struct inode *inode) -{ -} - -static inline void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *file) -{ -} - #endif /* CONFIG_9P_FSCACHE */ #endif /* _9P_CACHE_H */ diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 2e0fa7c932db..ab5b2069b78d 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -468,7 +468,8 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, #ifdef CONFIG_9P_FSCACHE /* register the session for caching */ - v9fs_cache_session_get_cookie(v9ses); + if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) + v9fs_cache_session_get_cookie(v9ses, dev_name); #endif spin_lock(&v9fs_sessionlist_lock); list_add(&v9ses->slist, &v9fs_sessionlist); @@ -501,8 +502,7 @@ void v9fs_session_close(struct v9fs_session_info *v9ses) } #ifdef CONFIG_9P_FSCACHE - if (v9ses->fscache) - v9fs_cache_session_put_cookie(v9ses); + fscache_relinquish_volume(v9fs_session_cache(v9ses), 0, false); kfree(v9ses->cachetag); #endif kfree(v9ses->uname); @@ -662,20 +662,12 @@ static int v9fs_cache_register(void) ret = v9fs_init_inode_cache(); if (ret < 0) return ret; -#ifdef CONFIG_9P_FSCACHE - ret = fscache_register_netfs(&v9fs_cache_netfs); - if (ret < 0) - v9fs_destroy_inode_cache(); -#endif return ret; } static void v9fs_cache_unregister(void) { v9fs_destroy_inode_cache(); -#ifdef CONFIG_9P_FSCACHE - fscache_unregister_netfs(&v9fs_cache_netfs); -#endif } /** diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 92124b235a6d..cf4f645785e0 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h @@ -89,7 +89,7 @@ struct v9fs_session_info { unsigned int cache; #ifdef CONFIG_9P_FSCACHE char *cachetag; - struct fscache_cookie *fscache; + struct fscache_volume *fscache; #endif char *uname; /* user name to mount as */ @@ -109,7 +109,6 @@ struct v9fs_session_info { struct v9fs_inode { #ifdef CONFIG_9P_FSCACHE - struct mutex fscache_lock; struct fscache_cookie *fscache; #endif struct p9_qid qid; @@ -133,6 +132,16 @@ static inline struct fscache_cookie *v9fs_inode_cookie(struct v9fs_inode *v9inod #endif } +static inline struct fscache_volume *v9fs_session_cache(struct v9fs_session_info *v9ses) +{ +#ifdef CONFIG_9P_FSCACHE + return v9ses->fscache; +#else + return NULL; +#endif +} + + extern int v9fs_show_options(struct seq_file *m, struct dentry *root); struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index b6a5a0be444d..24f7fd29f102 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -205,8 +206,10 @@ static int v9fs_dir_readdir_dotl(struct file *file, struct dir_context *ctx) int v9fs_dir_release(struct inode *inode, struct file *filp) { + struct v9fs_inode *v9inode = V9FS_I(inode); struct p9_fid *fid; - + loff_t i_size; + fid = filp->private_data; p9_debug(P9_DEBUG_VFS, "inode: %p filp: %p fid: %d\n", inode, filp, fid ? fid->fid : -1); @@ -216,6 +219,14 @@ int v9fs_dir_release(struct inode *inode, struct file *filp) spin_unlock(&inode->i_lock); p9_client_clunk(fid); } + + if ((filp->f_mode & FMODE_WRITE)) { + i_size = i_size_read(inode); + fscache_unuse_cookie(v9fs_inode_cookie(v9inode), + &v9inode->qid.version, &i_size); + } else { + fscache_unuse_cookie(v9fs_inode_cookie(v9inode), NULL, NULL); + } return 0; } diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 80052497f00f..461a51509300 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -95,7 +95,8 @@ int v9fs_file_open(struct inode *inode, struct file *file) } mutex_unlock(&v9inode->v_mutex); if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) - v9fs_cache_inode_set_cookie(inode, file); + fscache_use_cookie(v9fs_inode_cookie(v9inode), + file->f_mode & FMODE_WRITE); v9fs_open_fid_add(inode, fid); return 0; out_error: @@ -544,12 +545,12 @@ v9fs_vm_page_mkwrite(struct vm_fault *vmf) */ #ifdef CONFIG_9P_FSCACHE if (PageFsCache(page) && - wait_on_page_bit_killable(page, PG_fscache) < 0) + wait_on_page_fscache_killable(page) < 0) return VM_FAULT_RETRY; #endif if (PageWriteback(page) && - wait_on_page_bit_killable(page, PG_writeback) < 0) + wait_on_page_writeback_killable(page) < 0) return VM_FAULT_RETRY; /* Update file times before taking page lock */ diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 08f48b70a741..83db37bd4252 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -228,7 +228,6 @@ struct inode *v9fs_alloc_inode(struct super_block *sb) return NULL; #ifdef CONFIG_9P_FSCACHE v9inode->fscache = NULL; - mutex_init(&v9inode->fscache_lock); #endif v9inode->writeback_fid = NULL; v9inode->cache_validity = 0; @@ -381,7 +380,7 @@ void v9fs_evict_inode(struct inode *inode) clear_inode(inode); filemap_fdatawrite(&inode->i_data); - v9fs_cache_inode_put_cookie(inode); + fscache_relinquish_cookie(v9fs_inode_cookie(v9inode), false); /* clunk the fid stashed in writeback_fid */ if (v9inode->writeback_fid) { p9_client_clunk(v9inode->writeback_fid); @@ -862,7 +861,8 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, file->private_data = fid; if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) - v9fs_cache_inode_set_cookie(d_inode(dentry), file); + fscache_use_cookie(v9fs_inode_cookie(v9inode), + file->f_mode & FMODE_WRITE); v9fs_open_fid_add(inode, fid); file->f_mode |= FMODE_CREATED; @@ -1065,6 +1065,8 @@ static int v9fs_vfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, struct iattr *iattr) { int retval, use_dentry = 0; + struct inode *inode = d_inode(dentry); + struct v9fs_inode *v9inode = V9FS_I(inode); struct v9fs_session_info *v9ses; struct p9_fid *fid = NULL; struct p9_wstat wstat; @@ -1110,7 +1112,7 @@ static int v9fs_vfs_setattr(struct user_namespace *mnt_userns, /* Write all dirty data */ if (d_is_reg(dentry)) - filemap_write_and_wait(d_inode(dentry)->i_mapping); + filemap_write_and_wait(inode->i_mapping); retval = p9_client_wstat(fid, &wstat); @@ -1121,13 +1123,15 @@ static int v9fs_vfs_setattr(struct user_namespace *mnt_userns, return retval; if ((iattr->ia_valid & ATTR_SIZE) && - iattr->ia_size != i_size_read(d_inode(dentry))) - truncate_setsize(d_inode(dentry), iattr->ia_size); + iattr->ia_size != i_size_read(inode)) { + truncate_setsize(inode, iattr->ia_size); + fscache_resize_cookie(v9fs_inode_cookie(v9inode), iattr->ia_size); + } - v9fs_invalidate_inode_attr(d_inode(dentry)); + v9fs_invalidate_inode_attr(inode); - setattr_copy(&init_user_ns, d_inode(dentry), iattr); - mark_inode_dirty(d_inode(dentry)); + setattr_copy(&init_user_ns, inode, iattr); + mark_inode_dirty(inode); return 0; } diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 01b9e1281a29..a5058c9a2ab3 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -346,7 +346,8 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, goto err_clunk_old_fid; file->private_data = ofid; if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) - v9fs_cache_inode_set_cookie(inode, file); + fscache_use_cookie(v9fs_inode_cookie(v9inode), + file->f_mode & FMODE_WRITE); v9fs_open_fid_add(inode, ofid); file->f_mode |= FMODE_CREATED; out: From patchwork Mon Oct 18 15:08:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567279 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1AA4EC433EF for ; Mon, 18 Oct 2021 15:09:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0347A6103D for ; Mon, 18 Oct 2021 15:09:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232890AbhJRPLM (ORCPT ); Mon, 18 Oct 2021 11:11:12 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:58850 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233375AbhJRPKq (ORCPT ); Mon, 18 Oct 2021 11:10:46 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569714; 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=DtI7Re191AUvPZ/vtkvuZ2gD0a/mQddwHsEF9A3Bt0M=; b=Ac1zkp2rs3z3Yrda+eTH7JJB/HUtD/nd4NV/li98SeXT05SNB6/Z50ujtAI2GZ8JtE2yfs C0EcqfPrqjaXclSegD4KQnBQVM/3bfavU1x+GZwhj3TZtFsms9ksYpBrJgrj9xdeybnFia I/PWuBXeb1uqze0tDmu8Z5eQp0wnWDA= 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-149-vP4jBK5XNHiQwY3ewo9Qbg-1; Mon, 18 Oct 2021 11:08:31 -0400 X-MC-Unique: vP4jBK5XNHiQwY3ewo9Qbg-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 05D99107B27D; Mon, 18 Oct 2021 15:08:29 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8060E60D30; Mon, 18 Oct 2021 15:08:25 +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 63/67] 9p: Copy local writes to the cache when writing to the server From: David Howells To: linux-cachefs@redhat.com Cc: Eric Van Hensbergen , Latchesar Ionkov , Dominique Martinet , v9fs-developer@lists.sourceforge.net, dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:08:24 +0100 Message-ID: <163456970473.2614702.16723673129113194320.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org When writing to the server from v9fs_vfs_writepage(), copy the data to the cache object too. To make this possible, the cookie must have its active users count incremented when the page is dirtied and kept incremented until we manage to clean up all the pages. This allows the writeback to take place after the last file struct is released. This is done by taking a use on the cookie in v9fs_set_page_dirty() if we haven't already done so (controlled by the I_PINNING_FSCACHE_WB flag) and dropping the pin in v9fs_write_inode() if __writeback_single_inode() clears all the outstanding dirty pages (conveyed by the unpinned_fscache_wb flag in the writeback_control struct). Inode eviction must also clear the flag after truncating away all the outstanding pages. In the future this will be handled more gracefully by netfslib. Signed-off-by: David Howells cc: Eric Van Hensbergen cc: Latchesar Ionkov cc: Dominique Martinet cc: v9fs-developer@lists.sourceforge.net --- fs/9p/vfs_addr.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++----- fs/9p/vfs_inode.c | 2 ++ fs/9p/vfs_super.c | 3 +++ 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index de857fa4629b..2d1577538cde 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -132,15 +132,17 @@ static void v9fs_vfs_readahead(struct readahead_control *ractl) static int v9fs_release_page(struct page *page, gfp_t gfp) { + struct inode *inode = page->mapping->host; + struct v9fs_inode *v9inode = V9FS_I(inode); + if (PagePrivate(page)) return 0; -#ifdef CONFIG_9P_FSCACHE if (PageFsCache(page)) { if (!(gfp & __GFP_DIRECT_RECLAIM) || !(gfp & __GFP_FS)) return 0; wait_on_page_fscache(page); } -#endif + fscache_note_page_release(v9fs_inode_cookie(v9inode)); return 1; } @@ -157,10 +159,23 @@ static void v9fs_invalidate_page(struct page *page, unsigned int offset, wait_on_page_fscache(page); } +static void v9fs_write_to_cache_done(void *priv, ssize_t transferred_or_error, + bool was_async) +{ + struct v9fs_inode *v9inode = priv; + + if (IS_ERR_VALUE(transferred_or_error) && + transferred_or_error != -ENOBUFS) + fscache_invalidate(v9fs_inode_cookie(v9inode), + &v9inode->qid.version, + i_size_read(&v9inode->vfs_inode), 0); +} + static int v9fs_vfs_writepage_locked(struct page *page) { struct inode *inode = page->mapping->host; struct v9fs_inode *v9inode = V9FS_I(inode); + struct fscache_cookie *cookie = v9fs_inode_cookie(v9inode); loff_t start = page_offset(page); loff_t size = i_size_read(inode); struct iov_iter from; @@ -176,10 +191,21 @@ static int v9fs_vfs_writepage_locked(struct page *page) /* We should have writeback_fid always set */ BUG_ON(!v9inode->writeback_fid); + wait_on_page_fscache(page); + set_page_writeback(page); p9_client_write(v9inode->writeback_fid, start, &from, &err); + if (err == 0 && + fscache_cookie_enabled(cookie) && + test_bit(FSCACHE_COOKIE_IS_CACHING, &cookie->flags)) { + set_page_fscache(page); + fscache_write_to_cache(v9fs_inode_cookie(v9inode), + page->mapping, start, len, size, + v9fs_write_to_cache_done, v9inode); + } + end_page_writeback(page); return err; } @@ -290,10 +316,12 @@ static int v9fs_write_begin(struct file *filp, struct address_space *mapping, static int v9fs_write_end(struct file *filp, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, - struct page *page, void *fsdata) + struct page *subpage, void *fsdata) { + struct page *page = thp_head(subpage); loff_t last_pos = pos + copied; - struct inode *inode = page->mapping->host; + struct inode *inode = mapping->host; + struct v9fs_inode *v9inode = V9FS_I(inode); p9_debug(P9_DEBUG_VFS, "filp %p, mapping %p\n", filp, mapping); @@ -313,6 +341,7 @@ static int v9fs_write_end(struct file *filp, struct address_space *mapping, if (last_pos > inode->i_size) { inode_add_bytes(inode, last_pos - inode->i_size); i_size_write(inode, last_pos); + fscache_update_cookie(v9fs_inode_cookie(v9inode), NULL, &last_pos); } set_page_dirty(page); out: @@ -322,11 +351,25 @@ static int v9fs_write_end(struct file *filp, struct address_space *mapping, return copied; } +#ifdef CONFIG_9P_FSCACHE +/* + * Mark a page as having been made dirty and thus needing writeback. We also + * need to pin the cache object to write back to. + */ +static int v9fs_set_page_dirty(struct page *page) +{ + struct v9fs_inode *v9inode = V9FS_I(page->mapping->host); + + return fscache_set_page_dirty(page, v9fs_inode_cookie(v9inode)); +} +#else +#define v9fs_set_page_dirty __set_page_dirty_nobuffers +#endif const struct address_space_operations v9fs_addr_operations = { .readpage = v9fs_vfs_readpage, .readahead = v9fs_vfs_readahead, - .set_page_dirty = __set_page_dirty_nobuffers, + .set_page_dirty = v9fs_set_page_dirty, .writepage = v9fs_vfs_writepage, .write_begin = v9fs_write_begin, .write_end = v9fs_write_end, diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 83db37bd4252..a990c50cc27d 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -377,6 +377,8 @@ void v9fs_evict_inode(struct inode *inode) struct v9fs_inode *v9inode = V9FS_I(inode); truncate_inode_pages_final(&inode->i_data); + fscache_clear_inode_writeback(v9fs_inode_cookie(v9inode), inode, + &v9inode->qid.version); clear_inode(inode); filemap_fdatawrite(&inode->i_data); diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 5fce6e30bc5a..3721098e0992 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -307,6 +308,7 @@ static int v9fs_write_inode(struct inode *inode, __mark_inode_dirty(inode, I_DIRTY_DATASYNC); return ret; } + fscache_unpin_writeback(wbc, v9fs_inode_cookie(v9inode)); return 0; } @@ -330,6 +332,7 @@ static int v9fs_write_inode_dotl(struct inode *inode, __mark_inode_dirty(inode, I_DIRTY_DATASYNC); return ret; } + fscache_unpin_writeback(wbc, v9fs_inode_cookie(v9inode)); return 0; } From patchwork Mon Oct 18 15:08:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567281 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5BA93C433F5 for ; Mon, 18 Oct 2021 15:09:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3BD8E6103D for ; Mon, 18 Oct 2021 15:09:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233448AbhJRPLV (ORCPT ); Mon, 18 Oct 2021 11:11:21 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:53391 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233576AbhJRPK7 (ORCPT ); Mon, 18 Oct 2021 11:10:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569727; 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=zAnT82raamH1xp8nmO4ZV5YV83kJtKcN5B1pbFGq88g=; b=Udbm3usP06AeWFHrjgfLh1Rb0x/9GdB1MFKs0gAgHCOpmgh1HSapr++pl6APPwjhkrJJyk AOl4A8DPuMFUmkO/F1VtZduSdXbmrZUHxNsisO4YlDCwpcsaF1wrMbw57y3kUd1AnKsC/i siBErsR2uJTTLTCRECHXVN1aimzJths= 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-232-dFraY74dMn2k_3qhDxyljQ-1; Mon, 18 Oct 2021 11:08:44 -0400 X-MC-Unique: dFraY74dMn2k_3qhDxyljQ-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id B7AC18F50A; Mon, 18 Oct 2021 15:08:42 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 134CF100E809; Mon, 18 Oct 2021 15:08:34 +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 64/67] netfs: Display the netfs inode number in the netfs_read tracepoint From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:08:34 +0100 Message-ID: <163456971424.2614702.1006294959423305986.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Display the netfs inode number in the netfs_read tracepoint so that this can be used to correlate with the cachefiles_prep_read tracepoint. Signed-off-by: David Howells --- include/trace/events/netfs.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/trace/events/netfs.h b/include/trace/events/netfs.h index 4d470bffd9f1..e6f4ebbb4c69 100644 --- a/include/trace/events/netfs.h +++ b/include/trace/events/netfs.h @@ -135,6 +135,7 @@ TRACE_EVENT(netfs_read, __field(loff_t, start ) __field(size_t, len ) __field(enum netfs_read_trace, what ) + __field(unsigned int, netfs_inode ) ), TP_fast_assign( @@ -143,12 +144,14 @@ TRACE_EVENT(netfs_read, __entry->start = start; __entry->len = len; __entry->what = what; + __entry->netfs_inode = rreq->inode->i_ino; ), - TP_printk("R=%08x %s c=%08x s=%llx %zx", + TP_printk("R=%08x %s c=%08x ni=%x s=%llx %zx", __entry->rreq, __print_symbolic(__entry->what, netfs_read_traces), __entry->cookie, + __entry->netfs_inode, __entry->start, __entry->len) ); From patchwork Mon Oct 18 15:08:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567283 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 58D04C4332F for ; Mon, 18 Oct 2021 15:09:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 412D7610A5 for ; Mon, 18 Oct 2021 15:09:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233332AbhJRPLe (ORCPT ); Mon, 18 Oct 2021 11:11:34 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:48547 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232524AbhJRPLM (ORCPT ); Mon, 18 Oct 2021 11:11:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569738; 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=PltcY/PEBQU8nQ+jHuQECKOprYLw179l3iQuj0DcTgA=; b=PYT2PhF/bVE6RT/mvbzbpb6yADlX1cEAcLjLumqYUPEM1DWxeVVT7AhiUhwuRjJ1ndcmLe nwg0rOqgQd7aV2hIrrvZaI/mFgScGdJoM9yGC23RaZK9uI7WI++XUQwxa9B9ZmL72YUdAZ /ndPt+lc1F4dtERfkL17WWLgXIbNTPI= 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-97-tvN1ktKEO-OuF2x78SQuFw-1; Mon, 18 Oct 2021 11:08:54 -0400 X-MC-Unique: tvN1ktKEO-OuF2x78SQuFw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 85B328F516; Mon, 18 Oct 2021 15:08:52 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id C78525C1D0; Mon, 18 Oct 2021 15:08:48 +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 65/67] cachefiles: Add tracepoints to log errors from ops on the backing fs From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:08:47 +0100 Message-ID: <163456972797.2614702.14297945722771991084.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Add a couple of tracepoints to log errors that cachefiles gets from making calls to manipulate the backing filesystem. These calls are divided into two categories - VFS manipulation (eg. mkdir) and data I/O - with a separate tracepoint for each. Signed-off-by: David Howells --- fs/cachefiles/daemon.c | 2 + fs/cachefiles/interface.c | 11 ++++ fs/cachefiles/internal.h | 1 fs/cachefiles/io.c | 22 ++++++++- fs/cachefiles/namei.c | 59 ++++++++++++++++++++--- fs/cachefiles/xattr.c | 8 +++ include/trace/events/cachefiles.h | 94 +++++++++++++++++++++++++++++++++++++ 7 files changed, 187 insertions(+), 10 deletions(-) diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c index 6d31fba31ce9..2b926af39f43 100644 --- a/fs/cachefiles/daemon.c +++ b/fs/cachefiles/daemon.c @@ -692,6 +692,8 @@ int cachefiles_has_space(struct cachefiles_cache *cache, ret = vfs_statfs(&path, &stats); if (ret < 0) { + trace_cachefiles_vfs_error(NULL, d_inode(cache->store), ret, + cachefiles_trace_statfs_error); if (ret == -EIO) cachefiles_io_error(cache, "statfs failed"); _leave(" = %d", ret); diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 96f30eba585a..115be503b23a 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -153,8 +153,10 @@ static bool cachefiles_shorten_object(struct cachefiles_object *object, cachefiles_trunc_shrink); ret = vfs_truncate(&file->f_path, dio_size); if (ret < 0) { + trace_cachefiles_io_error(object, file_inode(file), ret, + cachefiles_trace_trunc_error); cachefiles_io_error_obj(object, "Trunc-to-size failed %d", ret); - cachefiles_remove_object_xattr(cache, file->f_path.dentry); + cachefiles_remove_object_xattr(cache, object, file->f_path.dentry); return false; } @@ -164,8 +166,10 @@ static bool cachefiles_shorten_object(struct cachefiles_object *object, ret = vfs_fallocate(file, FALLOC_FL_ZERO_RANGE, new_size, dio_size); if (ret < 0) { + trace_cachefiles_io_error(object, file_inode(file), ret, + cachefiles_trace_fallocate_error); cachefiles_io_error_obj(object, "Trunc-to-dio-size failed %d", ret); - cachefiles_remove_object_xattr(cache, file->f_path.dentry); + cachefiles_remove_object_xattr(cache, object, file->f_path.dentry); return false; } } @@ -384,6 +388,9 @@ static int cachefiles_attr_changed(struct cachefiles_object *object) inode_unlock(file_inode(file)); cachefiles_end_secure(cache, saved_cred); + if (ret < 0) + trace_cachefiles_io_error(NULL, file_inode(file), ret, + cachefiles_trace_notify_change_error); if (ret == -EIO) { cachefiles_io_error_obj(object, "Size set failed"); ret = -ENOBUFS; diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index 83cf2ca3a763..3dd3e13989d6 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -238,6 +238,7 @@ extern int cachefiles_set_object_xattr(struct cachefiles_object *object); extern int cachefiles_check_auxdata(struct cachefiles_object *object, struct file *file); extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, + struct cachefiles_object *object, struct dentry *dentry); extern void cachefiles_prepare_to_write(struct fscache_cookie *cookie); diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index 5e3579800689..136d0ea0a7c9 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -44,9 +44,14 @@ static inline void cachefiles_put_kiocb(struct cachefiles_kiocb *ki) static void cachefiles_read_complete(struct kiocb *iocb, long ret, long ret2) { struct cachefiles_kiocb *ki = container_of(iocb, struct cachefiles_kiocb, iocb); + struct inode *inode = file_inode(ki->iocb.ki_filp); _enter("%ld,%ld", ret, ret2); + if (ret < 0) + trace_cachefiles_io_error(ki->object, inode, ret, + cachefiles_trace_read_error); + if (ki->term_func) { if (ret >= 0) { if (ki->object->cookie->inval_counter == ki->inval_counter) @@ -195,6 +200,10 @@ static void cachefiles_write_complete(struct kiocb *iocb, long ret, long ret2) __sb_writers_acquired(inode->i_sb, SB_FREEZE_WRITE); __sb_end_write(inode->i_sb, SB_FREEZE_WRITE); + if (ret < 0) + trace_cachefiles_io_error(ki->object, inode, ret, + cachefiles_trace_write_error); + set_bit(FSCACHE_COOKIE_HAVE_DATA, &ki->object->cookie->flags); if (ki->term_func) ki->term_func(ki->term_func_priv, ret, ki->was_async); @@ -352,6 +361,8 @@ static enum netfs_read_source cachefiles_prepare_read(struct netfs_read_subreque why = cachefiles_trace_read_seek_nxio; goto download_and_store; } + trace_cachefiles_io_error(object, file_inode(file), off, + cachefiles_trace_seek_error); why = cachefiles_trace_read_seek_error; goto out; } @@ -370,6 +381,8 @@ static enum netfs_read_source cachefiles_prepare_read(struct netfs_read_subreque to = vfs_llseek(file, subreq->start, SEEK_HOLE); if (to < 0 && to >= (loff_t)-MAX_ERRNO) { + trace_cachefiles_io_error(object, file_inode(file), to, + cachefiles_trace_seek_error); why = cachefiles_trace_read_seek_error; goto out; } @@ -425,6 +438,8 @@ static int __cachefiles_prepare_write(struct netfs_cache_resources *cres, if (pos < 0 && pos >= (loff_t)-MAX_ERRNO) { if (pos == -ENXIO) goto check_space; /* Unallocated tail */ + trace_cachefiles_io_error(object, file_inode(file), pos, + cachefiles_trace_seek_error); return pos; } if ((u64)pos >= (u64)*_start + *_len) @@ -438,8 +453,11 @@ static int __cachefiles_prepare_write(struct netfs_cache_resources *cres, return 0; /* Enough space to simply overwrite the whole block */ pos = vfs_llseek(file, *_start, SEEK_HOLE); - if (pos < 0 && pos >= (loff_t)-MAX_ERRNO) + if (pos < 0 && pos >= (loff_t)-MAX_ERRNO) { + trace_cachefiles_io_error(object, file_inode(file), pos, + cachefiles_trace_seek_error); return pos; + } if ((u64)pos >= (u64)*_start + *_len) return 0; /* Fully allocated */ @@ -447,6 +465,8 @@ static int __cachefiles_prepare_write(struct netfs_cache_resources *cres, ret = vfs_fallocate(file, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, *_start, *_len); if (ret < 0) { + trace_cachefiles_io_error(object, file_inode(file), ret, + cachefiles_trace_fallocate_error); cachefiles_io_error_obj(object, "CacheFiles: fallocate failed (%d)\n", ret); ret = -EIO; diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 989df918570b..12266c90e5f8 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -122,8 +122,12 @@ int cachefiles_bury_object(struct cachefiles_cache *cache, inode_unlock(d_inode(dir)); - if (ret == -EIO) - cachefiles_io_error(cache, "Unlink failed"); + if (ret < 0) { + trace_cachefiles_vfs_error(object, d_inode(dir), ret, + cachefiles_trace_unlink_error); + if (ret == -EIO) + cachefiles_io_error(cache, "Unlink failed"); + } _leave(" = %d", ret); return ret; @@ -172,6 +176,9 @@ int cachefiles_bury_object(struct cachefiles_cache *cache, grave = lookup_one_len(nbuffer, cache->graveyard, strlen(nbuffer)); if (IS_ERR(grave)) { unlock_rename(cache->graveyard, dir); + trace_cachefiles_vfs_error(object, d_inode(cache->graveyard), + PTR_ERR(grave), + cachefiles_trace_lookup_error); if (PTR_ERR(grave) == -ENOMEM) { _leave(" = -ENOMEM"); @@ -224,6 +231,10 @@ int cachefiles_bury_object(struct cachefiles_cache *cache, }; trace_cachefiles_rename(object, rep, grave, why); ret = vfs_rename(&rd); + if (ret != 0) + trace_cachefiles_vfs_error(object, d_inode(dir), + PTR_ERR(grave), + cachefiles_trace_rename_error); if (ret != 0 && ret != -ENOMEM) cachefiles_io_error(cache, "Rename failed with error %d", ret); @@ -249,6 +260,9 @@ static int cachefiles_unlink(struct cachefiles_object *object, ret = security_path_unlink(&path, dentry); if (ret == 0) ret = vfs_unlink(&init_user_ns, d_backing_inode(fan), dentry, NULL); + if (ret != 0) + trace_cachefiles_vfs_error(object, d_backing_inode(fan), ret, + cachefiles_trace_unlink_error); return ret; } @@ -273,6 +287,9 @@ int cachefiles_delete_object(struct cachefiles_object *object, inode_unlock(d_backing_inode(fan)); dput(dentry); + if (ret < 0) + trace_cachefiles_vfs_error(object, d_backing_inode(fan), ret, + cachefiles_trace_unlink_error); if (ret < 0 && ret != -ENOENT) cachefiles_io_error(volume->cache, "Unlink failed"); return ret; @@ -326,8 +343,12 @@ static bool cachefiles_open_file(struct cachefiles_object *object, path.dentry = dentry; file = open_with_fake_path(&path, O_RDWR | O_LARGEFILE | O_DIRECT, d_backing_inode(dentry), cache->cache_cred); - if (IS_ERR(file)) + if (IS_ERR(file)) { + trace_cachefiles_vfs_error(object, d_backing_inode(dentry), + PTR_ERR(file), + cachefiles_trace_open_error); goto error; + } if (unlikely(!file->f_op->read_iter) || unlikely(!file->f_op->write_iter)) { @@ -430,6 +451,9 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, retry: subdir = lookup_one_len(dirname, dir, strlen(dirname)); if (IS_ERR(subdir)) { + trace_cachefiles_vfs_error(NULL, d_backing_inode(dir), + PTR_ERR(subdir), + cachefiles_trace_lookup_error); if (PTR_ERR(subdir) == -ENOMEM) goto nomem_d_alloc; goto lookup_error; @@ -454,8 +478,11 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, if (ret < 0) goto mkdir_error; ret = vfs_mkdir(&init_user_ns, d_inode(dir), subdir, 0700); - if (ret < 0) + if (ret < 0) { + trace_cachefiles_vfs_error(NULL, d_inode(dir), ret, + cachefiles_trace_mkdir_error); goto mkdir_error; + } if (unlikely(d_unhashed(subdir))) { dput(subdir); @@ -610,7 +637,7 @@ int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir, */ _debug("victim is cullable"); - ret = cachefiles_remove_object_xattr(cache, victim); + ret = cachefiles_remove_object_xattr(cache, NULL, victim); if (ret < 0) goto error_unlock; @@ -693,6 +720,8 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object) path.mnt = cache->mnt, path.dentry = vfs_tmpfile(&init_user_ns, fan, S_IFREG, O_RDWR); if (IS_ERR(path.dentry)) { + trace_cachefiles_vfs_error(object, d_inode(fan), PTR_ERR(path.dentry), + cachefiles_trace_tmpfile_error); if (PTR_ERR(path.dentry) == -EIO) cachefiles_io_error_obj(object, "Failed to create tmpfile"); file = ERR_CAST(path.dentry); @@ -711,6 +740,9 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object) cachefiles_trunc_expand_tmpfile); ret = vfs_truncate(&path, ni_size); if (ret < 0) { + trace_cachefiles_vfs_error( + object, d_backing_inode(path.dentry), ret, + cachefiles_trace_trunc_error); file = ERR_PTR(ret); goto out_dput; } @@ -718,8 +750,12 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object) file = open_with_fake_path(&path, O_RDWR | O_LARGEFILE | O_DIRECT, d_backing_inode(path.dentry), cache->cache_cred); - if (IS_ERR(file)) + if (IS_ERR(file)) { + trace_cachefiles_vfs_error(object, d_backing_inode(path.dentry), + PTR_ERR(file), + cachefiles_trace_open_error); goto out_dput; + } if (unlikely(!file->f_op->read_iter) || unlikely(!file->f_op->write_iter)) { fput(file); @@ -750,6 +786,8 @@ bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache, inode_lock_nested(d_inode(fan), I_MUTEX_PARENT); dentry = lookup_one_len(object->d_name, fan, object->d_name_len); if (IS_ERR(dentry)) { + trace_cachefiles_vfs_error(object, d_inode(fan), PTR_ERR(dentry), + cachefiles_trace_lookup_error); _debug("lookup fail %ld", PTR_ERR(dentry)); goto out_unlock; } @@ -761,12 +799,17 @@ bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache, } ret = cachefiles_unlink(object, fan, dentry, FSCACHE_OBJECT_IS_STALE); - if (ret < 0) + if (ret < 0) { + trace_cachefiles_vfs_error(object, d_inode(fan), ret, + cachefiles_trace_unlink_error); goto out_dput; + } dput(dentry); dentry = lookup_one_len(object->d_name, fan, object->d_name_len); if (IS_ERR(dentry)) { + trace_cachefiles_vfs_error(object, d_inode(fan), PTR_ERR(dentry), + cachefiles_trace_lookup_error); _debug("lookup fail %ld", PTR_ERR(dentry)); goto out_unlock; } @@ -775,6 +818,8 @@ bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache, ret = vfs_link(object->file->f_path.dentry, &init_user_ns, d_inode(fan), dentry, NULL); if (ret < 0) { + trace_cachefiles_vfs_error(object, d_inode(fan), PTR_ERR(dentry), + cachefiles_trace_link_error); _debug("link fail %d", ret); } else { trace_cachefiles_link(object, file_inode(object->file)); diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c index 30adca42883b..e0f77329c3ec 100644 --- a/fs/cachefiles/xattr.c +++ b/fs/cachefiles/xattr.c @@ -61,6 +61,8 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object) ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache, buf, sizeof(struct cachefiles_xattr) + len, 0); if (ret < 0) { + trace_cachefiles_vfs_error(object, file_inode(file), ret, + cachefiles_trace_setxattr_error); trace_cachefiles_coherency(object, file_inode(file)->i_ino, buf->content, cachefiles_coherency_set_fail); @@ -99,6 +101,9 @@ int cachefiles_check_auxdata(struct cachefiles_object *object, struct file *file xlen = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, buf, tlen); if (xlen != tlen) { + if (xlen < 0) + trace_cachefiles_vfs_error(object, file_inode(file), xlen, + cachefiles_trace_getxattr_error); if (xlen == -EIO) cachefiles_io_error_obj( object, @@ -129,12 +134,15 @@ int cachefiles_check_auxdata(struct cachefiles_object *object, struct file *file * remove the object's xattr to mark it stale */ int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, + struct cachefiles_object *object, struct dentry *dentry) { int ret; ret = vfs_removexattr(&init_user_ns, dentry, cachefiles_xattr_cache); if (ret < 0) { + trace_cachefiles_vfs_error(object, d_inode(dentry), ret, + cachefiles_trace_remxattr_error); if (ret == -ENOENT || ret == -ENODATA) ret = 0; else if (ret != -ENOMEM) diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h index 11447b20fc83..6a41a36ce581 100644 --- a/include/trace/events/cachefiles.h +++ b/include/trace/events/cachefiles.h @@ -72,6 +72,26 @@ enum cachefiles_prepare_read_trace { cachefiles_trace_read_seek_nxio, }; +enum cachefiles_error_trace { + cachefiles_trace_fallocate_error, + cachefiles_trace_getxattr_error, + cachefiles_trace_link_error, + cachefiles_trace_lookup_error, + cachefiles_trace_mkdir_error, + cachefiles_trace_notify_change_error, + cachefiles_trace_open_error, + cachefiles_trace_read_error, + cachefiles_trace_remxattr_error, + cachefiles_trace_rename_error, + cachefiles_trace_seek_error, + cachefiles_trace_setxattr_error, + cachefiles_trace_statfs_error, + cachefiles_trace_tmpfile_error, + cachefiles_trace_trunc_error, + cachefiles_trace_unlink_error, + cachefiles_trace_write_error, +}; + #endif /* @@ -126,6 +146,25 @@ enum cachefiles_prepare_read_trace { EM(cachefiles_trace_read_seek_error, "seek-error") \ E_(cachefiles_trace_read_seek_nxio, "seek-enxio") +#define cachefiles_error_traces \ + EM(cachefiles_trace_fallocate_error, "fallocate") \ + EM(cachefiles_trace_getxattr_error, "getxattr") \ + EM(cachefiles_trace_link_error, "link") \ + EM(cachefiles_trace_lookup_error, "lookup") \ + EM(cachefiles_trace_mkdir_error, "mkdir") \ + EM(cachefiles_trace_notify_change_error, "notify_change") \ + EM(cachefiles_trace_open_error, "open") \ + EM(cachefiles_trace_read_error, "read") \ + EM(cachefiles_trace_remxattr_error, "remxattr") \ + EM(cachefiles_trace_rename_error, "rename") \ + EM(cachefiles_trace_seek_error, "seek") \ + EM(cachefiles_trace_setxattr_error, "setxattr") \ + EM(cachefiles_trace_statfs_error, "statfs") \ + EM(cachefiles_trace_tmpfile_error, "tmpfile") \ + EM(cachefiles_trace_trunc_error, "trunc") \ + EM(cachefiles_trace_unlink_error, "unlink") \ + E_(cachefiles_trace_write_error, "write") + /* * Export enum symbols via userspace. @@ -140,6 +179,7 @@ cachefiles_obj_ref_traces; cachefiles_coherency_traces; cachefiles_trunc_traces; cachefiles_prepare_read_traces; +cachefiles_error_traces; /* * Now redefine the EM() and E_() macros to map the enums to the strings that @@ -496,6 +536,60 @@ TRACE_EVENT(cachefiles_trunc, __entry->to) ); +TRACE_EVENT(cachefiles_vfs_error, + TP_PROTO(struct cachefiles_object *obj, struct inode *backer, + int error, enum cachefiles_error_trace where), + + TP_ARGS(obj, backer, error, where), + + TP_STRUCT__entry( + __field(unsigned int, obj ) + __field(unsigned int, backer ) + __field(enum cachefiles_error_trace, where ) + __field(short, error ) + ), + + TP_fast_assign( + __entry->obj = obj ? obj->debug_id : 0; + __entry->backer = backer->i_ino; + __entry->error = error; + __entry->where = where; + ), + + TP_printk("o=%08x b=%08x %s e=%d", + __entry->obj, + __entry->backer, + __print_symbolic(__entry->where, cachefiles_error_traces), + __entry->error) + ); + +TRACE_EVENT(cachefiles_io_error, + TP_PROTO(struct cachefiles_object *obj, struct inode *backer, + int error, enum cachefiles_error_trace where), + + TP_ARGS(obj, backer, error, where), + + TP_STRUCT__entry( + __field(unsigned int, obj ) + __field(unsigned int, backer ) + __field(enum cachefiles_error_trace, where ) + __field(short, error ) + ), + + TP_fast_assign( + __entry->obj = obj ? obj->debug_id : 0; + __entry->backer = backer->i_ino; + __entry->error = error; + __entry->where = where; + ), + + TP_printk("o=%08x b=%08x %s e=%d", + __entry->obj, + __entry->backer, + __print_symbolic(__entry->where, cachefiles_error_traces), + __entry->error) + ); + #endif /* _TRACE_CACHEFILES_H */ /* This part must be outside protection */ From patchwork Mon Oct 18 15:08:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567285 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 57FAEC433EF for ; Mon, 18 Oct 2021 15:09:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3E94A60F94 for ; Mon, 18 Oct 2021 15:09:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233363AbhJRPLn (ORCPT ); Mon, 18 Oct 2021 11:11:43 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:44405 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233499AbhJRPLY (ORCPT ); Mon, 18 Oct 2021 11:11:24 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569751; 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=BKYI5BvDsOXffIFvPU9sYAc5vgRXUjZkZYpsLpIFF08=; b=gDRLKHG1KGkhS6uduM7BPdhOgEmw4h8cn+uOseB2Ow9T0EfB5cw6PD+8Yh/0bW6z9jLTS/ zgFktqiwNY7UuVcIHq6bDw1ZT6mbb75KL+5QV7mn+W7l8ndu2CT+gaYeuaTs3kzHBrqVZN p79lVn2YnYduYgWwML0V5WnPiPP0XaI= 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-566-NsdXsi1qNtu5WRFNMvnvUQ-1; Mon, 18 Oct 2021 11:09:08 -0400 X-MC-Unique: NsdXsi1qNtu5WRFNMvnvUQ-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 88EB81006AA6; Mon, 18 Oct 2021 15:09:06 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8629C167A4; Mon, 18 Oct 2021 15:08:58 +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 66/67] cachefiles: Add error injection support From: David Howells To: linux-cachefs@redhat.com Cc: dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:08:57 +0100 Message-ID: <163456973776.2614702.12301119633219400267.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Add support for injecting ENOSPC or EIO errors. This needs to be enabled by CONFIG_CACHEFILES_ERROR_INJECTION=y. Once enabled, ENOSPC on things like write and mkdir can be triggered by: echo 1 >/proc/sys/cachefiles/error_injection and EIO can be triggered on most operations by: echo 2 >/proc/sys/cachefiles/error_injection Signed-off-by: David Howells --- fs/cachefiles/Kconfig | 8 ++++++ fs/cachefiles/Makefile | 2 + fs/cachefiles/error_inject.c | 46 ++++++++++++++++++++++++++++++++++ fs/cachefiles/interface.c | 21 +++++++++++---- fs/cachefiles/internal.h | 39 +++++++++++++++++++++++++++++ fs/cachefiles/io.c | 34 ++++++++++++++++++------- fs/cachefiles/main.c | 7 +++++ fs/cachefiles/namei.c | 57 +++++++++++++++++++++++++++++++++--------- fs/cachefiles/xattr.c | 14 +++++++--- 9 files changed, 197 insertions(+), 31 deletions(-) create mode 100644 fs/cachefiles/error_inject.c diff --git a/fs/cachefiles/Kconfig b/fs/cachefiles/Kconfig index 6827b40f7ddc..c19515dd253e 100644 --- a/fs/cachefiles/Kconfig +++ b/fs/cachefiles/Kconfig @@ -19,3 +19,11 @@ config CACHEFILES_DEBUG caching on files module. If this is set, the debugging output may be enabled by setting bits in /sys/modules/cachefiles/parameter/debug or by including a debugging specifier in /etc/cachefilesd.conf. + + +config CACHEFILES_ERROR_INJECTION + bool "Provide error injection for cachefiles" + depends on CACHEFILES && SYSCTL + help + This permits error injection to be enabled in cachefiles whilst a + cache is in service. diff --git a/fs/cachefiles/Makefile b/fs/cachefiles/Makefile index 9062767331e8..c0df4c42cb09 100644 --- a/fs/cachefiles/Makefile +++ b/fs/cachefiles/Makefile @@ -15,4 +15,6 @@ cachefiles-y := \ volume.o \ xattr.o +cachefiles-$(CONFIG_CACHEFILES_ERROR_INJECTION) += error_inject.o + obj-$(CONFIG_CACHEFILES) := cachefiles.o diff --git a/fs/cachefiles/error_inject.c b/fs/cachefiles/error_inject.c new file mode 100644 index 000000000000..58f8aec964e4 --- /dev/null +++ b/fs/cachefiles/error_inject.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* Error injection handling. + * + * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +#include +#include "internal.h" + +unsigned int cachefiles_error_injection_state; + +static struct ctl_table_header *cachefiles_sysctl; +static struct ctl_table cachefiles_sysctls[] = { + { + .procname = "error_injection", + .data = &cachefiles_error_injection_state, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_douintvec, + }, + {} +}; + +static struct ctl_table cachefiles_sysctls_root[] = { + { + .procname = "cachefiles", + .mode = 0555, + .child = cachefiles_sysctls, + }, + {} +}; + +int __init cachefiles_register_error_injection(void) +{ + cachefiles_sysctl = register_sysctl_table(cachefiles_sysctls_root); + if (!cachefiles_sysctl) + return -ENOMEM; + return 0; + +} + +void cachefiles_unregister_error_injection(void) +{ + unregister_sysctl_table(cachefiles_sysctl); +} diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 115be503b23a..3c9710ceae86 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -151,7 +151,9 @@ static bool cachefiles_shorten_object(struct cachefiles_object *object, trace_cachefiles_trunc(object, inode, i_size, dio_size, cachefiles_trunc_shrink); - ret = vfs_truncate(&file->f_path, dio_size); + ret = cachefiles_inject_remove_error(); + if (ret == 0) + ret = vfs_truncate(&file->f_path, dio_size); if (ret < 0) { trace_cachefiles_io_error(object, file_inode(file), ret, cachefiles_trace_trunc_error); @@ -163,8 +165,10 @@ static bool cachefiles_shorten_object(struct cachefiles_object *object, if (new_size < dio_size) { trace_cachefiles_trunc(object, inode, dio_size, new_size, cachefiles_trunc_dio_adjust); - ret = vfs_fallocate(file, FALLOC_FL_ZERO_RANGE, - new_size, dio_size); + ret = cachefiles_inject_write_error(); + if (ret == 0) + ret = vfs_fallocate(file, FALLOC_FL_ZERO_RANGE, + new_size, dio_size); if (ret < 0) { trace_cachefiles_io_error(object, file_inode(file), ret, cachefiles_trace_fallocate_error); @@ -374,15 +378,20 @@ static int cachefiles_attr_changed(struct cachefiles_object *object) _debug("discard tail %llx", oi_size); newattrs.ia_valid = ATTR_SIZE; newattrs.ia_size = oi_size & PAGE_MASK; - ret = notify_change(&init_user_ns, file->f_path.dentry, - &newattrs, NULL); + ret = cachefiles_inject_remove_error(); + if (ret == 0) + ret = notify_change(&init_user_ns, file->f_path.dentry, + &newattrs, NULL); if (ret < 0) goto truncate_failed; } newattrs.ia_valid = ATTR_SIZE; newattrs.ia_size = ni_size; - ret = notify_change(&init_user_ns, file->f_path.dentry, &newattrs, NULL); + ret = cachefiles_inject_write_error(); + if (ret == 0) + ret = notify_change(&init_user_ns, file->f_path.dentry, + &newattrs, NULL); truncate_failed: inode_unlock(file_inode(file)); diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index 3dd3e13989d6..096ee6376f2a 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -155,6 +155,45 @@ extern const struct file_operations cachefiles_daemon_fops; extern int cachefiles_has_space(struct cachefiles_cache *cache, unsigned fnr, unsigned bnr); +/* + * error_inject.c + */ +#ifdef CONFIG_CACHEFILES_ERROR_INJECTION +extern unsigned int cachefiles_error_injection_state; +extern int cachefiles_register_error_injection(void); +extern void cachefiles_unregister_error_injection(void); + +#else +#define cachefiles_error_injection_state 0 + +static inline int cachefiles_register_error_injection(void) +{ + return 0; +} + +static inline void cachefiles_unregister_error_injection(void) +{ +} +#endif + + +static inline int cachefiles_inject_read_error(void) +{ + return cachefiles_error_injection_state & 2 ? -EIO : 0; +} + +static inline int cachefiles_inject_write_error(void) +{ + return cachefiles_error_injection_state & 2 ? -EIO : + cachefiles_error_injection_state & 1 ? -ENOSPC : + 0; +} + +static inline int cachefiles_inject_remove_error(void) +{ + return cachefiles_error_injection_state & 2 ? -EIO : 0; +} + /* * interface.c */ diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index 136d0ea0a7c9..78e6ef781f73 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -100,7 +100,9 @@ static int cachefiles_read(struct netfs_cache_resources *cres, if (read_hole != NETFS_READ_HOLE_IGNORE) { loff_t off = start_pos, off2; - off2 = vfs_llseek(file, off, SEEK_DATA); + off2 = cachefiles_inject_read_error(); + if (off2 == 0) + off2 = vfs_llseek(file, off, SEEK_DATA); if (off2 < 0 && off2 >= (loff_t)-MAX_ERRNO && off2 != -ENXIO) { skipped = 0; ret = off2; @@ -152,7 +154,9 @@ static int cachefiles_read(struct netfs_cache_resources *cres, trace_cachefiles_read(object, file_inode(file), ki->iocb.ki_pos, len - skipped); old_nofs = memalloc_nofs_save(); - ret = vfs_iocb_iter_read(file, &ki->iocb, iter); + ret = cachefiles_inject_read_error(); + if (ret == 0) + ret = vfs_iocb_iter_read(file, &ki->iocb, iter); memalloc_nofs_restore(old_nofs); switch (ret) { case -EIOCBQUEUED: @@ -273,7 +277,9 @@ static int cachefiles_write(struct netfs_cache_resources *cres, trace_cachefiles_write(object, inode, ki->iocb.ki_pos, len); old_nofs = memalloc_nofs_save(); - ret = vfs_iocb_iter_write(file, &ki->iocb, iter); + ret = cachefiles_inject_write_error(); + if (ret == 0) + ret = vfs_iocb_iter_write(file, &ki->iocb, iter); memalloc_nofs_restore(old_nofs); switch (ret) { case -EIOCBQUEUED: @@ -355,7 +361,9 @@ static enum netfs_read_source cachefiles_prepare_read(struct netfs_read_subreque cache = object->volume->cache; cachefiles_begin_secure(cache, &saved_cred); - off = vfs_llseek(file, subreq->start, SEEK_DATA); + off = cachefiles_inject_read_error(); + if (off == 0) + off = vfs_llseek(file, subreq->start, SEEK_DATA); if (off < 0 && off >= (loff_t)-MAX_ERRNO) { if (off == (loff_t)-ENXIO) { why = cachefiles_trace_read_seek_nxio; @@ -379,7 +387,9 @@ static enum netfs_read_source cachefiles_prepare_read(struct netfs_read_subreque goto download_and_store; } - to = vfs_llseek(file, subreq->start, SEEK_HOLE); + to = cachefiles_inject_read_error(); + if (to == 0) + to = vfs_llseek(file, subreq->start, SEEK_HOLE); if (to < 0 && to >= (loff_t)-MAX_ERRNO) { trace_cachefiles_io_error(object, file_inode(file), to, cachefiles_trace_seek_error); @@ -434,7 +444,9 @@ static int __cachefiles_prepare_write(struct netfs_cache_resources *cres, if (no_space_allocated_yet) goto check_space; - pos = vfs_llseek(file, *_start, SEEK_DATA); + pos = cachefiles_inject_read_error(); + if (pos == 0) + pos = vfs_llseek(file, *_start, SEEK_DATA); if (pos < 0 && pos >= (loff_t)-MAX_ERRNO) { if (pos == -ENXIO) goto check_space; /* Unallocated tail */ @@ -452,7 +464,9 @@ static int __cachefiles_prepare_write(struct netfs_cache_resources *cres, if (cachefiles_has_space(cache, 0, *_len / PAGE_SIZE) == 0) return 0; /* Enough space to simply overwrite the whole block */ - pos = vfs_llseek(file, *_start, SEEK_HOLE); + pos = cachefiles_inject_read_error(); + if (pos == 0) + pos = vfs_llseek(file, *_start, SEEK_HOLE); if (pos < 0 && pos >= (loff_t)-MAX_ERRNO) { trace_cachefiles_io_error(object, file_inode(file), pos, cachefiles_trace_seek_error); @@ -462,8 +476,10 @@ static int __cachefiles_prepare_write(struct netfs_cache_resources *cres, return 0; /* Fully allocated */ /* Partially allocated, but insufficient space: cull. */ - ret = vfs_fallocate(file, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, - *_start, *_len); + pos = cachefiles_inject_remove_error(); + if (pos == 0) + ret = vfs_fallocate(file, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + *_start, *_len); if (ret < 0) { trace_cachefiles_io_error(object, file_inode(file), ret, cachefiles_trace_fallocate_error); diff --git a/fs/cachefiles/main.c b/fs/cachefiles/main.c index 522fda828563..83f8a221a890 100644 --- a/fs/cachefiles/main.c +++ b/fs/cachefiles/main.c @@ -46,6 +46,10 @@ static int __init cachefiles_init(void) { int ret; + ret = cachefiles_register_error_injection(); + if (ret < 0) + goto error_einj; + ret = misc_register(&cachefiles_dev); if (ret < 0) goto error_dev; @@ -67,6 +71,8 @@ static int __init cachefiles_init(void) error_object_jar: misc_deregister(&cachefiles_dev); error_dev: + cachefiles_unregister_error_injection(); +error_einj: pr_err("failed to register: %d\n", ret); return ret; } @@ -82,6 +88,7 @@ static void __exit cachefiles_exit(void) kmem_cache_destroy(cachefiles_object_jar); misc_deregister(&cachefiles_dev); + cachefiles_unregister_error_injection(); } module_exit(cachefiles_exit); diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 12266c90e5f8..686480120570 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -116,7 +116,9 @@ int cachefiles_bury_object(struct cachefiles_cache *cache, dget(rep); /* Stop the dentry being negated if it's * only pinned by a file struct. */ - ret = vfs_unlink(&init_user_ns, d_inode(dir), rep, NULL); + ret = cachefiles_inject_remove_error(); + if (ret == 0) + ret = vfs_unlink(&init_user_ns, d_inode(dir), rep, NULL); dput(rep); } @@ -230,7 +232,9 @@ int cachefiles_bury_object(struct cachefiles_cache *cache, .new_dentry = grave, }; trace_cachefiles_rename(object, rep, grave, why); - ret = vfs_rename(&rd); + ret = cachefiles_inject_read_error(); + if (ret == 0) + ret = vfs_rename(&rd); if (ret != 0) trace_cachefiles_vfs_error(object, d_inode(dir), PTR_ERR(grave), @@ -258,6 +262,8 @@ static int cachefiles_unlink(struct cachefiles_object *object, trace_cachefiles_unlink(object, dentry, why); ret = security_path_unlink(&path, dentry); + if (ret == 0) + ret = cachefiles_inject_remove_error(); if (ret == 0) ret = vfs_unlink(&init_user_ns, d_backing_inode(fan), dentry, NULL); if (ret != 0) @@ -400,7 +406,12 @@ bool cachefiles_look_up_object(struct cachefiles_object *object) _enter("OBJ%x,%s,", object->debug_id, object->d_name); /* Look up path "cache/vol/fanout/file". */ - dentry = lookup_positive_unlocked(object->d_name, fan, object->d_name_len); + ret = cachefiles_inject_read_error(); + if (ret == 0) + dentry = lookup_positive_unlocked(object->d_name, fan, + object->d_name_len); + else + dentry = ERR_PTR(ret); trace_cachefiles_lookup(object, dentry); if (IS_ERR(dentry)) { if (dentry == ERR_PTR(-ENOENT)) @@ -449,7 +460,11 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, inode_lock(d_inode(dir)); retry: - subdir = lookup_one_len(dirname, dir, strlen(dirname)); + ret = cachefiles_inject_read_error(); + if (ret == 0) + subdir = lookup_one_len(dirname, dir, strlen(dirname)); + else + subdir = ERR_PTR(ret); if (IS_ERR(subdir)) { trace_cachefiles_vfs_error(NULL, d_backing_inode(dir), PTR_ERR(subdir), @@ -477,7 +492,9 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, ret = security_path_mkdir(&path, subdir, 0700); if (ret < 0) goto mkdir_error; - ret = vfs_mkdir(&init_user_ns, d_inode(dir), subdir, 0700); + ret = cachefiles_inject_write_error(); + if (ret == 0) + ret = vfs_mkdir(&init_user_ns, d_inode(dir), subdir, 0700); if (ret < 0) { trace_cachefiles_vfs_error(NULL, d_inode(dir), ret, cachefiles_trace_mkdir_error); @@ -717,8 +734,12 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object) cachefiles_begin_secure(cache, &saved_cred); - path.mnt = cache->mnt, - path.dentry = vfs_tmpfile(&init_user_ns, fan, S_IFREG, O_RDWR); + path.mnt = cache->mnt; + ret = cachefiles_inject_write_error(); + if (ret == 0) + path.dentry = vfs_tmpfile(&init_user_ns, fan, S_IFREG, O_RDWR); + else + path.dentry = ERR_PTR(ret); if (IS_ERR(path.dentry)) { trace_cachefiles_vfs_error(object, d_inode(fan), PTR_ERR(path.dentry), cachefiles_trace_tmpfile_error); @@ -738,7 +759,9 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object) if (ni_size > 0) { trace_cachefiles_trunc(object, d_backing_inode(path.dentry), 0, ni_size, cachefiles_trunc_expand_tmpfile); - ret = vfs_truncate(&path, ni_size); + ret = cachefiles_inject_write_error(); + if (ret == 0) + ret = vfs_truncate(&path, ni_size); if (ret < 0) { trace_cachefiles_vfs_error( object, d_backing_inode(path.dentry), ret, @@ -784,7 +807,11 @@ bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache, _enter(",%pD", object->file); inode_lock_nested(d_inode(fan), I_MUTEX_PARENT); - dentry = lookup_one_len(object->d_name, fan, object->d_name_len); + ret = cachefiles_inject_read_error(); + if (ret == 0) + dentry = lookup_one_len(object->d_name, fan, object->d_name_len); + else + dentry = ERR_PTR(ret); if (IS_ERR(dentry)) { trace_cachefiles_vfs_error(object, d_inode(fan), PTR_ERR(dentry), cachefiles_trace_lookup_error); @@ -806,7 +833,11 @@ bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache, } dput(dentry); - dentry = lookup_one_len(object->d_name, fan, object->d_name_len); + ret = cachefiles_inject_read_error(); + if (ret == 0) + dentry = lookup_one_len(object->d_name, fan, object->d_name_len); + else + dentry = ERR_PTR(ret); if (IS_ERR(dentry)) { trace_cachefiles_vfs_error(object, d_inode(fan), PTR_ERR(dentry), cachefiles_trace_lookup_error); @@ -815,8 +846,10 @@ bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache, } } - ret = vfs_link(object->file->f_path.dentry, &init_user_ns, - d_inode(fan), dentry, NULL); + ret = cachefiles_inject_read_error(); + if (ret == 0) + ret = vfs_link(object->file->f_path.dentry, &init_user_ns, + d_inode(fan), dentry, NULL); if (ret < 0) { trace_cachefiles_vfs_error(object, d_inode(fan), PTR_ERR(dentry), cachefiles_trace_link_error); diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c index e0f77329c3ec..2555b82be7e2 100644 --- a/fs/cachefiles/xattr.c +++ b/fs/cachefiles/xattr.c @@ -58,8 +58,10 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object) if (len > 0) memcpy(buf->data, fscache_get_aux(object->cookie), len); - ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache, - buf, sizeof(struct cachefiles_xattr) + len, 0); + ret = cachefiles_inject_write_error(); + if (ret == 0) + ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache, + buf, sizeof(struct cachefiles_xattr) + len, 0); if (ret < 0) { trace_cachefiles_vfs_error(object, file_inode(file), ret, cachefiles_trace_setxattr_error); @@ -99,7 +101,9 @@ int cachefiles_check_auxdata(struct cachefiles_object *object, struct file *file if (!buf) return -ENOMEM; - xlen = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, buf, tlen); + xlen = cachefiles_inject_read_error(); + if (xlen == 0) + xlen = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, buf, tlen); if (xlen != tlen) { if (xlen < 0) trace_cachefiles_vfs_error(object, file_inode(file), xlen, @@ -139,7 +143,9 @@ int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, { int ret; - ret = vfs_removexattr(&init_user_ns, dentry, cachefiles_xattr_cache); + ret = cachefiles_inject_remove_error(); + if (ret == 0) + ret = vfs_removexattr(&init_user_ns, dentry, cachefiles_xattr_cache); if (ret < 0) { trace_cachefiles_vfs_error(object, d_inode(dentry), ret, cachefiles_trace_remxattr_error); From patchwork Mon Oct 18 15:09:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 12567287 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 31C06C433EF for ; Mon, 18 Oct 2021 15:09:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1F93F610A3 for ; Mon, 18 Oct 2021 15:09:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233650AbhJRPLz (ORCPT ); Mon, 18 Oct 2021 11:11:55 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:24520 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232524AbhJRPLg (ORCPT ); Mon, 18 Oct 2021 11:11:36 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1634569764; 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=Tub9qV5VxABgzFj3ORCCtnSKBanlrG+GhBjqMhmHS0c=; b=Hnp7kOC5YO0UmnewVPYlayrafvaJFgNLedi47X5UCJVCi9Hh6dEf/KTGymyt/oxJthHlUs r//3d+GJn7odtmPTPf4dDl2nahXQf9M/KH67lhuELmQYQwHvM5D8GnuBM2dSi3DQqczeIU ug9lfMLe9whE+i2x4SZznrJDAoO8+PQ= 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-480-WAh5khE6Oh6dbitHDH8MXw-1; Mon, 18 Oct 2021 11:09:18 -0400 X-MC-Unique: WAh5khE6Oh6dbitHDH8MXw-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 656619116D; Mon, 18 Oct 2021 15:09:16 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 99F6A1A7E9; Mon, 18 Oct 2021 15:09:12 +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 67/67] cifs: Support fscache indexing rewrite (untested) From: David Howells To: linux-cachefs@redhat.com Cc: Jeff Layton , Steve French , Shyam Prasad N , linux-cifs@vger.kernel.org, dhowells@redhat.com, Trond Myklebust , Anna Schumaker , Steve French , Dominique Martinet , Jeff Layton , Matthew Wilcox , Alexander Viro , Omar Sandoval , Linus Torvalds , linux-afs@lists.infradead.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs-developer@lists.sourceforge.net, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Date: Mon, 18 Oct 2021 16:09:11 +0100 Message-ID: <163456975177.2614702.13238377969831836273.stgit@warthog.procyon.org.uk> In-Reply-To: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> References: <163456861570.2614702.14754548462706508617.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.23 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Change the cifs filesystem to take account of the changes to fscache's indexing rewrite and reenable caching in cifs. The following changes have been made: (1) The fscache_netfs struct is no more, and there's no need to register the filesystem as a whole. (2) The session cookie is now an fscache_volume cookie, allocated with fscache_acquire_volume(). That takes three parameters: a string representing the "volume" in the index, a string naming the cache to use (or NULL) and a u64 that conveys coherency metadata for the volume. For cifs, I've made it render the volume name string as: "cifs,," where the sharename has '/' characters replaced with ';'. This probably needs rethinking a bit as the total name could exceed the maximum filename component length. Further, the coherency data is currently just set to 0. It needs something else doing with it - I wonder if it would suffice simply to sum the resource_id, vol_create_time and vol_serial_number or maybe hash them. (3) The fscache_cookie_def is no more and needed information is passed directly to fscache_acquire_cookie(). The cache no longer calls back into the filesystem, but rather metadata changes are indicated at other times. fscache_acquire_cookie() is passed the same keying and coherency information as before. (4) The functions to set/reset cookies are removed and fscache_use_cookie() and fscache_unuse_cookie() are used instead. fscache_use_cookie() is passed a flag to indicate if the cookie is opened for writing. fscache_unuse_cookie() is passed updates for the metadata if we changed it (ie. if the file was opened for writing). These are called when the file is opened or closed. (5) cifs_setattr_*() are made to call fscache_resize() to change the size of the cache object. Signed-off-by: David Howells Acked-by: Jeff Layton cc: Steve French cc: Shyam Prasad N cc: linux-cifs@vger.kernel.org --- fs/cifs/Kconfig | 2 - fs/cifs/Makefile | 2 - fs/cifs/cache.c | 105 --------------------------- fs/cifs/cifsfs.c | 11 +-- fs/cifs/cifsglob.h | 5 - fs/cifs/connect.c | 3 - fs/cifs/file.c | 37 ++++++++-- fs/cifs/fscache.c | 201 +++++++++++++--------------------------------------- fs/cifs/fscache.h | 51 +++++-------- fs/cifs/inode.c | 18 +++-- 10 files changed, 117 insertions(+), 318 deletions(-) delete mode 100644 fs/cifs/cache.c diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig index c5477abbcff0..3b7e3b9e4fd2 100644 --- a/fs/cifs/Kconfig +++ b/fs/cifs/Kconfig @@ -188,7 +188,7 @@ config CIFS_SMB_DIRECT config CIFS_FSCACHE bool "Provide CIFS client caching support" - depends on CIFS=m && FSCACHE_OLD || CIFS=y && FSCACHE_OLD=y + depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y help Makes CIFS FS-Cache capable. Say Y here if you want your CIFS data to be cached locally on disk through the general filesystem cache diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile index 87fcacdf3de7..cc8fdcb35b71 100644 --- a/fs/cifs/Makefile +++ b/fs/cifs/Makefile @@ -25,7 +25,7 @@ cifs-$(CONFIG_CIFS_DFS_UPCALL) += cifs_dfs_ref.o dfs_cache.o cifs-$(CONFIG_CIFS_SWN_UPCALL) += netlink.o cifs_swn.o -cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o +cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cifs-$(CONFIG_CIFS_SMB_DIRECT) += smbdirect.o diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c deleted file mode 100644 index 8be57aaedab6..000000000000 --- a/fs/cifs/cache.c +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1 -/* - * CIFS filesystem cache index structure definitions - * - * Copyright (c) 2010 Novell, Inc. - * Authors(s): Suresh Jayaraman (sjayaraman@suse.de> - * - */ -#include "fscache.h" -#include "cifs_debug.h" - -/* - * CIFS filesystem definition for FS-Cache - */ -struct fscache_netfs cifs_fscache_netfs = { - .name = "cifs", - .version = 0, -}; - -/* - * Register CIFS for caching with FS-Cache - */ -int cifs_fscache_register(void) -{ - return fscache_register_netfs(&cifs_fscache_netfs); -} - -/* - * Unregister CIFS for caching - */ -void cifs_fscache_unregister(void) -{ - fscache_unregister_netfs(&cifs_fscache_netfs); -} - -/* - * Server object for FS-Cache - */ -const struct fscache_cookie_def cifs_fscache_server_index_def = { - .name = "CIFS.server", - .type = FSCACHE_COOKIE_TYPE_INDEX, -}; - -static enum -fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data, - const void *data, - uint16_t datalen, - loff_t object_size) -{ - struct cifs_fscache_super_auxdata auxdata; - const struct cifs_tcon *tcon = cookie_netfs_data; - - if (datalen != sizeof(auxdata)) - return FSCACHE_CHECKAUX_OBSOLETE; - - memset(&auxdata, 0, sizeof(auxdata)); - auxdata.resource_id = tcon->resource_id; - auxdata.vol_create_time = tcon->vol_create_time; - auxdata.vol_serial_number = tcon->vol_serial_number; - - if (memcmp(data, &auxdata, datalen) != 0) - return FSCACHE_CHECKAUX_OBSOLETE; - - return FSCACHE_CHECKAUX_OKAY; -} - -/* - * Superblock object for FS-Cache - */ -const struct fscache_cookie_def cifs_fscache_super_index_def = { - .name = "CIFS.super", - .type = FSCACHE_COOKIE_TYPE_INDEX, - .check_aux = cifs_fscache_super_check_aux, -}; - -static enum -fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data, - const void *data, - uint16_t datalen, - loff_t object_size) -{ - struct cifs_fscache_inode_auxdata auxdata; - struct cifsInodeInfo *cifsi = cookie_netfs_data; - - if (datalen != sizeof(auxdata)) - return FSCACHE_CHECKAUX_OBSOLETE; - - memset(&auxdata, 0, sizeof(auxdata)); - auxdata.eof = cifsi->server_eof; - auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec; - auxdata.last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec; - auxdata.last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec; - auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec; - - if (memcmp(data, &auxdata, datalen) != 0) - return FSCACHE_CHECKAUX_OBSOLETE; - - return FSCACHE_CHECKAUX_OKAY; -} - -const struct fscache_cookie_def cifs_fscache_inode_object_def = { - .name = "CIFS.uniqueid", - .type = FSCACHE_COOKIE_TYPE_DATAFILE, - .check_aux = cifs_fscache_inode_check_aux, -}; diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 9fa930dfd78d..d44a587a4c32 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -397,6 +397,8 @@ static void cifs_evict_inode(struct inode *inode) { truncate_inode_pages_final(&inode->i_data); + if (inode->i_state & I_PINNING_FSCACHE_WB) + cifs_fscache_unuse_inode_cookie(inode, true); clear_inode(inode); } @@ -1625,13 +1627,9 @@ init_cifs(void) goto out_destroy_cifsoplockd_wq; } - rc = cifs_fscache_register(); - if (rc) - goto out_destroy_deferredclose_wq; - rc = cifs_init_inodecache(); if (rc) - goto out_unreg_fscache; + goto out_destroy_deferredclose_wq; rc = cifs_init_mids(); if (rc) @@ -1693,8 +1691,6 @@ init_cifs(void) cifs_destroy_mids(); out_destroy_inodecache: cifs_destroy_inodecache(); -out_unreg_fscache: - cifs_fscache_unregister(); out_destroy_deferredclose_wq: destroy_workqueue(deferredclose_wq); out_destroy_cifsoplockd_wq: @@ -1730,7 +1726,6 @@ exit_cifs(void) cifs_destroy_request_bufs(); cifs_destroy_mids(); cifs_destroy_inodecache(); - cifs_fscache_unregister(); destroy_workqueue(deferredclose_wq); destroy_workqueue(cifsoplockd_wq); destroy_workqueue(decrypt_wq); diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index e916470468ea..d749250af775 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -653,9 +653,6 @@ struct TCP_Server_Info { unsigned int total_read; /* total amount of data read in this pass */ atomic_t in_send; /* requests trying to send */ atomic_t num_waiters; /* blocked waiting to get in sendrecv */ -#ifdef CONFIG_CIFS_FSCACHE - struct fscache_cookie *fscache; /* client index cache cookie */ -#endif #ifdef CONFIG_CIFS_STATS2 atomic_t num_cmds[NUMBER_OF_SMB2_COMMANDS]; /* total requests by cmd */ atomic_t smb2slowcmd[NUMBER_OF_SMB2_COMMANDS]; /* count resps > 1 sec */ @@ -1084,7 +1081,7 @@ struct cifs_tcon { __u32 max_bytes_copy; #ifdef CONFIG_CIFS_FSCACHE u64 resource_id; /* server resource id */ - struct fscache_cookie *fscache; /* cookie for share */ + struct fscache_volume *fscache; /* cookie for share */ #endif struct list_head pending_opens; /* list of incomplete opens */ struct cached_fid crfid; /* Cached root fid */ diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index c3b94c1e4591..db13e0f8bc4c 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1331,7 +1331,6 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect) spin_unlock(&GlobalMid_Lock); cifs_crypto_secmech_release(server); - cifs_fscache_release_client_cookie(server); kfree(server->session_key.response); server->session_key.response = NULL; @@ -1477,8 +1476,6 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx) list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list); spin_unlock(&cifs_tcp_ses_lock); - cifs_fscache_get_client_cookie(tcp_ses); - /* queue echo request delayed work */ queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 02894e999c56..04c841354077 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -632,7 +632,18 @@ int cifs_open(struct inode *inode, struct file *file) goto out; } - cifs_fscache_set_inode_cookie(inode, file); + + fscache_use_cookie(cifs_inode_cookie(file_inode(file)), + file->f_mode & FMODE_WRITE); + if (file->f_flags & O_DIRECT && + (!((file->f_flags & O_ACCMODE) != O_RDONLY) || + file->f_flags & O_APPEND)) { + struct cifs_fscache_inode_auxdata auxdata; + cifs_fscache_fill_auxdata(file_inode(file), &auxdata); + fscache_invalidate(cifs_inode_cookie(file_inode(file)), + &auxdata, i_size_read(file_inode(file)), + FSCACHE_INVAL_DIO_WRITE); + } if ((oplock & CIFS_CREATE_ACTION) && !posix_open_ok && tcon->unix_ext) { /* @@ -876,6 +887,8 @@ int cifs_close(struct inode *inode, struct file *file) struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_deferred_close *dclose; + cifs_fscache_unuse_inode_cookie(inode, file->f_mode & FMODE_WRITE); + if (file->private_data != NULL) { cfile = file->private_data; file->private_data = NULL; @@ -886,7 +899,6 @@ int cifs_close(struct inode *inode, struct file *file) dclose) { if (test_and_clear_bit(CIFS_INO_MODIFIED_ATTR, &cinode->flags)) { inode->i_ctime = inode->i_mtime = current_time(inode); - cifs_fscache_update_inode_cookie(inode); } spin_lock(&cinode->deferred_lock); cifs_add_deferred_close(cfile, dclose); @@ -4787,14 +4799,14 @@ static int cifs_release_page(struct page *page, gfp_t gfp) return false; wait_on_page_fscache(page); } + fscache_note_page_release(cifs_inode_cookie(page->mapping->host)); return true; } static void cifs_invalidate_page(struct page *page, unsigned int offset, unsigned int length) { - if (offset == 0 && length == PAGE_SIZE) - wait_on_page_fscache(page); + wait_on_page_fscache(page); } static int cifs_launder_page(struct page *page) @@ -4971,6 +4983,19 @@ static void cifs_swap_deactivate(struct file *file) /* do we need to unpin (or unlock) the file */ } +/* + * Mark a page as having been made dirty and thus needing writeback. We also + * need to pin the cache object to write back to. + */ +#ifdef CONFIG_CIFS_FSCACHE +static int cifs_set_page_dirty(struct page *page) +{ + return fscache_set_page_dirty(page, cifs_inode_cookie(page->mapping->host)); +} +#else +#define cifs_set_page_dirty __set_page_dirty_nobuffers +#endif + const struct address_space_operations cifs_addr_ops = { .readpage = cifs_readpage, .readpages = cifs_readpages, @@ -4978,7 +5003,7 @@ const struct address_space_operations cifs_addr_ops = { .writepages = cifs_writepages, .write_begin = cifs_write_begin, .write_end = cifs_write_end, - .set_page_dirty = __set_page_dirty_nobuffers, + .set_page_dirty = cifs_set_page_dirty, .releasepage = cifs_release_page, .direct_IO = cifs_direct_io, .invalidatepage = cifs_invalidate_page, @@ -5003,7 +5028,7 @@ const struct address_space_operations cifs_addr_ops_smallbuf = { .writepages = cifs_writepages, .write_begin = cifs_write_begin, .write_end = cifs_write_end, - .set_page_dirty = __set_page_dirty_nobuffers, + .set_page_dirty = cifs_set_page_dirty, .releasepage = cifs_release_page, .invalidatepage = cifs_invalidate_page, .launder_page = cifs_launder_page, diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c index d6ff668c268a..fa397e734b5c 100644 --- a/fs/cifs/fscache.c +++ b/fs/cifs/fscache.c @@ -12,217 +12,114 @@ #include "cifs_fs_sb.h" #include "cifsproto.h" -/* - * Key layout of CIFS server cache index object - */ -struct cifs_server_key { - struct { - uint16_t family; /* address family */ - __be16 port; /* IP port */ - } hdr; - union { - struct in_addr ipv4_addr; - struct in6_addr ipv6_addr; - }; -} __packed; - -/* - * Get a cookie for a server object keyed by {IPaddress,port,family} tuple - */ -void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) +void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) { - const struct sockaddr *sa = (struct sockaddr *) &server->dstaddr; - const struct sockaddr_in *addr = (struct sockaddr_in *) sa; - const struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) sa; - struct cifs_server_key key; - uint16_t key_len = sizeof(key.hdr); - - memset(&key, 0, sizeof(key)); + struct cifs_fscache_super_auxdata auxdata; + struct TCP_Server_Info *server = tcon->ses->server; + const struct sockaddr *sa = (struct sockaddr *)&server->dstaddr; + size_t slen, i; + char *sharename; + char *key; - /* - * Should not be a problem as sin_family/sin6_family overlays - * sa_family field - */ - key.hdr.family = sa->sa_family; + tcon->fscache = NULL; switch (sa->sa_family) { case AF_INET: - key.hdr.port = addr->sin_port; - key.ipv4_addr = addr->sin_addr; - key_len += sizeof(key.ipv4_addr); - break; - case AF_INET6: - key.hdr.port = addr6->sin6_port; - key.ipv6_addr = addr6->sin6_addr; - key_len += sizeof(key.ipv6_addr); break; - default: cifs_dbg(VFS, "Unknown network family '%d'\n", sa->sa_family); - server->fscache = NULL; return; } - server->fscache = - fscache_acquire_cookie(cifs_fscache_netfs.primary_index, - &cifs_fscache_server_index_def, - &key, key_len, - NULL, 0, - server, 0, true); - cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", - __func__, server, server->fscache); -} - -void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server) -{ - cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", - __func__, server, server->fscache); - fscache_relinquish_cookie(server->fscache, NULL, false); - server->fscache = NULL; -} - -void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) -{ - struct TCP_Server_Info *server = tcon->ses->server; - char *sharename; - struct cifs_fscache_super_auxdata auxdata; - sharename = extract_sharename(tcon->treeName); if (IS_ERR(sharename)) { cifs_dbg(FYI, "%s: couldn't extract sharename\n", __func__); - tcon->fscache = NULL; return; } + slen = strlen(sharename); + for (i = 0; i < slen; i++) + if (sharename[i] == '/') + sharename[i] = ';'; + + key = kasprintf(GFP_KERNEL, "cifs,%pISpc,%s", sa, sharename); + if (!key) + goto out; + memset(&auxdata, 0, sizeof(auxdata)); auxdata.resource_id = tcon->resource_id; auxdata.vol_create_time = tcon->vol_create_time; auxdata.vol_serial_number = tcon->vol_serial_number; + // TODO: Do something with the volume coherency data - tcon->fscache = - fscache_acquire_cookie(server->fscache, - &cifs_fscache_super_index_def, - sharename, strlen(sharename), - &auxdata, sizeof(auxdata), - tcon, 0, true); + tcon->fscache = fscache_acquire_volume(key, + NULL, /* preferred_cache */ + 0 /* coherency_data */); + cifs_dbg(FYI, "%s: (%s/0x%p)\n", __func__, key, tcon->fscache); + + kfree(key); +out: kfree(sharename); - cifs_dbg(FYI, "%s: (0x%p/0x%p)\n", - __func__, server->fscache, tcon->fscache); } void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) { struct cifs_fscache_super_auxdata auxdata; + cifs_dbg(FYI, "%s: (0x%p)\n", __func__, tcon->fscache); + memset(&auxdata, 0, sizeof(auxdata)); auxdata.resource_id = tcon->resource_id; auxdata.vol_create_time = tcon->vol_create_time; auxdata.vol_serial_number = tcon->vol_serial_number; + // TODO: Do something with the volume coherency data - cifs_dbg(FYI, "%s: (0x%p)\n", __func__, tcon->fscache); - fscache_relinquish_cookie(tcon->fscache, &auxdata, false); + fscache_relinquish_volume(tcon->fscache, + 0, /* coherency_data */ + false); tcon->fscache = NULL; } -static void cifs_fscache_acquire_inode_cookie(struct cifsInodeInfo *cifsi, - struct cifs_tcon *tcon) +void cifs_fscache_get_inode_cookie(struct inode *inode) { + struct cifsInodeInfo *cifsi = CIFS_I(inode); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); struct cifs_fscache_inode_auxdata auxdata; - memset(&auxdata, 0, sizeof(auxdata)); - auxdata.eof = cifsi->server_eof; - auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec; - auxdata.last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec; - auxdata.last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec; - auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec; + cifs_fscache_fill_auxdata(&cifsi->vfs_inode, &auxdata); cifsi->fscache = - fscache_acquire_cookie(tcon->fscache, - &cifs_fscache_inode_object_def, + fscache_acquire_cookie(tcon->fscache, 0, &cifsi->uniqueid, sizeof(cifsi->uniqueid), &auxdata, sizeof(auxdata), - cifsi, cifsi->vfs_inode.i_size, true); + cifsi->vfs_inode.i_size); } -static void cifs_fscache_enable_inode_cookie(struct inode *inode) +void cifs_fscache_unuse_inode_cookie(struct inode *inode, bool update) { - struct cifsInodeInfo *cifsi = CIFS_I(inode); - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); - - if (cifsi->fscache) - return; - - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE)) - return; - - cifs_fscache_acquire_inode_cookie(cifsi, tcon); - - cifs_dbg(FYI, "%s: got FH cookie (0x%p/0x%p)\n", - __func__, tcon->fscache, cifsi->fscache); + if (update) { + struct cifs_fscache_inode_auxdata auxdata; + loff_t i_size = i_size_read(inode); + + cifs_fscache_fill_auxdata(inode, &auxdata); + fscache_unuse_cookie(cifs_inode_cookie(inode), &auxdata, &i_size); + } else { + fscache_unuse_cookie(cifs_inode_cookie(inode), NULL, NULL); + } } void cifs_fscache_release_inode_cookie(struct inode *inode) { - struct cifs_fscache_inode_auxdata auxdata; struct cifsInodeInfo *cifsi = CIFS_I(inode); if (cifsi->fscache) { - memset(&auxdata, 0, sizeof(auxdata)); - auxdata.eof = cifsi->server_eof; - auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec; - auxdata.last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec; - auxdata.last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec; - auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec; - cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cifsi->fscache); - /* fscache_relinquish_cookie does not seem to update auxdata */ - fscache_update_cookie(cifsi->fscache, &auxdata); - fscache_relinquish_cookie(cifsi->fscache, &auxdata, false); + fscache_relinquish_cookie(cifsi->fscache, false); cifsi->fscache = NULL; } } -void cifs_fscache_update_inode_cookie(struct inode *inode) -{ - struct cifs_fscache_inode_auxdata auxdata; - struct cifsInodeInfo *cifsi = CIFS_I(inode); - - if (cifsi->fscache) { - memset(&auxdata, 0, sizeof(auxdata)); - auxdata.eof = cifsi->server_eof; - auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec; - auxdata.last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec; - auxdata.last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec; - auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec; - - cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cifsi->fscache); - fscache_update_cookie(cifsi->fscache, &auxdata); - } -} - -void cifs_fscache_set_inode_cookie(struct inode *inode, struct file *filp) -{ - cifs_fscache_enable_inode_cookie(inode); -} - -void cifs_fscache_reset_inode_cookie(struct inode *inode) -{ - struct cifsInodeInfo *cifsi = CIFS_I(inode); - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); - struct fscache_cookie *old = cifsi->fscache; - - if (cifsi->fscache) { - /* retire the current fscache cache and get a new one */ - fscache_relinquish_cookie(cifsi->fscache, NULL, true); - - cifs_fscache_acquire_inode_cookie(cifsi, tcon); - cifs_dbg(FYI, "%s: new cookie 0x%p oldcookie 0x%p\n", - __func__, cifsi->fscache, old); - } -} - /* * Retrieve a page from FS-Cache */ diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h index 081481645b77..886a47a4c409 100644 --- a/fs/cifs/fscache.h +++ b/fs/cifs/fscache.h @@ -33,32 +33,31 @@ struct cifs_fscache_inode_auxdata { u64 last_change_time_sec; u32 last_write_time_nsec; u32 last_change_time_nsec; - u64 eof; }; -/* - * cache.c - */ -extern struct fscache_netfs cifs_fscache_netfs; -extern const struct fscache_cookie_def cifs_fscache_server_index_def; -extern const struct fscache_cookie_def cifs_fscache_super_index_def; -extern const struct fscache_cookie_def cifs_fscache_inode_object_def; - -extern int cifs_fscache_register(void); -extern void cifs_fscache_unregister(void); - /* * fscache.c */ -extern void cifs_fscache_get_client_cookie(struct TCP_Server_Info *); -extern void cifs_fscache_release_client_cookie(struct TCP_Server_Info *); extern void cifs_fscache_get_super_cookie(struct cifs_tcon *); extern void cifs_fscache_release_super_cookie(struct cifs_tcon *); +extern void cifs_fscache_get_inode_cookie(struct inode *); extern void cifs_fscache_release_inode_cookie(struct inode *); -extern void cifs_fscache_update_inode_cookie(struct inode *inode); -extern void cifs_fscache_set_inode_cookie(struct inode *, struct file *); -extern void cifs_fscache_reset_inode_cookie(struct inode *); +extern void cifs_fscache_unuse_inode_cookie(struct inode *, bool); + +static inline +void cifs_fscache_fill_auxdata(struct inode *inode, + struct cifs_fscache_inode_auxdata *auxdata) +{ + struct cifsInodeInfo *cifsi = CIFS_I(inode); + + memset(&auxdata, 0, sizeof(auxdata)); + auxdata->last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec; + auxdata->last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec; + auxdata->last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec; + auxdata->last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec; +} + extern int __cifs_readpage_from_fscache(struct inode *, struct page *); extern void __cifs_readpage_to_fscache(struct inode *, struct page *); @@ -85,23 +84,13 @@ static inline struct fscache_cookie *cifs_inode_cookie(struct inode *inode) } #else /* CONFIG_CIFS_FSCACHE */ -static inline int cifs_fscache_register(void) { return 0; } -static inline void cifs_fscache_unregister(void) {} - -static inline void -cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) {} -static inline void -cifs_fscache_release_client_cookie(struct TCP_Server_Info *server) {} static inline void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) {} -static inline void -cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) {} +static inline void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) {} +static inline void cifs_fscache_get_inode_cookie(struct inode *inode) {} static inline void cifs_fscache_release_inode_cookie(struct inode *inode) {} -static inline void cifs_fscache_update_inode_cookie(struct inode *inode) {} -static inline void cifs_fscache_set_inode_cookie(struct inode *inode, - struct file *filp) {} -static inline void cifs_fscache_reset_inode_cookie(struct inode *inode) {} - +static inline void cifs_fscache_unuse_inode_cookie(struct inode *inode) {} +static inline struct fscache_cookie *cifs_inode_cookie(struct inode *inode) { return NULL; } static inline int cifs_readpage_from_fscache(struct inode *inode, struct page *page) diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 82848412ad85..384d7b8686b1 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1298,10 +1298,7 @@ cifs_iget(struct super_block *sb, struct cifs_fattr *fattr) inode->i_flags |= S_NOATIME | S_NOCMTIME; if (inode->i_state & I_NEW) { inode->i_ino = hash; -#ifdef CONFIG_CIFS_FSCACHE - /* initialize per-inode cache cookie pointer */ - CIFS_I(inode)->fscache = NULL; -#endif + cifs_fscache_get_inode_cookie(inode); unlock_new_inode(inode); } } @@ -2263,6 +2260,8 @@ cifs_dentry_needs_reval(struct dentry *dentry) int cifs_invalidate_mapping(struct inode *inode) { + struct cifs_fscache_inode_auxdata auxdata; + struct cifsInodeInfo *cifsi = CIFS_I(inode); int rc = 0; if (inode->i_mapping && inode->i_mapping->nrpages != 0) { @@ -2272,7 +2271,8 @@ cifs_invalidate_mapping(struct inode *inode) __func__, inode); } - cifs_fscache_reset_inode_cookie(inode); + cifs_fscache_fill_auxdata(&cifsi->vfs_inode, &auxdata); + fscache_invalidate(cifs_inode_cookie(inode), &auxdata, i_size_read(inode), 0); return rc; } @@ -2777,8 +2777,10 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) goto out; if ((attrs->ia_valid & ATTR_SIZE) && - attrs->ia_size != i_size_read(inode)) + attrs->ia_size != i_size_read(inode)) { truncate_setsize(inode, attrs->ia_size); + fscache_resize_cookie(cifs_inode_cookie(inode), attrs->ia_size); + } setattr_copy(&init_user_ns, inode, attrs); mark_inode_dirty(inode); @@ -2973,8 +2975,10 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) goto cifs_setattr_exit; if ((attrs->ia_valid & ATTR_SIZE) && - attrs->ia_size != i_size_read(inode)) + attrs->ia_size != i_size_read(inode)) { truncate_setsize(inode, attrs->ia_size); + fscache_resize_cookie(cifs_inode_cookie(inode), attrs->ia_size); + } setattr_copy(&init_user_ns, inode, attrs); mark_inode_dirty(inode);