From: Jingbo Xu jefflexu@linux.alibaba.com
anolis inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IB5UKT
Reference: https://gitee.com/anolis/cloud-kernel/commit/770910348d2b
--------------------------------
ANBZ: #4201
This optimization is inspired by [1].
When the on-demand routine is triggered, the user daemon will fetch data from remote and then write the fetched data to the backing file with DIRECT IO to avoid double page cache. When the on-demand routine finishes, the process requesting for IO will read data from the backing file (also with DIRECT IO). This mechanism will cause read latency since these two DIRECT IO.
To optimize this, make the user daemon buffer write the backing file. Make the process requesting for IO read data from the page cache of the backing file first if there's any, and otherwise fallback to the DIRECT IO.
Be noted that this patch only refactors the write routine to buffered IO, because the read routine prior to the refactoring of FsCache/Cachefiles, i.e. cachefiles_read_backing_file_one() in the normal read path and cachefiles_prepare_read() in the readahead path, has already worked in this way of trying to buffer read first.
Link: [1] https://github.com/dragonflyoss/image-service/blob/master/contrib/kernel-pat... Signed-off-by: Jingbo Xu jefflexu@linux.alibaba.com Reviewed-by: Joseph Qi joseph.qi@linux.alibaba.com Link: https://gitee.com/anolis/cloud-kernel/pulls/1252 Signed-off-by: Zizhi Wo wozizhi@huawei.com Signed-off-by: Baokun Li libaokun1@huawei.com --- fs/cachefiles/ondemand.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c index 250b98e9820c..950dc5a71cb6 100644 --- a/fs/cachefiles/ondemand.c +++ b/fs/cachefiles/ondemand.c @@ -3,8 +3,12 @@ #include <linux/file.h> #include <linux/anon_inodes.h> #include <linux/uio.h> +#include <linux/module.h> #include "internal.h"
+static bool cachefiles_buffered_ondemand = true; +module_param_named(buffered_ondemand, cachefiles_buffered_ondemand, bool, 0644); + static int cachefiles_ondemand_fd_release(struct inode *inode, struct file *file) { @@ -52,13 +56,23 @@ static ssize_t cachefiles_ondemand_fd_write_iter(struct kiocb *kiocb, { struct cachefiles_object *object = kiocb->ki_filp->private_data; size_t len = iter->count; - loff_t pos = kiocb->ki_pos; + struct kiocb iocb; int ret;
if (!object->file) return -ENOBUFS;
- ret = vfs_iter_write(object->file, iter, &pos, 0); + iocb = (struct kiocb) { + .ki_filp = object->file, + .ki_pos = kiocb->ki_pos, + .ki_flags = IOCB_WRITE, + .ki_ioprio = get_current_ioprio(), + }; + + if (!cachefiles_buffered_ondemand) + iocb.ki_flags |= IOCB_DIRECT; + + ret = vfs_iocb_iter_write(object->file, &iocb, iter); if (ret != len) return -EIO; return len;