From patchwork Thu Feb 17 12:01:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12749933 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D96AAC433FE for ; Thu, 17 Feb 2022 12:02:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230522AbiBQMCQ (ORCPT ); Thu, 17 Feb 2022 07:02:16 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:51668 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240166AbiBQMCP (ORCPT ); Thu, 17 Feb 2022 07:02:15 -0500 Received: from out30-42.freemail.mail.aliyun.com (out30-42.freemail.mail.aliyun.com [115.124.30.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C4CD762D1; Thu, 17 Feb 2022 04:01:59 -0800 (PST) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R111e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04400;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=13;SR=0;TI=SMTPD_---0V4kJNJN_1645099316; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V4kJNJN_1645099316) by smtp.aliyun-inc.com(127.0.0.1); Thu, 17 Feb 2022 20:01:56 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com Cc: xiang@kernel.org, torvalds@linux-foundation.org, gregkh@linuxfoundation.org, willy@infradead.org, linux-fsdevel@vger.kernel.org, joseph.qi@linux.alibaba.com, bo.liu@linux.alibaba.com, tao.peng@linux.alibaba.com, gerry@linux.alibaba.com, eguan@linux.alibaba.com, linux-kernel@vger.kernel.org Subject: [RESEND PATCH v3 1/4] fscache: export fscache_end_operation() Date: Thu, 17 Feb 2022 20:01:51 +0800 Message-Id: <20220217120154.16658-2-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220217120154.16658-1-jefflexu@linux.alibaba.com> References: <20220217120154.16658-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Export fscache_end_operation() to avoid code duplication. Besides, considering the paired fscache_begin_read_operation() is already exported, it shall make sense to also export fscache_end_operation(). Signed-off-by: Jeffle Xu Reviewed-by: Liu Bo --- fs/fscache/internal.h | 11 ----------- fs/nfs/fscache.c | 8 -------- include/linux/fscache.h | 14 ++++++++++++++ 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index f121c21590dc..ed1c9ed737f2 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h @@ -70,17 +70,6 @@ static inline void fscache_see_cookie(struct fscache_cookie *cookie, where); } -/* - * io.c - */ -static inline void fscache_end_operation(struct netfs_cache_resources *cres) -{ - const struct netfs_cache_ops *ops = fscache_operation_valid(cres); - - if (ops) - ops->end_operation(cres); -} - /* * main.c */ diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index cfe901650ab0..39654ca72d3d 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c @@ -249,14 +249,6 @@ void nfs_fscache_release_file(struct inode *inode, struct file *filp) } } -static inline void fscache_end_operation(struct netfs_cache_resources *cres) -{ - const struct netfs_cache_ops *ops = fscache_operation_valid(cres); - - if (ops) - ops->end_operation(cres); -} - /* * Fallback page reading interface. */ diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 296c5f1d9f35..d2430da8aa67 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -456,6 +456,20 @@ int fscache_begin_read_operation(struct netfs_cache_resources *cres, return -ENOBUFS; } +/** + * fscache_end_operation - End the read operation for the netfs lib + * @cres: The cache resources for the read operation + * + * Clean up the resources at the end of the read request. + */ +static inline void fscache_end_operation(struct netfs_cache_resources *cres) +{ + const struct netfs_cache_ops *ops = fscache_operation_valid(cres); + + if (ops) + ops->end_operation(cres); +} + /** * fscache_read - Start a read from the cache. * @cres: The cache resources to use From patchwork Thu Feb 17 12:01:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12749934 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4D023C433EF for ; Thu, 17 Feb 2022 12:02:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240193AbiBQMCR (ORCPT ); Thu, 17 Feb 2022 07:02:17 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:51686 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240184AbiBQMCP (ORCPT ); Thu, 17 Feb 2022 07:02:15 -0500 Received: from out30-42.freemail.mail.aliyun.com (out30-42.freemail.mail.aliyun.com [115.124.30.42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DCB4B60F4; Thu, 17 Feb 2022 04:02:00 -0800 (PST) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R941e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e01424;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=13;SR=0;TI=SMTPD_---0V4keWKf_1645099317; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V4keWKf_1645099317) by smtp.aliyun-inc.com(127.0.0.1); Thu, 17 Feb 2022 20:01:58 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com Cc: xiang@kernel.org, torvalds@linux-foundation.org, gregkh@linuxfoundation.org, willy@infradead.org, linux-fsdevel@vger.kernel.org, joseph.qi@linux.alibaba.com, bo.liu@linux.alibaba.com, tao.peng@linux.alibaba.com, gerry@linux.alibaba.com, eguan@linux.alibaba.com, linux-kernel@vger.kernel.org Subject: [RESEND PATCH v3 2/4] fscache: add a method to support on-demand read semantics Date: Thu, 17 Feb 2022 20:01:52 +0800 Message-Id: <20220217120154.16658-3-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220217120154.16658-1-jefflexu@linux.alibaba.com> References: <20220217120154.16658-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Add .ondemand_read() callback to netfs_cache_ops to implement on-demand read. The precondition for implementing on-demand read semantics is that, all blob files have been placed under corresponding directory with correct file size (sparse files) on the first beginning. When upper fs starts to access the blob file, it will "cache miss" (hit the hole). Then .ondemand_read() callback can be called to notify backend to prepare the data. The implementation of .ondemand_read() callback can be backend specific. The following patch will introduce the implementation for cachefiles, which will notify user daemon the requested file range to read. The .ondemand_read() callback will get blocked until the user daemon has prepared the corresponding data. Then once .ondemand_read() callback returns with 0, it is guaranteed that the requested data has been ready. In this case, users can retry to read from the backing file. Signed-off-by: Jeffle Xu --- Documentation/filesystems/netfs_library.rst | 17 ++++++++++++++ include/linux/fscache.h | 25 +++++++++++++++++++++ include/linux/netfs.h | 4 ++++ 3 files changed, 46 insertions(+) diff --git a/Documentation/filesystems/netfs_library.rst b/Documentation/filesystems/netfs_library.rst index 4f373a8ec47b..075370d4c021 100644 --- a/Documentation/filesystems/netfs_library.rst +++ b/Documentation/filesystems/netfs_library.rst @@ -466,6 +466,8 @@ operation table looks like the following:: int (*query_occupancy)(struct netfs_cache_resources *cres, loff_t start, size_t len, size_t granularity, loff_t *_data_start, size_t *_data_len); + int (*ondemand_read)(struct netfs_cache_resources *cres, + loff_t start_pos, size_t len); }; With a termination handler function pointer:: @@ -552,6 +554,21 @@ The methods defined in the table are: It returns 0 if some data was found, -ENODATA if there was no usable data within the region or -ENOBUFS if there is no caching on this file. + * ``ondemand_read()`` + + [Optional] Called to prepare cache for the requested data. It shall be called + only when on-demand read semantics is required. It will be called when a cache + miss is encountered. The function will make the backend prepare the data + regarding to @start_pos/@len of the cache file. It may get blocked until the + backend finishes getting the requested data or returns errors. + + Once it returns with 0, it is guaranteed that the requested data has been + ready in the cache file. In this case, users can get the data with another + read request. + + It returns 0 if data has been ready in the cache file, or other error code + from the cache, such as -ENOMEM. + Note that these methods are passed a pointer to the cache resource structure, not the read request structure as they could be used in other situations where there isn't a read request structure as well, such as writing dirty data to the diff --git a/include/linux/fscache.h b/include/linux/fscache.h index d2430da8aa67..34af865ba928 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -514,6 +514,31 @@ int fscache_read(struct netfs_cache_resources *cres, term_func, term_func_priv); } +/** + * fscache_ondemand_read - Prepare cache for the requested data. + * @cres: The cache resources to use + * @start_pos: The beginning file offset in the cache file + * @len: The length of the file offset range in the cache file + * + * This shall only be called when a cache miss is encountered. It will make + * the backend prepare the data regarding to @start_pos/@len of the cache file. + * It may get blocked until the backend finishes getting the requested data or + * returns errors. + * + * Returns: + * * 0 - Success (Data is ready in the cache file) + * * Other error code from the cache, such as -ENOMEM. + */ +static inline +int fscache_ondemand_read(struct netfs_cache_resources *cres, + loff_t start_pos, size_t len) +{ + const struct netfs_cache_ops *ops = fscache_operation_valid(cres); + if (ops->ondemand_read) + return ops->ondemand_read(cres, start_pos, len); + return -EOPNOTSUPP; +} + /** * fscache_begin_write_operation - Begin a write operation for the netfs lib * @cres: The cache resources for the write being performed diff --git a/include/linux/netfs.h b/include/linux/netfs.h index 614f22213e21..3d5f0376a326 100644 --- a/include/linux/netfs.h +++ b/include/linux/netfs.h @@ -251,6 +251,10 @@ struct netfs_cache_ops { int (*query_occupancy)(struct netfs_cache_resources *cres, loff_t start, size_t len, size_t granularity, loff_t *_data_start, size_t *_data_len); + + /* Prepare cache for the requested data */ + int (*ondemand_read)(struct netfs_cache_resources *cres, + loff_t start_pos, size_t len); }; struct readahead_control; From patchwork Thu Feb 17 12:01:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12749935 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 35B23C433FE for ; Thu, 17 Feb 2022 12:02:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240198AbiBQMCT (ORCPT ); Thu, 17 Feb 2022 07:02:19 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:51718 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240190AbiBQMCR (ORCPT ); Thu, 17 Feb 2022 07:02:17 -0500 Received: from out30-57.freemail.mail.aliyun.com (out30-57.freemail.mail.aliyun.com [115.124.30.57]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CDFAC60F4; Thu, 17 Feb 2022 04:02:02 -0800 (PST) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R191e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04400;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=13;SR=0;TI=SMTPD_---0V4kVs6e_1645099318; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V4kVs6e_1645099318) by smtp.aliyun-inc.com(127.0.0.1); Thu, 17 Feb 2022 20:01:59 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com Cc: xiang@kernel.org, torvalds@linux-foundation.org, gregkh@linuxfoundation.org, willy@infradead.org, linux-fsdevel@vger.kernel.org, joseph.qi@linux.alibaba.com, bo.liu@linux.alibaba.com, tao.peng@linux.alibaba.com, gerry@linux.alibaba.com, eguan@linux.alibaba.com, linux-kernel@vger.kernel.org Subject: [RESEND PATCH v3 3/4] cachefiles: extract generic function for daemon methods Date: Thu, 17 Feb 2022 20:01:53 +0800 Message-Id: <20220217120154.16658-4-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220217120154.16658-1-jefflexu@linux.alibaba.com> References: <20220217120154.16658-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org ... so that the following new devnode can reuse most of the code when implementing its own methods. Signed-off-by: Jeffle Xu Reviewed-by: Liu Bo --- fs/cachefiles/daemon.c | 70 +++++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c index 7ac04ee2c0a0..6b8d7c5bbe5d 100644 --- a/fs/cachefiles/daemon.c +++ b/fs/cachefiles/daemon.c @@ -78,6 +78,34 @@ static const struct cachefiles_daemon_cmd cachefiles_daemon_cmds[] = { { "", NULL } }; +static struct cachefiles_cache *cachefiles_daemon_open_cache(void) +{ + struct cachefiles_cache *cache; + + /* allocate a cache record */ + cache = kzalloc(sizeof(struct cachefiles_cache), GFP_KERNEL); + if (cache) { + mutex_init(&cache->daemon_mutex); + init_waitqueue_head(&cache->daemon_pollwq); + INIT_LIST_HEAD(&cache->volumes); + INIT_LIST_HEAD(&cache->object_list); + spin_lock_init(&cache->object_list_lock); + + /* set default caching limits + * - limit at 1% free space and/or free files + * - cull below 5% free space and/or free files + * - cease culling above 7% free space and/or free files + */ + cache->frun_percent = 7; + cache->fcull_percent = 5; + cache->fstop_percent = 1; + cache->brun_percent = 7; + cache->bcull_percent = 5; + cache->bstop_percent = 1; + } + + return cache; +} /* * Prepare a cache for caching. @@ -96,31 +124,13 @@ static int cachefiles_daemon_open(struct inode *inode, struct file *file) if (xchg(&cachefiles_open, 1) == 1) return -EBUSY; - /* allocate a cache record */ - cache = kzalloc(sizeof(struct cachefiles_cache), GFP_KERNEL); + + cache = cachefiles_daemon_open_cache(); if (!cache) { cachefiles_open = 0; return -ENOMEM; } - mutex_init(&cache->daemon_mutex); - init_waitqueue_head(&cache->daemon_pollwq); - INIT_LIST_HEAD(&cache->volumes); - INIT_LIST_HEAD(&cache->object_list); - spin_lock_init(&cache->object_list_lock); - - /* set default caching limits - * - limit at 1% free space and/or free files - * - cull below 5% free space and/or free files - * - cease culling above 7% free space and/or free files - */ - cache->frun_percent = 7; - cache->fcull_percent = 5; - cache->fstop_percent = 1; - cache->brun_percent = 7; - cache->bcull_percent = 5; - cache->bstop_percent = 1; - file->private_data = cache; cache->cachefilesd = file; return 0; @@ -209,10 +219,11 @@ static ssize_t cachefiles_daemon_read(struct file *file, char __user *_buffer, /* * Take a command from cachefilesd, parse it and act on it. */ -static ssize_t cachefiles_daemon_write(struct file *file, - const char __user *_data, - size_t datalen, - loff_t *pos) +static ssize_t cachefiles_daemon_do_write(struct file *file, + const char __user *_data, + size_t datalen, + loff_t *pos, + const struct cachefiles_daemon_cmd *cmds) { const struct cachefiles_daemon_cmd *cmd; struct cachefiles_cache *cache = file->private_data; @@ -261,7 +272,7 @@ static ssize_t cachefiles_daemon_write(struct file *file, } /* run the appropriate command handler */ - for (cmd = cachefiles_daemon_cmds; cmd->name[0]; cmd++) + for (cmd = cmds; cmd->name[0]; cmd++) if (strcmp(cmd->name, data) == 0) goto found_command; @@ -284,6 +295,15 @@ static ssize_t cachefiles_daemon_write(struct file *file, goto error; } +static ssize_t cachefiles_daemon_write(struct file *file, + const char __user *_data, + size_t datalen, + loff_t *pos) +{ + return cachefiles_daemon_do_write(file, _data, datalen, pos, + cachefiles_daemon_cmds); +} + /* * Poll for culling state * - use EPOLLOUT to indicate culling state From patchwork Thu Feb 17 12:01:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12749936 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6E574C433EF for ; Thu, 17 Feb 2022 12:02:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240215AbiBQMC0 (ORCPT ); Thu, 17 Feb 2022 07:02:26 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:51756 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240189AbiBQMCS (ORCPT ); Thu, 17 Feb 2022 07:02:18 -0500 Received: from out30-132.freemail.mail.aliyun.com (out30-132.freemail.mail.aliyun.com [115.124.30.132]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F121C62D1; Thu, 17 Feb 2022 04:02:03 -0800 (PST) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R361e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04394;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=13;SR=0;TI=SMTPD_---0V4keWL7_1645099319; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V4keWL7_1645099319) by smtp.aliyun-inc.com(127.0.0.1); Thu, 17 Feb 2022 20:02:00 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com Cc: xiang@kernel.org, torvalds@linux-foundation.org, gregkh@linuxfoundation.org, willy@infradead.org, linux-fsdevel@vger.kernel.org, joseph.qi@linux.alibaba.com, bo.liu@linux.alibaba.com, tao.peng@linux.alibaba.com, gerry@linux.alibaba.com, eguan@linux.alibaba.com, linux-kernel@vger.kernel.org Subject: [RESEND PATCH v3 4/4] cachefiles: detect backing file size in on-demand read mode Date: Thu, 17 Feb 2022 20:01:54 +0800 Message-Id: <20220217120154.16658-5-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220217120154.16658-1-jefflexu@linux.alibaba.com> References: <20220217120154.16658-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Fscache/cachefiles used to serve as a local cache for remote fs. The following patches will introduce a new use case, in which local read-only fs could implement on-demand reading with fscache. Then in this case, the upper read-only fs may has no idea on the size of the backed file. It is worth nothing that, in this scenario, user daemon is responsible for preparing all backing files with correct file size in the first beginning. (Backing files are all sparse files in this case). And since it's read-only, we can get the backing file size at runtime as the object size. This patch also adds one flag bit to distinguish the new introduced on-demand read mode from the original mode. The following patch will introduce a user configures it. Signed-off-by: Jeffle Xu --- fs/cachefiles/Kconfig | 13 +++++++++ fs/cachefiles/internal.h | 1 + fs/cachefiles/namei.c | 60 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/fs/cachefiles/Kconfig b/fs/cachefiles/Kconfig index 719faeeda168..cef412cfd127 100644 --- a/fs/cachefiles/Kconfig +++ b/fs/cachefiles/Kconfig @@ -26,3 +26,16 @@ config CACHEFILES_ERROR_INJECTION help This permits error injection to be enabled in cachefiles whilst a cache is in service. + +config CACHEFILES_ONDEMAND + bool "Support for on-demand reading" + depends on CACHEFILES + default n + help + This permits on-demand read mode of cachefiles. In this mode, when + cache miss, the cachefiles backend instead of the upper fs using + fscache is responsible for fetching data, e.g. through user daemon. + Then after the data's ready, upper fs can reinitiate a read from the + cache. + + If unsure, say N. diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index c793d33b0224..6473634c41a9 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -98,6 +98,7 @@ struct cachefiles_cache { #define CACHEFILES_DEAD 1 /* T if cache dead */ #define CACHEFILES_CULLING 2 /* T if cull engaged */ #define CACHEFILES_STATE_CHANGED 3 /* T if state changed (poll trigger) */ +#define CACHEFILES_ONDEMAND_MODE 4 /* T if in on-demand read mode */ char *rootdirname; /* name of cache root directory */ char *secctx; /* LSM security context */ char *tag; /* cache binding tag */ diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index f256c8aff7bb..abe75b4b955f 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -510,15 +510,69 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object) return file; } +#ifdef CONFIG_CACHEFILES_ONDEMAND +static inline bool cachefiles_can_create_file(struct cachefiles_cache *cache) +{ + /* + * On-demand read mode requires that backing files have been prepared + * with correct file size under corresponding directory in the very + * first begginning. We can get here when the backing file doesn't exist + * under corresponding directory, or the file size is unexpected 0. + */ + return !test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags); + +} + +/* + * Fs using fscache for on-demand reading may have no idea of the file size of + * backing files. Thus the on-demand read mode requires that backing files shall + * be prepared with correct file size under corresponding directory by the user + * daemon in the first beginning. Then the backend is responsible for taking the + * file size of the backing file as the object size at runtime. + */ +static int cachefiles_recheck_size(struct cachefiles_object *object, + struct file *file) +{ + loff_t size; + struct cachefiles_cache *cache = object->volume->cache; + + if (!test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags)) + return 0; + + size = i_size_read(file_inode(file)); + if (!size) + return -EINVAL; + + object->cookie->object_size = size; + return 0; +} +#else +static inline bool cachefiles_can_create_file(struct cachefiles_cache *cache) +{ + return true; +} + +static inline int cachefiles_recheck_size(struct cachefiles_object *object, + struct file *file) +{ + return 0; +} +#endif + + /* * Create a new file. */ static bool cachefiles_create_file(struct cachefiles_object *object) { + struct cachefiles_cache *cache = object->volume->cache; struct file *file; int ret; - ret = cachefiles_has_space(object->volume->cache, 1, 0, + if (!cachefiles_can_create_file(cache)) + return false; + + ret = cachefiles_has_space(cache, 1, 0, cachefiles_has_space_for_create); if (ret < 0) return false; @@ -573,6 +627,10 @@ static bool cachefiles_open_file(struct cachefiles_object *object, } _debug("file -> %pd positive", dentry); + ret = cachefiles_recheck_size(object, file); + if (ret < 0) + goto check_failed; + ret = cachefiles_check_auxdata(object, file); if (ret < 0) goto check_failed;