From patchwork Fri Mar 25 12:22:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791536 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 3585BC433EF for ; Fri, 25 Mar 2022 12:22:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1358959AbiCYMYH (ORCPT ); Fri, 25 Mar 2022 08:24:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38168 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1358958AbiCYMYH (ORCPT ); Fri, 25 Mar 2022 08:24:07 -0400 Received: from out199-6.us.a.mail.aliyun.com (out199-6.us.a.mail.aliyun.com [47.90.199.6]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4484DD447A; Fri, 25 Mar 2022 05:22:31 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R121e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04426;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=18;SR=0;TI=SMTPD_---0V89zY0V_1648210945; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89zY0V_1648210945) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:26 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 01/22] fscache: export fscache_end_operation() Date: Fri, 25 Mar 2022 20:22:02 +0800 Message-Id: <20220325122223.102958-2-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-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 Fri Mar 25 12:22:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791535 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 970C7C433F5 for ; Fri, 25 Mar 2022 12:22:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1358953AbiCYMYH (ORCPT ); Fri, 25 Mar 2022 08:24:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38158 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352849AbiCYMYG (ORCPT ); Fri, 25 Mar 2022 08:24:06 -0400 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 083E8D4479; Fri, 25 Mar 2022 05:22:31 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R161e4;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=18;SR=0;TI=SMTPD_---0V89qQzr_1648210947; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89qQzr_1648210947) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:28 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 02/22] cachefiles: extract write routine Date: Fri, 25 Mar 2022 20:22:03 +0800 Message-Id: <20220325122223.102958-3-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Extract the generic routine of writing data to cache files, and make it generally available. This will be used by the following patch implementing on-demand read mode. Since it's called inside cachefiles module in this case, make the interface generic and unrelated to netfs_cache_resources. It is worth nothing that, ki->inval_counter is not initialized after this cleanup. It shall not make any visible difference, since inval_counter is no longer used in the write completion routine, i.e. cachefiles_write_complete(). Signed-off-by: Jeffle Xu --- fs/cachefiles/internal.h | 10 +++++++ fs/cachefiles/io.c | 61 +++++++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index c793d33b0224..e80673d0ab97 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -201,6 +201,16 @@ extern void cachefiles_put_object(struct cachefiles_object *object, */ extern bool cachefiles_begin_operation(struct netfs_cache_resources *cres, enum fscache_want_state want_state); +extern int __cachefiles_prepare_write(struct cachefiles_object *object, + struct file *file, + loff_t *_start, size_t *_len, + bool no_space_allocated_yet); +extern int __cachefiles_write(struct cachefiles_object *object, + struct file *file, + loff_t start_pos, + struct iov_iter *iter, + netfs_io_terminated_t term_func, + void *term_func_priv); /* * key.c diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index 753986ea1583..8dbc1eb254a3 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -278,36 +278,33 @@ static void cachefiles_write_complete(struct kiocb *iocb, long ret) /* * Initiate a write to the cache. */ -static int cachefiles_write(struct netfs_cache_resources *cres, - loff_t start_pos, - struct iov_iter *iter, - netfs_io_terminated_t term_func, - void *term_func_priv) +int __cachefiles_write(struct cachefiles_object *object, + struct file *file, + loff_t start_pos, + struct iov_iter *iter, + netfs_io_terminated_t term_func, + void *term_func_priv) { - struct cachefiles_object *object; struct cachefiles_cache *cache; struct cachefiles_kiocb *ki; struct inode *inode; - struct file *file; unsigned int old_nofs; - ssize_t ret = -ENOBUFS; + ssize_t ret; size_t len = iov_iter_count(iter); - if (!fscache_wait_for_operation(cres, FSCACHE_WANT_WRITE)) - goto presubmission_error; fscache_count_write(); - object = cachefiles_cres_object(cres); cache = object->volume->cache; - file = cachefiles_cres_file(cres); _enter("%pD,%li,%llx,%zx/%llx", file, file_inode(file)->i_ino, start_pos, len, i_size_read(file_inode(file))); - ret = -ENOMEM; ki = kzalloc(sizeof(struct cachefiles_kiocb), GFP_KERNEL); - if (!ki) - goto presubmission_error; + if (!ki) { + if (term_func) + term_func(term_func_priv, -ENOMEM, false); + return -ENOMEM; + } refcount_set(&ki->ki_refcnt, 2); ki->iocb.ki_filp = file; @@ -316,7 +313,6 @@ 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 = cres->inval_counter; ki->start = start_pos; ki->len = len; ki->term_func = term_func; @@ -371,11 +367,24 @@ static int cachefiles_write(struct netfs_cache_resources *cres, cachefiles_put_kiocb(ki); _leave(" = %zd", ret); return ret; +} -presubmission_error: - if (term_func) - term_func(term_func_priv, ret, false); - return ret; +static int cachefiles_write(struct netfs_cache_resources *cres, + loff_t start_pos, + struct iov_iter *iter, + netfs_io_terminated_t term_func, + void *term_func_priv) +{ + if (!fscache_wait_for_operation(cres, FSCACHE_WANT_WRITE)) { + if (term_func) + term_func(term_func_priv, -ENOBUFS, false); + return -ENOBUFS; + } + + return __cachefiles_write(cachefiles_cres_object(cres), + cachefiles_cres_file(cres), + start_pos, iter, + term_func, term_func_priv); } /* @@ -486,13 +495,12 @@ 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, - bool no_space_allocated_yet) +int __cachefiles_prepare_write(struct cachefiles_object *object, + struct file *file, + loff_t *_start, size_t *_len, + bool no_space_allocated_yet) { - 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; @@ -579,7 +587,8 @@ static int cachefiles_prepare_write(struct netfs_cache_resources *cres, } cachefiles_begin_secure(cache, &saved_cred); - ret = __cachefiles_prepare_write(cres, _start, _len, i_size, + ret = __cachefiles_prepare_write(object, cachefiles_cres_file(cres), + _start, _len, no_space_allocated_yet); cachefiles_end_secure(cache, saved_cred); return ret; From patchwork Fri Mar 25 12:22:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791539 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 6ACA2C433F5 for ; Fri, 25 Mar 2022 12:22:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1358984AbiCYMYM (ORCPT ); Fri, 25 Mar 2022 08:24:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38224 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1358973AbiCYMYJ (ORCPT ); Fri, 25 Mar 2022 08:24:09 -0400 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 03F05CC527; Fri, 25 Mar 2022 05:22:33 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R101e4;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=18;SR=0;TI=SMTPD_---0V89aFqx_1648210948; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89aFqx_1648210948) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:29 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 03/22] cachefiles: notify user daemon with anon_fd when looking up cookie Date: Fri, 25 Mar 2022 20:22:04 +0800 Message-Id: <20220325122223.102958-4-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-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. This patch, along with the following patches, introduces a new on-demand read mode for cachefiles, which can boost the scenario where on-demand read semantics is needed, e.g. container image distribution. The essential difference between the original mode and on-demand read mode is that, in the original mode, when cache miss, netfs itself will fetch data from remote, and then write the fetched data into cache file. While in on-demand read mode, a user daemon is responsible for fetching data and then writing to the cache file. As the first step, notify user daemon with anon_fd when looking up cookie. Send the anonymous fd to user daemon when looking up cookie, no matter whether the cache file exist there or not. With the given anonymous fd, user daemon can fetch and then write data into cache file in advance, even when cache miss has not happended yet. Also add one advisory flag (FSCACHE_ADV_WANT_CACHE_SIZE) suggesting that cache file size shall be retrieved at runtime. This helps the scenario where one cache file can contain multiple netfs files for the purpose of deduplication, e.g. In this case, netfs itself has no idea the cache file size, whilst user daemon needs to offer the hint on the cache file size. Signed-off-by: Jeffle Xu Reported-by: kernel test robot Reported-by: kernel test robot --- fs/cachefiles/Kconfig | 11 + fs/cachefiles/Makefile | 1 + fs/cachefiles/daemon.c | 76 ++++++- fs/cachefiles/internal.h | 44 ++++ fs/cachefiles/namei.c | 16 +- fs/cachefiles/ondemand.c | 348 ++++++++++++++++++++++++++++++ include/linux/fscache.h | 1 + include/trace/events/cachefiles.h | 2 + include/uapi/linux/cachefiles.h | 43 ++++ 9 files changed, 529 insertions(+), 13 deletions(-) create mode 100644 fs/cachefiles/ondemand.c create mode 100644 include/uapi/linux/cachefiles.h diff --git a/fs/cachefiles/Kconfig b/fs/cachefiles/Kconfig index 719faeeda168..58aad1fb4c5c 100644 --- a/fs/cachefiles/Kconfig +++ b/fs/cachefiles/Kconfig @@ -26,3 +26,14 @@ 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 read" + 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 netfs, is responsible + for fetching data, e.g. through user daemon. + + If unsure, say N. diff --git a/fs/cachefiles/Makefile b/fs/cachefiles/Makefile index 16d811f1a2fa..c37a7a9af10b 100644 --- a/fs/cachefiles/Makefile +++ b/fs/cachefiles/Makefile @@ -16,5 +16,6 @@ cachefiles-y := \ xattr.o cachefiles-$(CONFIG_CACHEFILES_ERROR_INJECTION) += error_inject.o +cachefiles-$(CONFIG_CACHEFILES_ONDEMAND) += ondemand.o obj-$(CONFIG_CACHEFILES) := cachefiles.o diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c index 7ac04ee2c0a0..91b88a499737 100644 --- a/fs/cachefiles/daemon.c +++ b/fs/cachefiles/daemon.c @@ -75,6 +75,9 @@ static const struct cachefiles_daemon_cmd cachefiles_daemon_cmds[] = { { "inuse", cachefiles_daemon_inuse }, { "secctx", cachefiles_daemon_secctx }, { "tag", cachefiles_daemon_tag }, +#ifdef CONFIG_CACHEFILES_ONDEMAND + { "cinit", cachefiles_ondemand_cinit }, +#endif { "", NULL } }; @@ -108,6 +111,9 @@ static int cachefiles_daemon_open(struct inode *inode, struct file *file) INIT_LIST_HEAD(&cache->volumes); INIT_LIST_HEAD(&cache->object_list); spin_lock_init(&cache->object_list_lock); +#ifdef CONFIG_CACHEFILES_ONDEMAND + xa_init_flags(&cache->reqs, XA_FLAGS_ALLOC); +#endif /* set default caching limits * - limit at 1% free space and/or free files @@ -126,6 +132,27 @@ static int cachefiles_daemon_open(struct inode *inode, struct file *file) return 0; } +#ifdef CONFIG_CACHEFILES_ONDEMAND +static inline void cachefiles_flush_reqs(struct cachefiles_cache *cache) +{ + struct xarray *xa = &cache->reqs; + struct cachefiles_req *req; + unsigned long index; + + /* + * 1) Cache has been marked as dead state, and then 2) flush all + * pending requests in @reqs xarray. The barrier inside set_bit() + * will ensure that above two ops won't be reordered. + */ + xa_lock(xa); + xa_for_each(xa, index, req) { + req->error = -EIO; + complete(&req->done); + } + xa_unlock(xa); +} +#endif + /* * Release a cache. */ @@ -139,6 +166,11 @@ static int cachefiles_daemon_release(struct inode *inode, struct file *file) set_bit(CACHEFILES_DEAD, &cache->flags); +#ifdef CONFIG_CACHEFILES_ONDEMAND + cachefiles_flush_reqs(cache); + xa_destroy(&cache->reqs); +#endif + cachefiles_daemon_unbind(cache); /* clean up the control file interface */ @@ -152,23 +184,15 @@ static int cachefiles_daemon_release(struct inode *inode, struct file *file) return 0; } -/* - * Read the cache state. - */ -static ssize_t cachefiles_daemon_read(struct file *file, char __user *_buffer, - size_t buflen, loff_t *pos) +static ssize_t cachefiles_do_daemon_read(struct cachefiles_cache *cache, + char __user *_buffer, + size_t buflen) { - struct cachefiles_cache *cache = file->private_data; unsigned long long b_released; unsigned f_released; char buffer[256]; int n; - //_enter(",,%zu,", buflen); - - if (!test_bit(CACHEFILES_READY, &cache->flags)) - return 0; - /* check how much space the cache has */ cachefiles_has_space(cache, 0, 0, cachefiles_has_space_check); @@ -206,6 +230,26 @@ static ssize_t cachefiles_daemon_read(struct file *file, char __user *_buffer, return n; } +/* + * Read the cache state. + */ +static ssize_t cachefiles_daemon_read(struct file *file, char __user *_buffer, + size_t buflen, loff_t *pos) +{ + struct cachefiles_cache *cache = file->private_data; + + //_enter(",,%zu,", buflen); + + if (!test_bit(CACHEFILES_READY, &cache->flags)) + return 0; + + if (IS_ENABLED(CONFIG_CACHEFILES_ONDEMAND) && + test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags)) + return cachefiles_ondemand_daemon_read(cache, _buffer, buflen); + else + return cachefiles_do_daemon_read(cache, _buffer, buflen); +} + /* * Take a command from cachefilesd, parse it and act on it. */ @@ -297,8 +341,18 @@ static __poll_t cachefiles_daemon_poll(struct file *file, poll_wait(file, &cache->daemon_pollwq, poll); mask = 0; +#ifdef CONFIG_CACHEFILES_ONDEMAND + if (test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags)) { + if (!xa_empty(&cache->reqs)) + mask |= EPOLLIN; + } else { + if (test_bit(CACHEFILES_STATE_CHANGED, &cache->flags)) + mask |= EPOLLIN; + } +#else if (test_bit(CACHEFILES_STATE_CHANGED, &cache->flags)) mask |= EPOLLIN; +#endif if (test_bit(CACHEFILES_CULLING, &cache->flags)) mask |= EPOLLOUT; diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index e80673d0ab97..8a0f1b691aca 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -15,6 +15,8 @@ #include #include #include +#include +#include #define CACHEFILES_DIO_BLOCK_SIZE 4096 @@ -58,6 +60,9 @@ struct cachefiles_object { enum cachefiles_content content_info:8; /* Info about content presence */ unsigned long flags; #define CACHEFILES_OBJECT_USING_TMPFILE 0 /* Have an unlinked tmpfile */ +#ifdef CONFIG_CACHEFILES_ONDEMAND + int fd; /* anonymous fd */ +#endif }; /* @@ -98,11 +103,24 @@ 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 */ +#ifdef CONFIG_CACHEFILES_ONDEMAND + struct xarray reqs; /* xarray of pending on-demand requests */ +#endif }; +struct cachefiles_req { + struct cachefiles_object *object; + struct completion done; + int error; + struct cachefiles_msg msg; +}; + +#define CACHEFILES_REQ_NEW XA_MARK_1 + #include static inline @@ -250,6 +268,32 @@ extern struct file *cachefiles_create_tmpfile(struct cachefiles_object *object); extern bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache, struct cachefiles_object *object); +/* + * ondemand.c + */ +#ifdef CONFIG_CACHEFILES_ONDEMAND +extern ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache, + char __user *_buffer, + size_t buflen); + +extern int cachefiles_ondemand_cinit(struct cachefiles_cache *cache, + char *args); + +extern int cachefiles_ondemand_init_object(struct cachefiles_object *object); + +#else +ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache, + char __user *_buffer, size_t buflen) +{ + return -EOPNOTSUPP; +} + +static inline int cachefiles_ondemand_init_object(struct cachefiles_object *object) +{ + return 0; +} +#endif + /* * security.c */ diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index f256c8aff7bb..22aba4c6a762 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -444,10 +444,9 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object) struct dentry *fan = volume->fanout[(u8)object->cookie->key_hash]; struct file *file; struct path path; - uint64_t ni_size = object->cookie->object_size; + uint64_t ni_size; long ret; - ni_size = round_up(ni_size, CACHEFILES_DIO_BLOCK_SIZE); cachefiles_begin_secure(cache, &saved_cred); @@ -473,6 +472,15 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object) goto out_dput; } + ret = cachefiles_ondemand_init_object(object); + if (ret < 0) { + file = ERR_PTR(ret); + goto out_dput; + } + + ni_size = object->cookie->object_size; + ni_size = round_up(ni_size, CACHEFILES_DIO_BLOCK_SIZE); + if (ni_size > 0) { trace_cachefiles_trunc(object, d_backing_inode(path.dentry), 0, ni_size, cachefiles_trunc_expand_tmpfile); @@ -573,6 +581,10 @@ static bool cachefiles_open_file(struct cachefiles_object *object, } _debug("file -> %pd positive", dentry); + ret = cachefiles_ondemand_init_object(object); + if (ret < 0) + goto error_fput; + ret = cachefiles_check_auxdata(object, file); if (ret < 0) goto check_failed; diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c new file mode 100644 index 000000000000..0742c4a7797a --- /dev/null +++ b/fs/cachefiles/ondemand.c @@ -0,0 +1,348 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2022, Alibaba Cloud + */ +#include +#include +#include +#include "internal.h" + +static int cachefiles_ondemand_fd_release(struct inode *inode, + struct file *file) +{ + struct cachefiles_object *object = file->private_data; + + /* + * Uninstall anon_fd to the cachefiles object, so that no further + * associated requests will get enqueued. + */ + object->fd = -1; + + cachefiles_put_object(object, cachefiles_obj_put_ondemand_fd); + return 0; +} + +static ssize_t cachefiles_ondemand_fd_write_iter(struct kiocb *kiocb, + struct iov_iter *iter) +{ + struct cachefiles_object *object = kiocb->ki_filp->private_data; + struct cachefiles_cache *cache = object->volume->cache; + struct file *file = object->file; + size_t len = iter->count; + loff_t pos = kiocb->ki_pos; + const struct cred *saved_cred; + int ret; + + if (!file) + return -ENOBUFS; + + cachefiles_begin_secure(cache, &saved_cred); + ret = __cachefiles_prepare_write(object, file, &pos, &len, true); + cachefiles_end_secure(cache, saved_cred); + if (ret < 0) + return ret; + + ret = __cachefiles_write(object, file, pos, iter, NULL, NULL); + if (!ret) + ret = len; + + return ret; +} + +static loff_t cachefiles_ondemand_fd_llseek(struct file *filp, loff_t pos, int whence) +{ + struct cachefiles_object *object = filp->private_data; + struct file *file = object->file; + + if (!file) + return -ENOBUFS; + + return vfs_llseek(file, pos, whence); +} + +static const struct file_operations cachefiles_ondemand_fd_fops = { + .owner = THIS_MODULE, + .release = cachefiles_ondemand_fd_release, + .write_iter = cachefiles_ondemand_fd_write_iter, + .llseek = cachefiles_ondemand_fd_llseek, +}; + +/* + * Init request completion + * - command: "cinit [,]" + */ +int cachefiles_ondemand_cinit(struct cachefiles_cache *cache, char *args) +{ + struct cachefiles_req *req; + struct cachefiles_open *load; + struct fscache_cookie *cookie; + char *pid, *psize; + unsigned long id, flags, size = 0; + int ret; + + if (!test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags)) + return -EOPNOTSUPP; + + if (!*args) { + pr_err("Empty id specified\n"); + return -EINVAL; + } + + pid = args; + psize = strchr(args, ','); + if (psize) { + *psize = 0; + psize++; + + ret = kstrtoul(psize, 0, &size); + if (ret) + return ret; + } + + ret = kstrtoul(pid, 0, &id); + if (ret) + return ret; + + req = xa_erase(&cache->reqs, id); + if (!req) + return -EINVAL; + + load = (void *)req->msg.data; + flags = load->flags; + + if (test_bit(CACHEFILES_OPEN_WANT_CACHE_SIZE, &flags)) { + if (size) { + cookie = req->object->cookie; + cookie->object_size = size; + clear_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags); + } else { + req->error = -EINVAL; + } + } + + complete(&req->done); + return 0; +} + +static int cachefiles_ondemand_get_fd(struct cachefiles_req *req) +{ + struct cachefiles_object *object; + struct cachefiles_open *load; + struct fd f; + int ret; + + object = cachefiles_grab_object(req->object, + cachefiles_obj_get_ondemand_fd); + + ret = anon_inode_getfd("[cachefiles]", &cachefiles_ondemand_fd_fops, + object, O_WRONLY); + if (ret < 0) { + cachefiles_put_object(object, cachefiles_obj_put_ondemand_fd); + return ret; + } + + f = fdget_pos(ret); + if (WARN_ON_ONCE(!f.file)) + return -EBADFD; + + f.file->f_mode |= FMODE_PWRITE | FMODE_LSEEK; + fdput_pos(f); + + load = (void *)req->msg.data; + load->fd = object->fd = ret; + + return 0; +} + +ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache, + char __user *_buffer, size_t buflen) +{ + struct cachefiles_req *req; + struct cachefiles_msg *msg; + unsigned long id = 0; + size_t n; + int ret = 0; + XA_STATE(xas, &cache->reqs, 0); + + /* + * Search for request that has not ever been processed, to prevent + * requests from being sent to user daemon repeatedly. + */ + xa_lock(&cache->reqs); + req = xas_find_marked(&xas, UINT_MAX, CACHEFILES_REQ_NEW); + if (!req) { + xa_unlock(&cache->reqs); + return 0; + } + + msg = &req->msg; + n = msg->len; + + if (n > buflen) { + xa_unlock(&cache->reqs); + return -EMSGSIZE; + } + + xas_clear_mark(&xas, CACHEFILES_REQ_NEW); + xa_unlock(&cache->reqs); + + msg->id = id = xas.xa_index; + + if (msg->opcode == CACHEFILES_OP_OPEN) { + ret = cachefiles_ondemand_get_fd(req); + if (ret) + goto error; + } + + if (copy_to_user(_buffer, msg, n) != 0) { + ret = -EFAULT; + goto err_put_fd; + } + + return n; + +err_put_fd: + if (msg->opcode == CACHEFILES_OP_OPEN) + close_fd(req->object->fd); +error: + xa_erase(&cache->reqs, id); + req->error = ret; + complete(&req->done); + return ret; +} + +typedef int (*init_req_fn)(struct cachefiles_req *req, void *private); + +static int cachefiles_ondemand_send_req(struct cachefiles_object *object, + enum cachefiles_opcode opcode, + size_t data_len, + init_req_fn init_req, + void *private) +{ + struct cachefiles_cache *cache = object->volume->cache; + struct cachefiles_req *req; + XA_STATE(xas, &cache->reqs, 0); + int ret; + + if (!test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags)) + return -EOPNOTSUPP; + + if (test_bit(CACHEFILES_DEAD, &cache->flags)) + return -EIO; + + req = kzalloc(sizeof(*req) + data_len, GFP_KERNEL); + if (!req) + return -ENOMEM; + + req->object = object; + init_completion(&req->done); + req->msg.opcode = opcode; + req->msg.len = sizeof(struct cachefiles_msg) + data_len; + + ret = init_req(req, private); + if (ret) + goto out; + + do { + /* + * Stop enqueuing the request when daemon is dying. So we need + * to 1) check cache state, and 2) enqueue request if cache is + * alive. + * + * These two ops need to be atomic as a whole. Otherwise request + * may be enqueued after xarray has been flushed, in which case + * the orphan request will never be completed and thus netfs + * will hang there forever. + */ + xas_lock(&xas); + + /* recheck dead state with lock held */ + if (test_bit(CACHEFILES_DEAD, &cache->flags)) { + xas_unlock(&xas); + ret = -EIO; + goto out; + } + + xas.xa_index = 0; + xas_find_marked(&xas, UINT_MAX, XA_FREE_MARK); + if (xas.xa_node == XAS_RESTART) + xas_set_err(&xas, -EBUSY); + xas_store(&xas, req); + xas_clear_mark(&xas, XA_FREE_MARK); + xas_set_mark(&xas, CACHEFILES_REQ_NEW); + xas_unlock(&xas); + } while (xas_nomem(&xas, GFP_KERNEL)); + + ret = xas_error(&xas); + if (ret) + goto out; + + wake_up_all(&cache->daemon_pollwq); + wait_for_completion(&req->done); + ret = req->error; +out: + kfree(req); + return ret; +} + +static int init_open_req(struct cachefiles_req *req, void *private) +{ + struct cachefiles_object *object = req->object; + struct fscache_cookie *cookie = object->cookie; + struct fscache_volume *volume = object->volume->vcookie; + struct cachefiles_open *load = (void *)req->msg.data; + size_t volume_key_len, cookie_key_len; + void *volume_key, *cookie_key; + unsigned long flags = 0; + + /* + * Volume key is of string format. + * key[0] stores strlen() of the string, while the remained part stores + * the content of the string (excluding the suffix '\0'). Append the + * suffix '\0' to the output volume_key, so that it's a valid string. + */ + volume_key_len = volume->key[0] + 1; + volume_key = volume->key + 1; + + /* + * Cookie key is of binary format, which is netfs specific. + */ + cookie_key_len = cookie->key_len; + cookie_key = fscache_get_key(cookie); + + if (object->cookie->advice & FSCACHE_ADV_WANT_CACHE_SIZE) + __set_bit(CACHEFILES_OPEN_WANT_CACHE_SIZE, &flags); + + load->flags = flags; + load->volume_key_len = volume_key_len; + load->cookie_key_len = cookie_key_len; + memcpy(load->data, volume_key, volume_key_len); + memcpy(load->data + volume_key_len, cookie_key, cookie_key_len); + + return 0; +} + +int cachefiles_ondemand_init_object(struct cachefiles_object *object) +{ + struct fscache_cookie *cookie = object->cookie; + struct fscache_volume *volume = object->volume->vcookie; + size_t volume_key_len, cookie_key_len, data_len; + + /* + * Cachefiles will firstly check cache file under the root cache + * directory. If coherency check failed, it will fallback to creating a + * new tmpfile as the cache file. Reuse the previously created anon_fd + * if any. + */ + if (object->fd > 0) + return 0; + + volume_key_len = volume->key[0] + 1; + cookie_key_len = cookie->key_len; + data_len = sizeof(struct cachefiles_open) + + volume_key_len + cookie_key_len; + + return cachefiles_ondemand_send_req(object, + CACHEFILES_OP_OPEN, data_len, + init_open_req, NULL); +} diff --git a/include/linux/fscache.h b/include/linux/fscache.h index d2430da8aa67..a330354f33ca 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h @@ -39,6 +39,7 @@ struct fscache_cookie; #define FSCACHE_ADV_SINGLE_CHUNK 0x01 /* The object is a single chunk of data */ #define FSCACHE_ADV_WRITE_CACHE 0x00 /* Do cache if written to locally */ #define FSCACHE_ADV_WRITE_NOCACHE 0x02 /* Don't cache if written to locally */ +#define FSCACHE_ADV_WANT_CACHE_SIZE 0x04 /* Retrieve cache size at runtime */ #define FSCACHE_INVAL_DIO_WRITE 0x01 /* Invalidate due to DIO write */ diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h index c6f5aa74db89..371e5816e98c 100644 --- a/include/trace/events/cachefiles.h +++ b/include/trace/events/cachefiles.h @@ -31,6 +31,8 @@ enum cachefiles_obj_ref_trace { cachefiles_obj_see_lookup_failed, cachefiles_obj_see_withdraw_cookie, cachefiles_obj_see_withdrawal, + cachefiles_obj_get_ondemand_fd, + cachefiles_obj_put_ondemand_fd, }; enum fscache_why_object_killed { diff --git a/include/uapi/linux/cachefiles.h b/include/uapi/linux/cachefiles.h new file mode 100644 index 000000000000..0c44d68be6bd --- /dev/null +++ b/include/uapi/linux/cachefiles.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _LINUX_CACHEFILES_H +#define _LINUX_CACHEFILES_H + +#include + +/* + * Fscache ensures that the maximum length of cookie key is 255. The volume key + * is controled by netfs, and generally no bigger than 255. + */ +#define CACHEFILES_MSG_MAX_SIZE 1024 + +enum cachefiles_opcode { + CACHEFILES_OP_OPEN, +}; + +/* + * @id identifying position of this message in the radix tree + * @opcode message type, CACHEFILE_OP_* + * @len message length, including message header and following data + * @data message type specific payload + */ +struct cachefiles_msg { + __u32 id; + __u32 opcode; + __u32 len; + __u8 data[]; +}; + +struct cachefiles_open { + __u32 volume_key_len; + __u32 cookie_key_len; + __u32 fd; + __u32 flags; + /* following data contains volume_key and cookie_key in sequence */ + __u8 data[]; +}; + +enum cachefiles_open_flags { + CACHEFILES_OPEN_WANT_CACHE_SIZE, +}; + +#endif From patchwork Fri Mar 25 12:22:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791538 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 4F390C433FE for ; Fri, 25 Mar 2022 12:22:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1358975AbiCYMYK (ORCPT ); Fri, 25 Mar 2022 08:24:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38210 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1358971AbiCYMYJ (ORCPT ); Fri, 25 Mar 2022 08:24:09 -0400 Received: from out30-44.freemail.mail.aliyun.com (out30-44.freemail.mail.aliyun.com [115.124.30.44]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DA289D4479; Fri, 25 Mar 2022 05:22:34 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R171e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04357;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=18;SR=0;TI=SMTPD_---0V89aFr5_1648210950; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89aFr5_1648210950) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:31 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 04/22] cachefiles: notify user daemon when withdrawing cookie Date: Fri, 25 Mar 2022 20:22:05 +0800 Message-Id: <20220325122223.102958-5-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Notify user daemon that cookie is going to be withdrawn, providing a hint that the associated anon_fd can be closed. The anon_fd attached in the CLOSE request shall be same with that in the previous OPEN request. Be noted that this is only a hint. User daemon can close the anon_fd when receiving the CLOSE request, then it will receive another anon_fd if the cookie gets looked up. Or it can also ignore the CLOSE request, and keep writing data into the anon_fd. However the next time cookie gets looked up, the user daemon will still receive another anon_fd. Signed-off-by: Jeffle Xu --- fs/cachefiles/interface.c | 2 ++ fs/cachefiles/internal.h | 3 +++ fs/cachefiles/ondemand.c | 27 +++++++++++++++++++++++++++ include/uapi/linux/cachefiles.h | 5 +++++ 4 files changed, 37 insertions(+) diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index ae93cee9d25d..c5b8fefd4ccc 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -322,6 +322,8 @@ static void cachefiles_commit_object(struct cachefiles_object *object, static void cachefiles_clean_up_object(struct cachefiles_object *object, struct cachefiles_cache *cache) { + cachefiles_ondemand_cleanup_object(object); + if (test_bit(FSCACHE_COOKIE_RETIRED, &object->cookie->flags)) { if (!test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) { cachefiles_see_object(object, cachefiles_obj_see_clean_delete); diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index 8a0f1b691aca..c80b519a887b 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -280,6 +280,7 @@ extern int cachefiles_ondemand_cinit(struct cachefiles_cache *cache, char *args); extern int cachefiles_ondemand_init_object(struct cachefiles_object *object); +extern void cachefiles_ondemand_cleanup_object(struct cachefiles_object *object); #else ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache, @@ -292,6 +293,8 @@ static inline int cachefiles_ondemand_init_object(struct cachefiles_object *obje { return 0; } + +static inline void cachefiles_ondemand_cleanup_object(struct cachefiles_object *object) {} #endif /* diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c index 0742c4a7797a..7fd518e01e5a 100644 --- a/fs/cachefiles/ondemand.c +++ b/fs/cachefiles/ondemand.c @@ -199,6 +199,12 @@ ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache, goto err_put_fd; } + /* CLOSE request has no reply */ + if (msg->opcode == CACHEFILES_OP_CLOSE) { + xa_erase(&cache->reqs, id); + complete(&req->done); + } + return n; err_put_fd: @@ -322,6 +328,19 @@ static int init_open_req(struct cachefiles_req *req, void *private) return 0; } +static int init_close_req(struct cachefiles_req *req, void *private) +{ + struct cachefiles_object *object = req->object; + struct cachefiles_close *load = (void *)req->msg.data; + int fd = object->fd; + + if (WARN_ON_ONCE(fd == -1)) + return -EIO; + + load->fd = fd; + return 0; +} + int cachefiles_ondemand_init_object(struct cachefiles_object *object) { struct fscache_cookie *cookie = object->cookie; @@ -346,3 +365,11 @@ int cachefiles_ondemand_init_object(struct cachefiles_object *object) CACHEFILES_OP_OPEN, data_len, init_open_req, NULL); } + +void cachefiles_ondemand_cleanup_object(struct cachefiles_object *object) +{ + cachefiles_ondemand_send_req(object, + CACHEFILES_OP_CLOSE, + sizeof(struct cachefiles_close), + init_close_req, NULL); +} diff --git a/include/uapi/linux/cachefiles.h b/include/uapi/linux/cachefiles.h index 0c44d68be6bd..03047e4b7df2 100644 --- a/include/uapi/linux/cachefiles.h +++ b/include/uapi/linux/cachefiles.h @@ -12,6 +12,7 @@ enum cachefiles_opcode { CACHEFILES_OP_OPEN, + CACHEFILES_OP_CLOSE, }; /* @@ -40,4 +41,8 @@ enum cachefiles_open_flags { CACHEFILES_OPEN_WANT_CACHE_SIZE, }; +struct cachefiles_close { + __u32 fd; +}; + #endif From patchwork Fri Mar 25 12:22:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791540 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 89350C433EF for ; Fri, 25 Mar 2022 12:22:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1358978AbiCYMYP (ORCPT ); Fri, 25 Mar 2022 08:24:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38340 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354835AbiCYMYM (ORCPT ); Fri, 25 Mar 2022 08:24:12 -0400 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 17B0ED4CBE; Fri, 25 Mar 2022 05:22:37 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R171e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04423;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=18;SR=0;TI=SMTPD_---0V89zY1L_1648210951; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89zY1L_1648210951) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:32 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 05/22] cachefiles: implement on-demand read Date: Fri, 25 Mar 2022 20:22:06 +0800 Message-Id: <20220325122223.102958-6-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Implement the data plane of on-demand read mode. A new NETFS_READ_HOLE_ONDEMAND flag is introduced to indicate that on-demand read should be done when a cache miss encountered. In this case, the read routine will send a READ request to user daemon, along with the anonymous fd and the file range that shall be read. Now user daemon is responsible for fetching data in the given file range, and then writing the fetched data into cache file with the given anonymous fd. After sending the READ request, the read routine will hang there, until the READ request is handled by user daemon. Then it will retry to read from the same file range. If a cache miss is encountered again on the same file range, the read routine will fail then. Signed-off-by: Jeffle Xu --- fs/cachefiles/internal.h | 7 +++ fs/cachefiles/io.c | 11 +++++ fs/cachefiles/ondemand.c | 81 +++++++++++++++++++++++++++++++++ include/linux/netfs.h | 1 + include/uapi/linux/cachefiles.h | 13 ++++++ 5 files changed, 113 insertions(+) diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index c80b519a887b..686f25097681 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -281,6 +281,8 @@ extern int cachefiles_ondemand_cinit(struct cachefiles_cache *cache, extern int cachefiles_ondemand_init_object(struct cachefiles_object *object); extern void cachefiles_ondemand_cleanup_object(struct cachefiles_object *object); +extern int cachefiles_ondemand_read(struct cachefiles_object *object, + loff_t pos, size_t len); #else ssize_t cachefiles_ondemand_daemon_read(struct cachefiles_cache *cache, @@ -295,6 +297,11 @@ static inline int cachefiles_ondemand_init_object(struct cachefiles_object *obje } static inline void cachefiles_ondemand_cleanup_object(struct cachefiles_object *object) {} +static inline int cachefiles_ondemand_read(struct cachefiles_object *object, + loff_t pos, size_t len) +{ + return -EOPNOTSUPP; +} #endif /* diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index 8dbc1eb254a3..ee1283ba7a2c 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -95,6 +95,7 @@ static int cachefiles_read(struct netfs_cache_resources *cres, file, file_inode(file)->i_ino, start_pos, len, i_size_read(file_inode(file))); +retry: /* If the caller asked us to seek for data before doing the read, then * we should do that now. If we find a gap, we fill it with zeros. */ @@ -119,6 +120,16 @@ static int cachefiles_read(struct netfs_cache_resources *cres, if (read_hole == NETFS_READ_HOLE_FAIL) goto presubmission_error; + if (read_hole == NETFS_READ_HOLE_ONDEMAND) { + if (!cachefiles_ondemand_read(object, off, len)) { + /* fail the read if no progress achieved */ + read_hole = NETFS_READ_HOLE_FAIL; + goto retry; + } + + goto presubmission_error; + } + iov_iter_zero(len, iter); skipped = len; ret = 0; diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c index 7fd518e01e5a..965fb7bd97c0 100644 --- a/fs/cachefiles/ondemand.c +++ b/fs/cachefiles/ondemand.c @@ -11,13 +11,30 @@ static int cachefiles_ondemand_fd_release(struct inode *inode, struct file *file) { struct cachefiles_object *object = file->private_data; + struct cachefiles_cache *cache = object->volume->cache; + struct xarray *xa = &cache->reqs; + struct cachefiles_req *req; + unsigned long index; + xa_lock(xa); /* * Uninstall anon_fd to the cachefiles object, so that no further * associated requests will get enqueued. */ object->fd = -1; + /* + * Flush all pending READ requests since their completion depends on + * anon_fd. + */ + xa_for_each(xa, index, req) { + if (req->msg.opcode == CACHEFILES_OP_READ) { + req->error = -EIO; + complete(&req->done); + } + } + xa_unlock(xa); + cachefiles_put_object(object, cachefiles_obj_put_ondemand_fd); return 0; } @@ -60,11 +77,35 @@ static loff_t cachefiles_ondemand_fd_llseek(struct file *filp, loff_t pos, int w return vfs_llseek(file, pos, whence); } +static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl, + unsigned long arg) +{ + struct cachefiles_object *object = filp->private_data; + struct cachefiles_cache *cache = object->volume->cache; + struct cachefiles_req *req; + unsigned long id; + + if (ioctl != CACHEFILES_IOC_CREAD) + return -EINVAL; + + if (!test_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags)) + return -EOPNOTSUPP; + + id = arg; + req = xa_erase(&cache->reqs, id); + if (!req) + return -EINVAL; + + complete(&req->done); + return 0; +} + static const struct file_operations cachefiles_ondemand_fd_fops = { .owner = THIS_MODULE, .release = cachefiles_ondemand_fd_release, .write_iter = cachefiles_ondemand_fd_write_iter, .llseek = cachefiles_ondemand_fd_llseek, + .unlocked_ioctl = cachefiles_ondemand_fd_ioctl, }; /* @@ -269,6 +310,13 @@ static int cachefiles_ondemand_send_req(struct cachefiles_object *object, goto out; } + /* recheck anon_fd for READ request with lock held */ + if (opcode == CACHEFILES_OP_READ && object->fd == -1) { + xas_unlock(&xas); + ret = -EIO; + goto out; + } + xas.xa_index = 0; xas_find_marked(&xas, UINT_MAX, XA_FREE_MARK); if (xas.xa_node == XAS_RESTART) @@ -341,6 +389,28 @@ static int init_close_req(struct cachefiles_req *req, void *private) return 0; } +struct cachefiles_read_ctx { + loff_t off; + size_t len; +}; + +static int init_read_req(struct cachefiles_req *req, void *private) +{ + struct cachefiles_object *object = req->object; + struct cachefiles_read *load = (void *)&req->msg.data; + struct cachefiles_read_ctx *read_ctx = private; + int fd = object->fd; + + /* Stop enqueuing request when daemon closes anon_fd prematurely. */ + if (WARN_ON_ONCE(fd == -1)) + return -EIO; + + load->off = read_ctx->off; + load->len = read_ctx->len; + load->fd = fd; + return 0; +} + int cachefiles_ondemand_init_object(struct cachefiles_object *object) { struct fscache_cookie *cookie = object->cookie; @@ -373,3 +443,14 @@ void cachefiles_ondemand_cleanup_object(struct cachefiles_object *object) sizeof(struct cachefiles_close), init_close_req, NULL); } + +int cachefiles_ondemand_read(struct cachefiles_object *object, + loff_t pos, size_t len) +{ + struct cachefiles_read_ctx read_ctx = {pos, len}; + + return cachefiles_ondemand_send_req(object, + CACHEFILES_OP_READ, + sizeof(struct cachefiles_read), + init_read_req, &read_ctx); +} diff --git a/include/linux/netfs.h b/include/linux/netfs.h index 614f22213e21..2a9c50d3a928 100644 --- a/include/linux/netfs.h +++ b/include/linux/netfs.h @@ -203,6 +203,7 @@ enum netfs_read_from_hole { NETFS_READ_HOLE_IGNORE, NETFS_READ_HOLE_CLEAR, NETFS_READ_HOLE_FAIL, + NETFS_READ_HOLE_ONDEMAND, }; /* diff --git a/include/uapi/linux/cachefiles.h b/include/uapi/linux/cachefiles.h index 03047e4b7df2..004335d44e16 100644 --- a/include/uapi/linux/cachefiles.h +++ b/include/uapi/linux/cachefiles.h @@ -3,6 +3,7 @@ #define _LINUX_CACHEFILES_H #include +#include /* * Fscache ensures that the maximum length of cookie key is 255. The volume key @@ -13,6 +14,7 @@ enum cachefiles_opcode { CACHEFILES_OP_OPEN, CACHEFILES_OP_CLOSE, + CACHEFILES_OP_READ, }; /* @@ -45,4 +47,15 @@ struct cachefiles_close { __u32 fd; }; +struct cachefiles_read { + __u64 off; + __u64 len; + __u32 fd; +}; + +/* + * For CACHEFILES_IOC_CREAD, arg is the @id field of corresponding READ request. + */ +#define CACHEFILES_IOC_CREAD _IOW(0x98, 1, long) + #endif From patchwork Fri Mar 25 12:22:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791555 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 00534C4332F for ; Fri, 25 Mar 2022 12:23:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1359089AbiCYMZR (ORCPT ); Fri, 25 Mar 2022 08:25:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38464 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1358987AbiCYMYP (ORCPT ); Fri, 25 Mar 2022 08:24:15 -0400 Received: from out199-14.us.a.mail.aliyun.com (out199-14.us.a.mail.aliyun.com [47.90.199.14]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 427D9D5561; Fri, 25 Mar 2022 05:22:39 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R121e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04426;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=18;SR=0;TI=SMTPD_---0V89qR-b_1648210953; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89qR-b_1648210953) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:34 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 06/22] cachefiles: enable on-demand read mode Date: Fri, 25 Mar 2022 20:22:07 +0800 Message-Id: <20220325122223.102958-7-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Enable on-demand read mode by adding an optional parameter to the "bind" command. On-demand mode will be turned on when this parameter is "ondemand", i.e. "bind ondemand". Otherwise cachefiles will work in the original mode. Signed-off-by: Jeffle Xu --- fs/cachefiles/daemon.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c index 91b88a499737..2c38c5361bda 100644 --- a/fs/cachefiles/daemon.c +++ b/fs/cachefiles/daemon.c @@ -741,11 +741,6 @@ static int cachefiles_daemon_bind(struct cachefiles_cache *cache, char *args) cache->brun_percent >= 100) return -ERANGE; - if (*args) { - pr_err("'bind' command doesn't take an argument\n"); - return -EINVAL; - } - if (!cache->rootdirname) { pr_err("No cache directory specified\n"); return -EINVAL; @@ -757,6 +752,14 @@ static int cachefiles_daemon_bind(struct cachefiles_cache *cache, char *args) return -EBUSY; } + if (IS_ENABLED(CONFIG_CACHEFILES_ONDEMAND) && + !strcmp(args, "ondemand")) { + set_bit(CACHEFILES_ONDEMAND_MODE, &cache->flags); + } else if (*args) { + pr_err("'bind' command doesn't take an argument\n"); + return -EINVAL; + } + /* Make sure we have copies of the tag string */ if (!cache->tag) { /* From patchwork Fri Mar 25 12:22:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791546 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 DBC76C4332F for ; Fri, 25 Mar 2022 12:23:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1359032AbiCYMYo (ORCPT ); Fri, 25 Mar 2022 08:24:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38438 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1358973AbiCYMYT (ORCPT ); Fri, 25 Mar 2022 08:24:19 -0400 Received: from out30-133.freemail.mail.aliyun.com (out30-133.freemail.mail.aliyun.com [115.124.30.133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0EFF8CC527; Fri, 25 Mar 2022 05:22:39 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R181e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04423;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=18;SR=0;TI=SMTPD_---0V89aFrb_1648210954; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89aFrb_1648210954) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:35 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 07/22] cachefiles: document on-demand read mode Date: Fri, 25 Mar 2022 20:22:08 +0800 Message-Id: <20220325122223.102958-8-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Document new user interface introduced by on-demand read mode. Signed-off-by: Jeffle Xu --- .../filesystems/caching/cachefiles.rst | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) diff --git a/Documentation/filesystems/caching/cachefiles.rst b/Documentation/filesystems/caching/cachefiles.rst index 8bf396b76359..46420fca6677 100644 --- a/Documentation/filesystems/caching/cachefiles.rst +++ b/Documentation/filesystems/caching/cachefiles.rst @@ -28,6 +28,8 @@ Cache on Already Mounted Filesystem (*) Debugging. + (*) On-demand Read. + Overview @@ -482,3 +484,179 @@ the control file. For example:: echo $((1|4|8)) >/sys/module/cachefiles/parameters/debug will turn on all function entry debugging. + + +On-demand Read +============== + +When working in original mode, cachefiles mainly serves as a local cache for +remote networking fs, while in on-demand read mode, cachefiles can boost the +scenario where on-demand read semantics is needed, e.g. container image +distribution. + +The essential difference between these two modes is that, in original mode, +when cache miss, netfs itself will fetch data from remote, and then write the +fetched data into cache file. While in on-demand read mode, a user daemon is +responsible for fetching data and then writing to the cache file. + +``CONFIG_CACHEFILES_ONDEMAND`` shall be enabled to support on-demand read mode. + + +Protocol Communication +---------------------- + +The on-demand read mode relies on a simple protocol used for communication +between kernel and user daemon. The model is like:: + + kernel --[request]--> user daemon --[reply]--> kernel + +The cachefiles kernel module will send requests to user daemon when needed. +User daemon needs to poll on the devnode ('/dev/cachefiles') to check if +there's pending request to be processed. A POLLIN event will be returned +when there's pending request. + +Then user daemon needs to read the devnode to fetch one request and process it +accordingly. It is worth nothing that each read only gets one request. When +finished processing the request, user dameon needs to write the reply to the +devnode. + +Each request is started with a message header like:: + + struct cachefiles_msg { + __u32 id; + __u32 opcode; + __u32 len; + __u8 data[]; + }; + + * ``id`` identifies the position of this request in an internal xarray + managing all pending requests. + + * ``opcode`` identifies the type of this request. + + * ``data`` identifies the payload of this request. + + * ``len`` identifies the whole length of this request, including the + header and following type specific payload. + + +Turn on On-demand Mode +---------------------- + +An optional parameter is added to "bind" command:: + + bind [ondemand] + +When "bind" command takes without argument, it defaults to the original mode. +When "bind" command takes with "ondemand" argument, i.e. "bind ondemand", +on-demand read mode will be enabled. + + +OPEN Request +------------ + +When netfs opens a cache file for the first time, a request with +CACHEFILES_OP_OPEN opcode, a.k.a OPEN request will be sent to user daemon. The +payload format is like:: + + struct cachefiles_open { + __u32 volume_key_len; + __u32 cookie_key_len; + __u32 fd; + __u32 flags; + __u8 data[]; + }; + + * ``data`` contains volume_key and cookie_key in sequence. + + * ``volume_key_len`` identifies the length of the volume key of the + cache file, in bytes. volume_key is of string format, with a suffix + '\0'. + + * ``cookie_key_len`` identifies the length of the cookie key of the + cache file, in bytes. The format of cookie_key is netfs specific. It + can be of binary format. + + * ``fd`` identifies the anonymous fd of the cache file, with which user + daemon can perform write/llseek file operations on the cache file. + + +OPEN request contains (volume_key, cookie_key, anon_fd) triple for corresponding +cache file. With this triple, user daemon could fetch and write data into the +cache file in the background, even when kernel has not triggered the cache miss +yet. User daemon is able to distinguish the requested cache file with the given +(volume_key, cookie_key), and write the fetched data into cache file with the +given anon_fd. + +After recording the (volume_key, cookie_key, anon_fd) triple, user daemon shall +reply with "cinit" (complete init) command:: + + cinit + + * ``id`` is exactly the id field of the previous OPEN request. + + +Besides, CACHEFILES_OPEN_WANT_CACHE_SIZE flag may be set in flags field of +OPEN request. This flag is used in the scenario where one cache file can contain +multiple netfs files for the purpose of deduplication, e.g. In this case, netfs +itself has no idea the cache file size, whilst user daemon needs to offer the +hint on the cache file size. + +Thus when receiving an OPEN request with CACHEFILES_OPEN_WANT_CACHE_SIZE flag +set, user daemon must reply with the cache file size:: + + cinit , + + * ``id`` is exactly the id field of the previous OPEN request. + + * ``cache_size`` identifies the size of the cache file. + + +CLOSE Request +------------- +When cookie withdrawed, a request with CACHEFILES_OP_CLOSE opcode, a.k.a CLOSE +request, will be sent to user daemon. It will notify user daemon to close the +attached anon_fd. The payload format is like:: + + struct cachefiles_close { + __u32 fd; + }; + + * ``fd`` identifies the anon_fd to be closed, which is exactly the same + with that in OPEN request. + + +READ Request +------------ + +When on-demand read mode is turned on, and cache miss encountered, kernel will +send a request with CACHEFILES_OP_READ opcode, a.k.a READ request, to user +daemon. It will notify user daemon to fetch data in the requested file range. +The payload format is like:: + + struct cachefiles_read { + __u64 off; + __u64 len; + __u32 fd; + }; + + * ``off`` identifies the starting offset of the requested file range. + + * ``len`` identifies the length of the requested file range. + + * ``fd`` identifies the anonymous fd of the requested cache file. It is + guaranteed that it shall be the same with the fd field in the previous + OPEN request. + +When receiving one READ request, user daemon needs to fetch data of the +requested file range, and then write the fetched data into cache file with the +given anonymous fd. + +When finished processing the READ request, user daemon needs to reply with +CACHEFILES_IOC_CREAD ioctl on the corresponding anon_fd:: + + ioctl(fd, CACHEFILES_IOC_CREAD, id); + + * ``fd`` is exactly the fd field of the previous READ request. + + * ``id`` is exactly the id field of the previous READ request. From patchwork Fri Mar 25 12:22:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791553 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 B409BC433EF for ; Fri, 25 Mar 2022 12:23:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1359049AbiCYMZO (ORCPT ); Fri, 25 Mar 2022 08:25:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38438 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354234AbiCYMYm (ORCPT ); Fri, 25 Mar 2022 08:24:42 -0400 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 E6671D555B; Fri, 25 Mar 2022 05:22:41 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R551e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04395;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=18;SR=0;TI=SMTPD_---0V89qR.F_1648210956; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89qR.F_1648210956) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:37 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 08/22] erofs: use meta buffers for erofs_read_superblock() Date: Fri, 25 Mar 2022 20:22:09 +0800 Message-Id: <20220325122223.102958-9-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org The only change is that, meta buffers read cache page without __GFP_FS flag, which shall not matter. Signed-off-by: Jeffle Xu Reviewed-by: Chao Yu Reviewed-by: Gao Xiang --- fs/erofs/super.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/fs/erofs/super.c b/fs/erofs/super.c index 915eefe0d7e2..12755217631f 100644 --- a/fs/erofs/super.c +++ b/fs/erofs/super.c @@ -281,21 +281,19 @@ static int erofs_init_devices(struct super_block *sb, static int erofs_read_superblock(struct super_block *sb) { struct erofs_sb_info *sbi; - struct page *page; + struct erofs_buf buf = __EROFS_BUF_INITIALIZER; struct erofs_super_block *dsb; unsigned int blkszbits; void *data; int ret; - page = read_mapping_page(sb->s_bdev->bd_inode->i_mapping, 0, NULL); - if (IS_ERR(page)) { + data = erofs_read_metabuf(&buf, sb, 0, EROFS_KMAP); + if (IS_ERR(data)) { erofs_err(sb, "cannot read erofs superblock"); - return PTR_ERR(page); + return PTR_ERR(data); } sbi = EROFS_SB(sb); - - data = kmap(page); dsb = (struct erofs_super_block *)(data + EROFS_SUPER_OFFSET); ret = -EINVAL; @@ -365,8 +363,7 @@ static int erofs_read_superblock(struct super_block *sb) if (erofs_sb_has_ztailpacking(sbi)) erofs_info(sb, "EXPERIMENTAL compressed inline data feature in use. Use at your own risk!"); out: - kunmap(page); - put_page(page); + erofs_put_metabuf(&buf); return ret; } From patchwork Fri Mar 25 12:22:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791554 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 E05C1C433F5 for ; Fri, 25 Mar 2022 12:23:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1359064AbiCYMZQ (ORCPT ); Fri, 25 Mar 2022 08:25:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38458 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1358997AbiCYMYm (ORCPT ); Fri, 25 Mar 2022 08:24:42 -0400 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 C3E72D4CB5; Fri, 25 Mar 2022 05:22:42 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R131e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04423;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=18;SR=0;TI=SMTPD_---0V89zY2J_1648210957; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89zY2J_1648210957) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:38 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 09/22] erofs: make erofs_map_blocks() generally available Date: Fri, 25 Mar 2022 20:22:10 +0800 Message-Id: <20220325122223.102958-10-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org ... so that it can be used in the following introduced fs/erofs/fscache.c. Signed-off-by: Jeffle Xu --- fs/erofs/data.c | 4 ++-- fs/erofs/internal.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/erofs/data.c b/fs/erofs/data.c index 226a57c57ee6..6e2a28242453 100644 --- a/fs/erofs/data.c +++ b/fs/erofs/data.c @@ -104,8 +104,8 @@ static int erofs_map_blocks_flatmode(struct inode *inode, return 0; } -static int erofs_map_blocks(struct inode *inode, - struct erofs_map_blocks *map, int flags) +int erofs_map_blocks(struct inode *inode, + struct erofs_map_blocks *map, int flags) { struct super_block *sb = inode->i_sb; struct erofs_inode *vi = EROFS_I(inode); diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 5aa2cf2c2f80..e424293f47a2 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -484,6 +484,8 @@ void *erofs_read_metabuf(struct erofs_buf *buf, struct super_block *sb, int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *dev); int erofs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, u64 start, u64 len); +int erofs_map_blocks(struct inode *inode, + struct erofs_map_blocks *map, int flags); /* inode.c */ static inline unsigned long erofs_inode_hash(erofs_nid_t nid) From patchwork Fri Mar 25 12:22:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791550 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 B5A2DC4332F for ; Fri, 25 Mar 2022 12:23:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1359000AbiCYMZJ (ORCPT ); Fri, 25 Mar 2022 08:25:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38454 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1359028AbiCYMYo (ORCPT ); Fri, 25 Mar 2022 08:24:44 -0400 Received: from out30-131.freemail.mail.aliyun.com (out30-131.freemail.mail.aliyun.com [115.124.30.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 48B97D5E86; Fri, 25 Mar 2022 05:22:45 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R201e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04426;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=18;SR=0;TI=SMTPD_---0V89zY2j_1648210959; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89zY2j_1648210959) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:40 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 10/22] erofs: add mode checking helper Date: Fri, 25 Mar 2022 20:22:11 +0800 Message-Id: <20220325122223.102958-11-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Until then erofs is exactly blockdev based filesystem. In other using scenarios (e.g. container image), erofs needs to run upon files. This patch set is going to introduces a new nodev mode, in which erofs could be mounted from a bootstrap blob file containing complete erofs image. Add a helper checking which mode erofs works in. Signed-off-by: Jeffle Xu --- fs/erofs/internal.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index e424293f47a2..1486e2573667 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -161,6 +161,11 @@ struct erofs_sb_info { #define set_opt(opt, option) ((opt)->mount_opt |= EROFS_MOUNT_##option) #define test_opt(opt, option) ((opt)->mount_opt & EROFS_MOUNT_##option) +static inline bool erofs_is_nodev_mode(struct super_block *sb) +{ + return !sb->s_bdev; +} + enum { EROFS_ZIP_CACHE_DISABLED, EROFS_ZIP_CACHE_READAHEAD, From patchwork Fri Mar 25 12:22:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791549 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 B9EEDC433EF for ; Fri, 25 Mar 2022 12:23:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347076AbiCYMZI (ORCPT ); Fri, 25 Mar 2022 08:25:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39836 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1359037AbiCYMYo (ORCPT ); Fri, 25 Mar 2022 08:24:44 -0400 Received: from out30-45.freemail.mail.aliyun.com (out30-45.freemail.mail.aliyun.com [115.124.30.45]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F1DADD5E9B; Fri, 25 Mar 2022 05:22:46 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R321e4;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=18;SR=0;TI=SMTPD_---0V89aFsf_1648210960; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89aFsf_1648210960) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:41 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 11/22] erofs: register global fscache volume Date: Fri, 25 Mar 2022 20:22:12 +0800 Message-Id: <20220325122223.102958-12-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org All erofs instances will share one global fscache volume. In this using scenario, one erofs instance could be mounted from one (or multiple) blob files instead of blkdev. The number of blob files that each erofs instance could correspond to is limited. For example, when used for container image distribution, one erofs instance used for container image for node.js will correspond to ~20 blob files in total. Thus in densely employed environment, there could be as many as hundreds of containers and thus thousands of fscache cookies under one fscache volume. Then as for cachefiles backend, the hash table managing all cookies under one volume contains 32K slots. Thus the hashing functionality shall scale well in this case. Besides, cachefiles backend will scatter backing files under 256 fan sub-directoris, and thus the scalability of looking up backing files shall also not be an issue. Signed-off-by: Jeffle Xu --- fs/erofs/Kconfig | 10 ++++++++++ fs/erofs/Makefile | 1 + fs/erofs/fscache.c | 22 ++++++++++++++++++++++ fs/erofs/internal.h | 9 +++++++++ fs/erofs/super.c | 7 +++++++ 5 files changed, 49 insertions(+) create mode 100644 fs/erofs/fscache.c diff --git a/fs/erofs/Kconfig b/fs/erofs/Kconfig index f57255ab88ed..a6f5d61bdc49 100644 --- a/fs/erofs/Kconfig +++ b/fs/erofs/Kconfig @@ -98,3 +98,13 @@ config EROFS_FS_ZIP_LZMA systems will be readable without selecting this option. If unsure, say N. + +config EROFS_FS_ONDEMAND + bool "EROFS fscache-based ondeand-read" + depends on CACHEFILES_ONDEMAND && (EROFS_FS=m && FSCACHE && CACHEFILES || EROFS_FS=y && FSCACHE=y && CACHEFILES=y) + default n + help + EROFS is mounted from data blob files and implement on-demand read + semantics through fscache. + + If unsure, say N. diff --git a/fs/erofs/Makefile b/fs/erofs/Makefile index 8a3317e38e5a..99bbc597a3e9 100644 --- a/fs/erofs/Makefile +++ b/fs/erofs/Makefile @@ -5,3 +5,4 @@ erofs-objs := super.o inode.o data.o namei.o dir.o utils.o pcpubuf.o sysfs.o erofs-$(CONFIG_EROFS_FS_XATTR) += xattr.o erofs-$(CONFIG_EROFS_FS_ZIP) += decompressor.o zmap.o zdata.o erofs-$(CONFIG_EROFS_FS_ZIP_LZMA) += decompressor_lzma.o +erofs-$(CONFIG_EROFS_FS_ONDEMAND) += fscache.o diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c new file mode 100644 index 000000000000..08cf570a0810 --- /dev/null +++ b/fs/erofs/fscache.c @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2022, Alibaba Cloud + */ +#include +#include "internal.h" + +static struct fscache_volume *volume; + +int __init erofs_init_fscache(void) +{ + volume = fscache_acquire_volume("erofs", NULL, NULL, 0); + if (!volume) + return -EINVAL; + + return 0; +} + +void erofs_exit_fscache(void) +{ + fscache_relinquish_volume(volume, NULL, false); +} diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 1486e2573667..45b8b0dd8a27 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -616,6 +616,15 @@ static inline int z_erofs_load_lzma_config(struct super_block *sb, } #endif /* !CONFIG_EROFS_FS_ZIP */ +/* fscache.c */ +#ifdef CONFIG_EROFS_FS_ONDEMAND +int erofs_init_fscache(void); +void erofs_exit_fscache(void); +#else +static inline int erofs_init_fscache(void) { return 0; } +static inline void erofs_exit_fscache(void) {} +#endif + #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ #endif /* __EROFS_INTERNAL_H */ diff --git a/fs/erofs/super.c b/fs/erofs/super.c index 12755217631f..798f0c379e35 100644 --- a/fs/erofs/super.c +++ b/fs/erofs/super.c @@ -814,6 +814,10 @@ static int __init erofs_module_init(void) if (err) goto sysfs_err; + err = erofs_init_fscache(); + if (err) + goto fscache_err; + err = register_filesystem(&erofs_fs_type); if (err) goto fs_err; @@ -821,6 +825,8 @@ static int __init erofs_module_init(void) return 0; fs_err: + erofs_exit_fscache(); +fscache_err: erofs_exit_sysfs(); sysfs_err: z_erofs_exit_zip_subsystem(); @@ -841,6 +847,7 @@ static void __exit erofs_module_exit(void) /* Ensure all RCU free inodes / pclusters are safe to be destroyed. */ rcu_barrier(); + erofs_exit_fscache(); erofs_exit_sysfs(); z_erofs_exit_zip_subsystem(); z_erofs_lzma_exit(); From patchwork Fri Mar 25 12:22:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791548 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 AF5ABC433FE for ; Fri, 25 Mar 2022 12:23:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354065AbiCYMZG (ORCPT ); Fri, 25 Mar 2022 08:25:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39864 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1359042AbiCYMYo (ORCPT ); Fri, 25 Mar 2022 08:24:44 -0400 Received: from out30-44.freemail.mail.aliyun.com (out30-44.freemail.mail.aliyun.com [115.124.30.44]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B9D61D5562; Fri, 25 Mar 2022 05:22:48 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R201e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04395;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=18;SR=0;TI=SMTPD_---0V89aFsk_1648210962; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89aFsk_1648210962) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:43 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 12/22] erofs: add cookie context helper functions Date: Fri, 25 Mar 2022 20:22:13 +0800 Message-Id: <20220325122223.102958-13-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Introduce "struct erofs_fscache" for managing cookie for backinig file, and helper functions for initializing and cleaning up this context structure. Signed-off-by: Jeffle Xu --- fs/erofs/fscache.c | 61 +++++++++++++++++++++++++++++++++++++++++++++ fs/erofs/internal.h | 14 +++++++++++ 2 files changed, 75 insertions(+) diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c index 08cf570a0810..73235fd43bf6 100644 --- a/fs/erofs/fscache.c +++ b/fs/erofs/fscache.c @@ -7,6 +7,67 @@ static struct fscache_volume *volume; +static int erofs_fscache_init_cookie(struct erofs_fscache *ctx, char *path) +{ + struct fscache_cookie *cookie; + + cookie = fscache_acquire_cookie(volume, FSCACHE_ADV_WANT_CACHE_SIZE, + path, strlen(path), + NULL, 0, 0); + if (!cookie) + return -EINVAL; + + fscache_use_cookie(cookie, false); + ctx->cookie = cookie; + return 0; +} + +static inline void erofs_fscache_cleanup_cookie(struct erofs_fscache *ctx) +{ + struct fscache_cookie *cookie = ctx->cookie; + + fscache_unuse_cookie(cookie, NULL, NULL); + fscache_relinquish_cookie(cookie, false); + ctx->cookie = NULL; +} + +/* + * erofs_fscache_get - create an fscache context for blob file + * @sb: superblock + * @path: name of blob file + * + * Return: fscache context on success, ERR_PTR() on failure. + */ +struct erofs_fscache *erofs_fscache_get(struct super_block *sb, char *path) +{ + struct erofs_fscache *ctx; + int ret; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return ERR_PTR(-ENOMEM); + + ret = erofs_fscache_init_cookie(ctx, path); + if (ret) { + erofs_err(sb, "failed to init cookie"); + goto err; + } + + return ctx; +err: + kfree(ctx); + return ERR_PTR(ret); +} + +void erofs_fscache_put(struct erofs_fscache *ctx) +{ + if (!ctx) + return; + + erofs_fscache_cleanup_cookie(ctx); + kfree(ctx); +} + int __init erofs_init_fscache(void) { volume = fscache_acquire_volume("erofs", NULL, NULL, 0); diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 45b8b0dd8a27..d4f2b43cedae 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -96,6 +96,10 @@ struct erofs_sb_lz4_info { u16 max_pclusterblks; }; +struct erofs_fscache { + struct fscache_cookie *cookie; +}; + struct erofs_sb_info { struct erofs_mount_opts opt; /* options */ #ifdef CONFIG_EROFS_FS_ZIP @@ -620,9 +624,19 @@ static inline int z_erofs_load_lzma_config(struct super_block *sb, #ifdef CONFIG_EROFS_FS_ONDEMAND int erofs_init_fscache(void); void erofs_exit_fscache(void); + +struct erofs_fscache *erofs_fscache_get(struct super_block *sb, char *path); +void erofs_fscache_put(struct erofs_fscache *ctx); #else static inline int erofs_init_fscache(void) { return 0; } static inline void erofs_exit_fscache(void) {} + +static inline struct erofs_fscache *erofs_fscache_get(struct super_block *sb, + char *path) +{ + return ERR_PTR(-EOPNOTSUPP); +} +static inline void erofs_fscache_put(struct erofs_fscache *ctx) {} #endif #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ From patchwork Fri Mar 25 12:22:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791541 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 3B940C4332F for ; Fri, 25 Mar 2022 12:23:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1359093AbiCYMYu (ORCPT ); Fri, 25 Mar 2022 08:24:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38460 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1359047AbiCYMYo (ORCPT ); Fri, 25 Mar 2022 08:24:44 -0400 Received: from out30-131.freemail.mail.aliyun.com (out30-131.freemail.mail.aliyun.com [115.124.30.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1EA8BD5E88; Fri, 25 Mar 2022 05:22:49 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R141e4;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=18;SR=0;TI=SMTPD_---0V89aFt._1648210964; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89aFt._1648210964) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:45 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 13/22] erofs: add anonymous inode managing page cache of blob file Date: Fri, 25 Mar 2022 20:22:14 +0800 Message-Id: <20220325122223.102958-14-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Introduce one anonymous inode for managing page cache of corresponding blob file. Then erofs could read directly from the address space of the anonymous inode when cache hit. Signed-off-by: Jeffle Xu --- fs/erofs/fscache.c | 41 ++++++++++++++++++++++++++++++++++++++++- fs/erofs/internal.h | 7 +++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c index 73235fd43bf6..30383d9adb62 100644 --- a/fs/erofs/fscache.c +++ b/fs/erofs/fscache.c @@ -7,6 +7,9 @@ static struct fscache_volume *volume; +static const struct address_space_operations erofs_fscache_blob_aops = { +}; + static int erofs_fscache_init_cookie(struct erofs_fscache *ctx, char *path) { struct fscache_cookie *cookie; @@ -31,6 +34,29 @@ static inline void erofs_fscache_cleanup_cookie(struct erofs_fscache *ctx) ctx->cookie = NULL; } +static int erofs_fscache_get_inode(struct erofs_fscache *ctx, + struct super_block *sb) +{ + struct inode *const inode = new_inode(sb); + + if (!inode) + return -ENOMEM; + + set_nlink(inode, 1); + inode->i_size = OFFSET_MAX; + inode->i_mapping->a_ops = &erofs_fscache_blob_aops; + mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); + + ctx->inode = inode; + return 0; +} + +static inline void erofs_fscache_put_inode(struct erofs_fscache *ctx) +{ + iput(ctx->inode); + ctx->inode = NULL; +} + /* * erofs_fscache_get - create an fscache context for blob file * @sb: superblock @@ -38,7 +64,8 @@ static inline void erofs_fscache_cleanup_cookie(struct erofs_fscache *ctx) * * Return: fscache context on success, ERR_PTR() on failure. */ -struct erofs_fscache *erofs_fscache_get(struct super_block *sb, char *path) +struct erofs_fscache *erofs_fscache_get(struct super_block *sb, char *path, + bool need_inode) { struct erofs_fscache *ctx; int ret; @@ -53,7 +80,18 @@ struct erofs_fscache *erofs_fscache_get(struct super_block *sb, char *path) goto err; } + if (need_inode) { + ret = erofs_fscache_get_inode(ctx, sb); + if (ret) { + erofs_err(sb, "failed to get anonymous inode"); + goto err_cookie; + } + } + return ctx; + +err_cookie: + erofs_fscache_cleanup_cookie(ctx); err: kfree(ctx); return ERR_PTR(ret); @@ -65,6 +103,7 @@ void erofs_fscache_put(struct erofs_fscache *ctx) return; erofs_fscache_cleanup_cookie(ctx); + erofs_fscache_put_inode(ctx); kfree(ctx); } diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index d4f2b43cedae..459f31803c3b 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -98,6 +98,7 @@ struct erofs_sb_lz4_info { struct erofs_fscache { struct fscache_cookie *cookie; + struct inode *inode; }; struct erofs_sb_info { @@ -625,14 +626,16 @@ static inline int z_erofs_load_lzma_config(struct super_block *sb, int erofs_init_fscache(void); void erofs_exit_fscache(void); -struct erofs_fscache *erofs_fscache_get(struct super_block *sb, char *path); +struct erofs_fscache *erofs_fscache_get(struct super_block *sb, char *path, + bool need_inode); void erofs_fscache_put(struct erofs_fscache *ctx); #else static inline int erofs_init_fscache(void) { return 0; } static inline void erofs_exit_fscache(void) {} static inline struct erofs_fscache *erofs_fscache_get(struct super_block *sb, - char *path) + char *path, + bool need_inode) { return ERR_PTR(-EOPNOTSUPP); } From patchwork Fri Mar 25 12:22:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791542 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 C1AD7C433F5 for ; Fri, 25 Mar 2022 12:23:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353476AbiCYMYw (ORCPT ); Fri, 25 Mar 2022 08:24:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38456 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1359049AbiCYMYo (ORCPT ); Fri, 25 Mar 2022 08:24:44 -0400 Received: from out30-45.freemail.mail.aliyun.com (out30-45.freemail.mail.aliyun.com [115.124.30.45]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 20E29D5EB2; Fri, 25 Mar 2022 05:22:50 -0700 (PDT) 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=18;SR=0;TI=SMTPD_---0V89Vk7G_1648210965; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89Vk7G_1648210965) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:46 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 14/22] erofs: add erofs_fscache_read_folios() helper Date: Fri, 25 Mar 2022 20:22:15 +0800 Message-Id: <20220325122223.102958-15-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Add erofs_fscache_read_folios() helper reading from fscache. It supports on-demand read semantics. That is, it will make the backend prepare for the data when cache miss. Once data ready, it will reinitiate a read from the cache. This helper can then be used to implement .readpage()/.readahead() of on-demand read semantics. Besides also add erofs_fscache_read_folio() wrapper helper. Signed-off-by: Jeffle Xu --- fs/erofs/fscache.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c index 30383d9adb62..6a55f7b5f883 100644 --- a/fs/erofs/fscache.c +++ b/fs/erofs/fscache.c @@ -7,6 +7,45 @@ static struct fscache_volume *volume; +/* + * erofs_fscache_read_folios - Read data from fscache. + * + * Fill the read data into page cache described by @start/len, which shall be + * both aligned with PAGE_SIZE. @pstart describes the corresponding physical + * start address in the cache file. + */ +static int erofs_fscache_read_folios(struct fscache_cookie *cookie, + struct address_space *mapping, + loff_t start, size_t len, + loff_t pstart) +{ + struct netfs_cache_resources cres; + struct iov_iter iter; + int ret; + + memset(&cres, 0, sizeof(cres)); + + ret = fscache_begin_read_operation(&cres, cookie); + if (ret) + return ret; + + iov_iter_xarray(&iter, READ, &mapping->i_pages, start, len); + + ret = fscache_read(&cres, pstart, &iter, + NETFS_READ_HOLE_ONDEMAND, NULL, NULL); + + fscache_end_operation(&cres); + return ret; +} + +static inline int erofs_fscache_read_folio(struct fscache_cookie *cookie, + struct folio *folio, loff_t pstart) +{ + return erofs_fscache_read_folios(cookie, folio_file_mapping(folio), + folio_pos(folio), folio_size(folio), + pstart); +} + static const struct address_space_operations erofs_fscache_blob_aops = { }; From patchwork Fri Mar 25 12:22:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791547 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 7307EC433F5 for ; Fri, 25 Mar 2022 12:23:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352787AbiCYMZE (ORCPT ); Fri, 25 Mar 2022 08:25:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39758 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1359059AbiCYMYp (ORCPT ); Fri, 25 Mar 2022 08:24:45 -0400 Received: from out30-43.freemail.mail.aliyun.com (out30-43.freemail.mail.aliyun.com [115.124.30.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 15329D5EBC; Fri, 25 Mar 2022 05:22:51 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R151e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04407;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=18;SR=0;TI=SMTPD_---0V89zY3j_1648210967; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89zY3j_1648210967) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:48 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 15/22] erofs: register cookie context for bootstrap blob Date: Fri, 25 Mar 2022 20:22:16 +0800 Message-Id: <20220325122223.102958-16-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Registers fscache_cookie for the bootstrap blob file. The bootstrap blob file can be specified by a new mount option, which is going to be introduced by a following patch. Something worth mentioning about the cleanup routine. 1. The init routine is prior to when the root inode gets initialized, and thus the corresponding cleanup routine shall be placed inside .kill_sb() callback. 2. The init routine will instantiate anonymous inodes under the super_block, and thus .put_super() callback shall also contain the cleanup routine. Or we'll get "VFS: Busy inodes after unmount." warning. Signed-off-by: Jeffle Xu --- fs/erofs/internal.h | 3 +++ fs/erofs/super.c | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 459f31803c3b..d8c886a7491e 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -73,6 +73,7 @@ struct erofs_mount_opts { /* threshold for decompression synchronously */ unsigned int max_sync_decompress_pages; #endif + char *tag; unsigned int mount_opt; }; @@ -151,6 +152,8 @@ struct erofs_sb_info { /* sysfs support */ struct kobject s_kobj; /* /sys/fs/erofs/ */ struct completion s_kobj_unregister; + + struct erofs_fscache *bootstrap; }; #define EROFS_SB(sb) ((struct erofs_sb_info *)(sb)->s_fs_info) diff --git a/fs/erofs/super.c b/fs/erofs/super.c index 798f0c379e35..de5aeda4aea0 100644 --- a/fs/erofs/super.c +++ b/fs/erofs/super.c @@ -598,6 +598,16 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) sbi->devs = ctx->devs; ctx->devs = NULL; + if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && erofs_is_nodev_mode(sb)) { + struct erofs_fscache *bootstrap; + + bootstrap = erofs_fscache_get(sb, ctx->opt.tag, true); + if (IS_ERR(bootstrap)) + return PTR_ERR(bootstrap); + + sbi->bootstrap = bootstrap; + } + err = erofs_read_superblock(sb); if (err) return err; @@ -753,6 +763,7 @@ static void erofs_kill_sb(struct super_block *sb) return; erofs_free_dev_context(sbi->devs); + erofs_fscache_put(sbi->bootstrap); fs_put_dax(sbi->dax_dev); kfree(sbi); sb->s_fs_info = NULL; @@ -771,6 +782,12 @@ static void erofs_put_super(struct super_block *sb) iput(sbi->managed_cache); sbi->managed_cache = NULL; #endif + erofs_fscache_put(sbi->bootstrap); + /* + * Set sbi->bootstrap to NULL, so that the following cleanup routine + * inside .kill_sb() could be skipped then. + */ + sbi->bootstrap = NULL; } static struct file_system_type erofs_fs_type = { From patchwork Fri Mar 25 12:22:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791544 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 01F06C433FE for ; Fri, 25 Mar 2022 12:23:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1359068AbiCYMY7 (ORCPT ); Fri, 25 Mar 2022 08:24:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40046 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1359078AbiCYMYr (ORCPT ); Fri, 25 Mar 2022 08:24:47 -0400 Received: from out30-45.freemail.mail.aliyun.com (out30-45.freemail.mail.aliyun.com [115.124.30.45]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1FF82D64D8; Fri, 25 Mar 2022 05:22:53 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R121e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04426;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=18;SR=0;TI=SMTPD_---0V89aFtZ_1648210968; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89aFtZ_1648210968) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:49 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 16/22] erofs: implement fscache-based metadata read Date: Fri, 25 Mar 2022 20:22:17 +0800 Message-Id: <20220325122223.102958-17-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Implements the data plane of reading metadata from bootstrap blob file over fscache. Signed-off-by: Jeffle Xu --- fs/erofs/data.c | 17 +++++++++++++++-- fs/erofs/fscache.c | 34 ++++++++++++++++++++++++++++++++++ fs/erofs/internal.h | 8 ++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/fs/erofs/data.c b/fs/erofs/data.c index 6e2a28242453..b4571bea93d5 100644 --- a/fs/erofs/data.c +++ b/fs/erofs/data.c @@ -31,15 +31,28 @@ void erofs_put_metabuf(struct erofs_buf *buf) void *erofs_read_metabuf(struct erofs_buf *buf, struct super_block *sb, erofs_blk_t blkaddr, enum erofs_kmap_type type) { - struct address_space *const mapping = sb->s_bdev->bd_inode->i_mapping; + struct address_space *mapping; + struct erofs_sb_info *sbi = EROFS_SB(sb); erofs_off_t offset = blknr_to_addr(blkaddr); pgoff_t index = offset >> PAGE_SHIFT; struct page *page = buf->page; if (!page || page->index != index) { erofs_put_metabuf(buf); - page = read_cache_page_gfp(mapping, index, + if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && + erofs_is_nodev_mode(sb)) { + struct folio *folio; + + folio = erofs_fscache_get_folio(sbi->bootstrap, index); + if (IS_ERR(folio)) + page = (struct page *)folio; + else + page = folio_page(folio, 0); + } else { + mapping = sb->s_bdev->bd_inode->i_mapping; + page = read_cache_page_gfp(mapping, index, mapping_gfp_constraint(mapping, ~__GFP_FS)); + } if (IS_ERR(page)) return page; /* should already be PageUptodate, no need to lock page */ diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c index 6a55f7b5f883..91377939b4f7 100644 --- a/fs/erofs/fscache.c +++ b/fs/erofs/fscache.c @@ -46,9 +46,43 @@ static inline int erofs_fscache_read_folio(struct fscache_cookie *cookie, pstart); } +static int erofs_fscache_readpage_blob(struct file *data, struct page *page) +{ + int ret; + struct erofs_fscache *ctx = (struct erofs_fscache *)data; + struct folio *folio = page_folio(page); + + ret = erofs_fscache_read_folio(ctx->cookie, folio, folio_pos(folio)); + if (!ret) + folio_mark_uptodate(folio); + + folio_unlock(folio); + return ret; +} + static const struct address_space_operations erofs_fscache_blob_aops = { + .readpage = erofs_fscache_readpage_blob, }; +/* + * erofs_fscache_get_folio - find and read page cache of blob file + * @ctx: the context of the blob file + * @index: the page index + * + * Get the page cache of the blob file at the index offset. It will find the + * page through the address space of the anonymous inode. This function is only + * used to read page cache of bootstrap blob file (metadata), since currently + * only bootstrap blob file manages an anonymous inode inside the fscache + * context. + * + * Return: up to date page on success, ERR_PTR() on failure. + */ +struct folio *erofs_fscache_get_folio(struct erofs_fscache *ctx, pgoff_t index) +{ + DBG_BUGON(!ctx->inode); + return read_mapping_folio(ctx->inode->i_mapping, index, ctx); +} + static int erofs_fscache_init_cookie(struct erofs_fscache *ctx, char *path) { struct fscache_cookie *cookie; diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index d8c886a7491e..fa89a1e3012f 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -632,6 +632,8 @@ void erofs_exit_fscache(void); struct erofs_fscache *erofs_fscache_get(struct super_block *sb, char *path, bool need_inode); void erofs_fscache_put(struct erofs_fscache *ctx); + +struct folio *erofs_fscache_get_folio(struct erofs_fscache *ctx, pgoff_t index); #else static inline int erofs_init_fscache(void) { return 0; } static inline void erofs_exit_fscache(void) {} @@ -643,6 +645,12 @@ static inline struct erofs_fscache *erofs_fscache_get(struct super_block *sb, return ERR_PTR(-EOPNOTSUPP); } static inline void erofs_fscache_put(struct erofs_fscache *ctx) {} + +static inline struct folio *erofs_fscache_get_folio(struct erofs_fscache *ctx, + pgoff_t index) +{ + return ERR_PTR(-EOPNOTSUPP); +} #endif #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ From patchwork Fri Mar 25 12:22:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791545 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 9BA50C433EF for ; Fri, 25 Mar 2022 12:23:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1356120AbiCYMZD (ORCPT ); Fri, 25 Mar 2022 08:25:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40216 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1359089AbiCYMYt (ORCPT ); Fri, 25 Mar 2022 08:24:49 -0400 Received: from out30-45.freemail.mail.aliyun.com (out30-45.freemail.mail.aliyun.com [115.124.30.45]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 223A3D64F1; Fri, 25 Mar 2022 05:22:57 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R271e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04357;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=18;SR=0;TI=SMTPD_---0V89qR1S_1648210970; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89qR1S_1648210970) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:51 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 17/22] erofs: implement fscache-based data read for non-inline layout Date: Fri, 25 Mar 2022 20:22:18 +0800 Message-Id: <20220325122223.102958-18-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Implements the data plane of reading data from bootstrap blob file over fscache for non-inline layout. Be noted that compressed layout is not supported yet. Signed-off-by: Jeffle Xu --- fs/erofs/fscache.c | 83 +++++++++++++++++++++++++++++++++++++++++++++ fs/erofs/inode.c | 8 ++++- fs/erofs/internal.h | 5 +++ 3 files changed, 95 insertions(+), 1 deletion(-) diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c index 91377939b4f7..4a9a4e60c15d 100644 --- a/fs/erofs/fscache.c +++ b/fs/erofs/fscache.c @@ -60,10 +60,93 @@ static int erofs_fscache_readpage_blob(struct file *data, struct page *page) return ret; } +static inline int erofs_fscache_get_map(struct erofs_map_blocks *map, + struct super_block *sb) +{ + struct erofs_sb_info *sbi = EROFS_SB(sb); + + map->m_fscache = sbi->bootstrap; + return 0; +} + +static int erofs_fscache_readpage_noinline(struct folio *folio, + struct erofs_map_blocks *map) +{ + struct fscache_cookie *cookie = map->m_fscache->cookie; + /* + * 1) For FLAT_PLAIN layout, the output map.m_la shall be equal to o_la, + * and the output map.m_pa is exactly the physical address of o_la. + * 2) For CHUNK_BASED layout, the output map.m_la is rounded down to the + * nearest chunk boundary, and the output map.m_pa is actually the + * physical address of this chunk boundary. So we need to recalculate + * the actual physical address of o_la. + */ + loff_t start = map->m_pa + (map->o_la - map->m_la); + + return erofs_fscache_read_folio(cookie, folio, start); +} + +static int erofs_fscache_do_readpage(struct folio *folio) +{ + struct inode *inode = folio_file_mapping(folio)->host; + struct erofs_inode *vi = EROFS_I(inode); + struct super_block *sb = inode->i_sb; + struct erofs_map_blocks map; + int ret; + + if (erofs_inode_is_data_compressed(vi->datalayout)) { + erofs_info(sb, "compressed layout not supported yet"); + return -EOPNOTSUPP; + } + + DBG_BUGON(folio_size(folio) != EROFS_BLKSIZ); + + map.m_la = map.o_la = folio_pos(folio); + + ret = erofs_map_blocks(inode, &map, EROFS_GET_BLOCKS_RAW); + if (ret) + return ret; + + if (!(map.m_flags & EROFS_MAP_MAPPED)) { + folio_zero_range(folio, 0, folio_size(folio)); + return 0; + } + + ret = erofs_fscache_get_map(&map, sb); + if (ret) + return ret; + + switch (vi->datalayout) { + case EROFS_INODE_FLAT_PLAIN: + case EROFS_INODE_CHUNK_BASED: + return erofs_fscache_readpage_noinline(folio, &map); + default: + DBG_BUGON(1); + return -EOPNOTSUPP; + } +} + +static int erofs_fscache_readpage(struct file *file, struct page *page) +{ + struct folio *folio = page_folio(page); + int ret; + + ret = erofs_fscache_do_readpage(folio); + if (!ret) + folio_mark_uptodate(folio); + + folio_unlock(folio); + return ret; +} + static const struct address_space_operations erofs_fscache_blob_aops = { .readpage = erofs_fscache_readpage_blob, }; +const struct address_space_operations erofs_fscache_access_aops = { + .readpage = erofs_fscache_readpage, +}; + /* * erofs_fscache_get_folio - find and read page cache of blob file * @ctx: the context of the blob file diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c index ff62f84f47d3..744faf3ef9f4 100644 --- a/fs/erofs/inode.c +++ b/fs/erofs/inode.c @@ -296,7 +296,13 @@ static int erofs_fill_inode(struct inode *inode, int isdir) err = z_erofs_fill_inode(inode); goto out_unlock; } - inode->i_mapping->a_ops = &erofs_raw_access_aops; + +#ifdef CONFIG_EROFS_FS_ONDEMAND + if (erofs_is_nodev_mode(inode->i_sb)) + inode->i_mapping->a_ops = &erofs_fscache_access_aops; +#endif + if (!erofs_is_nodev_mode(inode->i_sb)) + inode->i_mapping->a_ops = &erofs_raw_access_aops; out_unlock: erofs_put_metabuf(&buf); diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index fa89a1e3012f..6537ededed51 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -442,6 +442,9 @@ struct erofs_map_blocks { unsigned short m_deviceid; char m_algorithmformat; unsigned int m_flags; + + struct erofs_fscache *m_fscache; + erofs_off_t o_la; }; /* Flags used by erofs_map_blocks_flatmode() */ @@ -634,6 +637,8 @@ struct erofs_fscache *erofs_fscache_get(struct super_block *sb, char *path, void erofs_fscache_put(struct erofs_fscache *ctx); struct folio *erofs_fscache_get_folio(struct erofs_fscache *ctx, pgoff_t index); + +extern const struct address_space_operations erofs_fscache_access_aops; #else static inline int erofs_init_fscache(void) { return 0; } static inline void erofs_exit_fscache(void) {} From patchwork Fri Mar 25 12:22:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791543 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 5E3D3C433EF for ; Fri, 25 Mar 2022 12:23:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1359038AbiCYMY5 (ORCPT ); Fri, 25 Mar 2022 08:24:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39892 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1359053AbiCYMYt (ORCPT ); Fri, 25 Mar 2022 08:24:49 -0400 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 41584D64E7; Fri, 25 Mar 2022 05:22:57 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R341e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04395;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=18;SR=0;TI=SMTPD_---0V89aFuG_1648210971; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89aFuG_1648210971) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:52 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 18/22] erofs: implement fscache-based data read for inline layout Date: Fri, 25 Mar 2022 20:22:19 +0800 Message-Id: <20220325122223.102958-19-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org This patch implements the data plane of reading data from bootstrap blob file over fscache for inline layout. For the heading non-inline part, the data plane for non-inline layout is resued, while only the tail packing part needs special handling. Signed-off-by: Jeffle Xu --- fs/erofs/fscache.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c index 4a9a4e60c15d..d75958470645 100644 --- a/fs/erofs/fscache.c +++ b/fs/erofs/fscache.c @@ -74,8 +74,9 @@ static int erofs_fscache_readpage_noinline(struct folio *folio, { struct fscache_cookie *cookie = map->m_fscache->cookie; /* - * 1) For FLAT_PLAIN layout, the output map.m_la shall be equal to o_la, - * and the output map.m_pa is exactly the physical address of o_la. + * 1) For FLAT_PLAIN and FLAT_INLINE (the heading non tail packing part) + * layout, the output map.m_la shall be equal to o_la, and the output + * map.m_pa is exactly the physical address of o_la. * 2) For CHUNK_BASED layout, the output map.m_la is rounded down to the * nearest chunk boundary, and the output map.m_pa is actually the * physical address of this chunk boundary. So we need to recalculate @@ -86,6 +87,42 @@ static int erofs_fscache_readpage_noinline(struct folio *folio, return erofs_fscache_read_folio(cookie, folio, start); } +static int erofs_fscache_readpage_inline(struct folio *folio, + struct erofs_map_blocks *map) +{ + struct inode *inode = folio_file_mapping(folio)->host; + struct super_block *sb = inode->i_sb; + struct erofs_buf buf = __EROFS_BUF_INITIALIZER; + erofs_blk_t blknr; + size_t offset, len; + void *src, *dst; + + /* + * For inline (tail packing) layout, the offset may be non-zero, which + * can be calculated from corresponding physical address directly. + * Currently only flat layout supports inline (FLAT_INLINE), and the + * output map.m_pa is exactly the physical address of o_la in this case. + */ + offset = erofs_blkoff(map->m_pa); + blknr = erofs_blknr(map->m_pa); + len = map->m_llen; + + src = erofs_read_metabuf(&buf, sb, blknr, EROFS_KMAP); + if (IS_ERR(src)) + return PTR_ERR(src); + + DBG_BUGON(folio_size(folio) != PAGE_SIZE); + + dst = kmap(folio_page(folio, 0)); + memcpy(dst, src + offset, len); + memset(dst + len, 0, PAGE_SIZE - len); + kunmap(folio_page(folio, 0)); + + erofs_put_metabuf(&buf); + + return 0; +} + static int erofs_fscache_do_readpage(struct folio *folio) { struct inode *inode = folio_file_mapping(folio)->host; @@ -116,8 +153,12 @@ static int erofs_fscache_do_readpage(struct folio *folio) if (ret) return ret; + if (map.m_flags & EROFS_MAP_META) + return erofs_fscache_readpage_inline(folio, &map); + switch (vi->datalayout) { case EROFS_INODE_FLAT_PLAIN: + case EROFS_INODE_FLAT_INLINE: case EROFS_INODE_CHUNK_BASED: return erofs_fscache_readpage_noinline(folio, &map); default: From patchwork Fri Mar 25 12:22:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791552 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 CE00BC433FE for ; Fri, 25 Mar 2022 12:23:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1359044AbiCYMZM (ORCPT ); Fri, 25 Mar 2022 08:25:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39784 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1359054AbiCYMYu (ORCPT ); Fri, 25 Mar 2022 08:24:50 -0400 Received: from out199-6.us.a.mail.aliyun.com (out199-6.us.a.mail.aliyun.com [47.90.199.6]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2126CD64FC; Fri, 25 Mar 2022 05:22:59 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R461e4;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=18;SR=0;TI=SMTPD_---0V89Vk8X_1648210973; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89Vk8X_1648210973) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:54 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 19/22] erofs: register cookie context for data blobs Date: Fri, 25 Mar 2022 20:22:20 +0800 Message-Id: <20220325122223.102958-20-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Similar to the multi device mode, erofs could be mounted from multiple blob files (one bootstrap blob file and optional multiple data blob files). In this case, each device slot contains the path of corresponding data blob file. Registers corresponding cookie context for each data blob file. Signed-off-by: Jeffle Xu --- fs/erofs/internal.h | 1 + fs/erofs/super.c | 30 ++++++++++++++++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 6537ededed51..94a118caf580 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -52,6 +52,7 @@ struct erofs_device_info { struct block_device *bdev; struct dax_device *dax_dev; u64 dax_part_off; + struct erofs_fscache *blob; u32 blocks; u32 mapped_blkaddr; diff --git a/fs/erofs/super.c b/fs/erofs/super.c index de5aeda4aea0..9a6f35e0c22b 100644 --- a/fs/erofs/super.c +++ b/fs/erofs/super.c @@ -259,15 +259,28 @@ static int erofs_init_devices(struct super_block *sb, } dis = ptr + erofs_blkoff(pos); - bdev = blkdev_get_by_path(dif->path, - FMODE_READ | FMODE_EXCL, - sb->s_type); - if (IS_ERR(bdev)) { - err = PTR_ERR(bdev); - break; + if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && + erofs_is_nodev_mode(sb)) { + struct erofs_fscache *blob; + + blob = erofs_fscache_get(sb, dif->path, false); + if (IS_ERR(blob)) { + err = PTR_ERR(blob); + break; + } + dif->blob = blob; + } else { + bdev = blkdev_get_by_path(dif->path, + FMODE_READ | FMODE_EXCL, + sb->s_type); + if (IS_ERR(bdev)) { + err = PTR_ERR(bdev); + break; + } + dif->bdev = bdev; + dif->dax_dev = fs_dax_get_by_bdev(bdev, &dif->dax_part_off); } - dif->bdev = bdev; - dif->dax_dev = fs_dax_get_by_bdev(bdev, &dif->dax_part_off); + dif->blocks = le32_to_cpu(dis->blocks); dif->mapped_blkaddr = le32_to_cpu(dis->mapped_blkaddr); sbi->total_blocks += dif->blocks; @@ -694,6 +707,7 @@ static int erofs_release_device_info(int id, void *ptr, void *data) { struct erofs_device_info *dif = ptr; + erofs_fscache_put(dif->blob); fs_put_dax(dif->dax_dev); if (dif->bdev) blkdev_put(dif->bdev, FMODE_READ | FMODE_EXCL); From patchwork Fri Mar 25 12:22:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791556 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 0202DC433F5 for ; Fri, 25 Mar 2022 12:24:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1359109AbiCYMZl (ORCPT ); Fri, 25 Mar 2022 08:25:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40416 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1359116AbiCYMYw (ORCPT ); Fri, 25 Mar 2022 08:24:52 -0400 Received: from out30-131.freemail.mail.aliyun.com (out30-131.freemail.mail.aliyun.com [115.124.30.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 22108D760E; Fri, 25 Mar 2022 05:23:02 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R181e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04395;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=18;SR=0;TI=SMTPD_---0V89rBrD_1648210975; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89rBrD_1648210975) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:55 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 20/22] erofs: implement fscache-based data read for data blobs Date: Fri, 25 Mar 2022 20:22:21 +0800 Message-Id: <20220325122223.102958-21-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Implements the data plane of reading data from data blob file over fscache. Signed-off-by: Jeffle Xu --- fs/erofs/data.c | 3 +++ fs/erofs/fscache.c | 15 +++++++++++++-- fs/erofs/internal.h | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/fs/erofs/data.c b/fs/erofs/data.c index b4571bea93d5..b9a05de3c3b2 100644 --- a/fs/erofs/data.c +++ b/fs/erofs/data.c @@ -206,6 +206,7 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map) map->m_bdev = sb->s_bdev; map->m_daxdev = EROFS_SB(sb)->dax_dev; map->m_dax_part_off = EROFS_SB(sb)->dax_part_off; + map->m_fscache = EROFS_SB(sb)->bootstrap; if (map->m_deviceid) { down_read(&devs->rwsem); @@ -217,6 +218,7 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map) map->m_bdev = dif->bdev; map->m_daxdev = dif->dax_dev; map->m_dax_part_off = dif->dax_part_off; + map->m_fscache = dif->blob; up_read(&devs->rwsem); } else if (devs->extra_devices) { down_read(&devs->rwsem); @@ -234,6 +236,7 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map) map->m_bdev = dif->bdev; map->m_daxdev = dif->dax_dev; map->m_dax_part_off = dif->dax_part_off; + map->m_fscache = dif->blob; break; } } diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c index d75958470645..cbb39657615e 100644 --- a/fs/erofs/fscache.c +++ b/fs/erofs/fscache.c @@ -63,9 +63,20 @@ static int erofs_fscache_readpage_blob(struct file *data, struct page *page) static inline int erofs_fscache_get_map(struct erofs_map_blocks *map, struct super_block *sb) { - struct erofs_sb_info *sbi = EROFS_SB(sb); + struct erofs_map_dev mdev; + int ret; + + mdev = (struct erofs_map_dev) { + .m_deviceid = map->m_deviceid, + .m_pa = map->m_pa, + }; + + ret = erofs_map_dev(sb, &mdev); + if (ret) + return ret; - map->m_fscache = sbi->bootstrap; + map->m_fscache = mdev.m_fscache; + map->m_pa = mdev.m_pa; return 0; } diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 94a118caf580..cea08f12a2c3 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -487,6 +487,7 @@ struct erofs_map_dev { struct block_device *m_bdev; struct dax_device *m_daxdev; u64 m_dax_part_off; + struct erofs_fscache *m_fscache; erofs_off_t m_pa; unsigned int m_deviceid; From patchwork Fri Mar 25 12:22:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791551 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 D0FF9C433F5 for ; Fri, 25 Mar 2022 12:23:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1354835AbiCYMZL (ORCPT ); Fri, 25 Mar 2022 08:25:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40258 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1359097AbiCYMYu (ORCPT ); Fri, 25 Mar 2022 08:24:50 -0400 Received: from out30-44.freemail.mail.aliyun.com (out30-44.freemail.mail.aliyun.com [115.124.30.44]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BAA06BE6; Fri, 25 Mar 2022 05:23:01 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R311e4;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=18;SR=0;TI=SMTPD_---0V89zY52_1648210976; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89zY52_1648210976) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:57 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 21/22] erofs: implement fscache-based data readahead Date: Fri, 25 Mar 2022 20:22:22 +0800 Message-Id: <20220325122223.102958-22-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Implements fscache-based data readahead. Also registers an individual bdi for each erofs instance to enable readahead. Signed-off-by: Jeffle Xu --- fs/erofs/fscache.c | 114 +++++++++++++++++++++++++++++++++++++++++++++ fs/erofs/super.c | 4 ++ 2 files changed, 118 insertions(+) diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c index cbb39657615e..589d1e7c2b1b 100644 --- a/fs/erofs/fscache.c +++ b/fs/erofs/fscache.c @@ -191,12 +191,126 @@ static int erofs_fscache_readpage(struct file *file, struct page *page) return ret; } +static inline size_t erofs_fscache_calc_len(struct erofs_map_blocks *map, + size_t len, size_t done) +{ + /* + * 1) For CHUNK_BASED layout, the output m_la is rounded down to the + * nearest chunk boundary, and the output m_llen actually starts from + * the start of the containing chunk. + * 2) For other cases, the output m_la is equal to o_la. + */ + size_t length = map->m_llen - (map->o_la - map->m_la); + + return min_t(size_t, length, len - done); +} + +static inline void erofs_fscache_unlock_folios(struct readahead_control *rac, + size_t len) +{ + while (len) { + struct folio *folio = readahead_folio(rac); + + len -= folio_size(folio); + folio_mark_uptodate(folio); + folio_unlock(folio); + } +} + +static void erofs_fscache_readahead(struct readahead_control *rac) +{ + struct inode *inode = rac->mapping->host; + struct erofs_inode *vi = EROFS_I(inode); + struct super_block *sb = inode->i_sb; + size_t len, done = 0; + loff_t start; + int ret; + + if (erofs_inode_is_data_compressed(vi->datalayout)) { + erofs_info(sb, "compressed layout not supported yet"); + return; + } + + if (!readahead_count(rac)) + return; + + start = readahead_pos(rac); + len = readahead_length(rac); + + do { + struct erofs_map_blocks map; + + map.m_la = map.o_la = start + done; + + ret = erofs_map_blocks(inode, &map, EROFS_GET_BLOCKS_RAW); + if (ret) + return; + + /* Read-ahead Hole + * Two cases will hit this: + * 1) EOF. Imposibble in readahead routine; + * 2) hole. Only CHUNK_BASED layout supports hole. + */ + if (!(map.m_flags & EROFS_MAP_MAPPED)) { + struct iov_iter iter; + loff_t offset = start + done; + size_t count = erofs_fscache_calc_len(&map, len, done); + + iov_iter_xarray(&iter, READ, &rac->mapping->i_pages, offset, count); + iov_iter_zero(count, &iter); + + erofs_fscache_unlock_folios(rac, count); + ret = count; + continue; + } + + ret = erofs_fscache_get_map(&map, sb); + if (ret) + return; + + /* Read-ahead Inline */ + if (map.m_flags & EROFS_MAP_META) { + struct folio *folio = readahead_folio(rac); + + ret = erofs_fscache_readpage_inline(folio, &map); + if (!ret) { + folio_mark_uptodate(folio); + ret = folio_size(folio); + } + + folio_unlock(folio); + continue; + } + + /* Read-ahead No-inline */ + if (vi->datalayout == EROFS_INODE_FLAT_PLAIN || + vi->datalayout == EROFS_INODE_FLAT_INLINE || + vi->datalayout == EROFS_INODE_CHUNK_BASED) { + struct fscache_cookie *cookie = map.m_fscache->cookie; + loff_t offset = start + done; + size_t count = erofs_fscache_calc_len(&map, len, done); + loff_t pstart = map.m_pa + (map.o_la - map.m_la); + + ret = erofs_fscache_read_folios(cookie, rac->mapping, + offset, count, pstart); + if (!ret) { + erofs_fscache_unlock_folios(rac, count); + ret = count; + } + } else { + DBG_BUGON(1); + return; + } + } while (ret > 0 && ((done += ret) < len)); +} + static const struct address_space_operations erofs_fscache_blob_aops = { .readpage = erofs_fscache_readpage_blob, }; const struct address_space_operations erofs_fscache_access_aops = { .readpage = erofs_fscache_readpage, + .readahead = erofs_fscache_readahead, }; /* diff --git a/fs/erofs/super.c b/fs/erofs/super.c index 9a6f35e0c22b..8ac400581784 100644 --- a/fs/erofs/super.c +++ b/fs/erofs/super.c @@ -619,6 +619,10 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) return PTR_ERR(bootstrap); sbi->bootstrap = bootstrap; + + err = super_setup_bdi(sb); + if (err) + return err; } err = erofs_read_superblock(sb); From patchwork Fri Mar 25 12:22:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingbo Xu X-Patchwork-Id: 12791557 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 A4E94C433F5 for ; Fri, 25 Mar 2022 12:24:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1359189AbiCYMZs (ORCPT ); Fri, 25 Mar 2022 08:25:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39864 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1359121AbiCYMYw (ORCPT ); Fri, 25 Mar 2022 08:24:52 -0400 Received: from out30-45.freemail.mail.aliyun.com (out30-45.freemail.mail.aliyun.com [115.124.30.45]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 14D7AD7616; Fri, 25 Mar 2022 05:23:03 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R651e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e04423;MF=jefflexu@linux.alibaba.com;NM=1;PH=DS;RN=18;SR=0;TI=SMTPD_---0V89qR2m_1648210978; Received: from localhost(mailfrom:jefflexu@linux.alibaba.com fp:SMTPD_---0V89qR2m_1648210978) by smtp.aliyun-inc.com(127.0.0.1); Fri, 25 Mar 2022 20:22:59 +0800 From: Jeffle Xu To: dhowells@redhat.com, linux-cachefs@redhat.com, xiang@kernel.org, chao@kernel.org, linux-erofs@lists.ozlabs.org Cc: 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, luodaowen.backend@bytedance.com, tianzichen@kuaishou.com, fannaihao@baidu.com Subject: [PATCH v6 22/22] erofs: add 'tag' mount option Date: Fri, 25 Mar 2022 20:22:23 +0800 Message-Id: <20220325122223.102958-23-jefflexu@linux.alibaba.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220325122223.102958-1-jefflexu@linux.alibaba.com> References: <20220325122223.102958-1-jefflexu@linux.alibaba.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Introduce 'tag' mount option to enable on-demand read sementics. In this case, erofs could be mounted from blob files instead of blkdev. By then users could specify the name of bootstrap blob file containing the complete erofs image. Signed-off-by: Jeffle Xu --- fs/erofs/super.c | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/fs/erofs/super.c b/fs/erofs/super.c index 8ac400581784..6ea83f36842c 100644 --- a/fs/erofs/super.c +++ b/fs/erofs/super.c @@ -403,6 +403,7 @@ enum { Opt_dax, Opt_dax_enum, Opt_device, + Opt_tag, Opt_err }; @@ -427,6 +428,7 @@ static const struct fs_parameter_spec erofs_fs_parameters[] = { fsparam_flag("dax", Opt_dax), fsparam_enum("dax", Opt_dax_enum, erofs_dax_param_enums), fsparam_string("device", Opt_device), + fsparam_string("tag", Opt_tag), {} }; @@ -522,6 +524,16 @@ static int erofs_fc_parse_param(struct fs_context *fc, } ++ctx->devs->extra_devices; break; + case Opt_tag: +#ifdef CONFIG_EROFS_FS_ONDEMAND + kfree(ctx->opt.tag); + ctx->opt.tag = kstrdup(param->string, GFP_KERNEL); + if (!ctx->opt.tag) + return -ENOMEM; +#else + errorfc(fc, "tag option not supported"); +#endif + break; default: return -ENOPARAM; } @@ -596,9 +608,14 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) sb->s_magic = EROFS_SUPER_MAGIC; - if (!sb_set_blocksize(sb, EROFS_BLKSIZ)) { - erofs_err(sb, "failed to set erofs blksize"); - return -EINVAL; + if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && erofs_is_nodev_mode(sb)) { + sb->s_blocksize = EROFS_BLKSIZ; + sb->s_blocksize_bits = LOG_BLOCK_SIZE; + } else { + if (!sb_set_blocksize(sb, EROFS_BLKSIZ)) { + erofs_err(sb, "failed to set erofs blksize"); + return -EINVAL; + } } sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); @@ -607,7 +624,6 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) sb->s_fs_info = sbi; sbi->opt = ctx->opt; - sbi->dax_dev = fs_dax_get_by_bdev(sb->s_bdev, &sbi->dax_part_off); sbi->devs = ctx->devs; ctx->devs = NULL; @@ -623,6 +639,10 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) err = super_setup_bdi(sb); if (err) return err; + + sbi->dax_dev = NULL; + } else { + sbi->dax_dev = fs_dax_get_by_bdev(sb->s_bdev, &sbi->dax_part_off); } err = erofs_read_superblock(sb); @@ -685,6 +705,11 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) static int erofs_fc_get_tree(struct fs_context *fc) { + struct erofs_fs_context *ctx = fc->fs_private; + + if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && ctx->opt.tag) + return get_tree_nodev(fc, erofs_fc_fill_super); + return get_tree_bdev(fc, erofs_fc_fill_super); } @@ -734,6 +759,7 @@ static void erofs_fc_free(struct fs_context *fc) struct erofs_fs_context *ctx = fc->fs_private; erofs_free_dev_context(ctx->devs); + kfree(ctx->opt.tag); kfree(ctx); } @@ -774,7 +800,10 @@ static void erofs_kill_sb(struct super_block *sb) WARN_ON(sb->s_magic != EROFS_SUPER_MAGIC); - kill_block_super(sb); + if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && erofs_is_nodev_mode(sb)) + generic_shutdown_super(sb); + else + kill_block_super(sb); sbi = EROFS_SB(sb); if (!sbi) @@ -896,7 +925,10 @@ static int erofs_statfs(struct dentry *dentry, struct kstatfs *buf) { struct super_block *sb = dentry->d_sb; struct erofs_sb_info *sbi = EROFS_SB(sb); - u64 id = huge_encode_dev(sb->s_bdev->bd_dev); + u64 id = 0; + + if (!IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) || !erofs_is_nodev_mode(sb)) + id = huge_encode_dev(sb->s_bdev->bd_dev); buf->f_type = sb->s_magic; buf->f_bsize = EROFS_BLKSIZ;