[RFC 14/19] erofs: introduce fscache support

Jeffle Xu jefflexu at linux.alibaba.com
Fri Dec 10 18:36:14 AEDT 2021


This patch only handles the volume cookie and data file cookie for
bootstrap. The corresponding IO path is remained to be implemented in
the following patch.

Signed-off-by: Jeffle Xu <jefflexu at linux.alibaba.com>
---
 fs/erofs/Makefile   |  2 +-
 fs/erofs/fscache.c  | 37 +++++++++++++++++++++++++++++++++++++
 fs/erofs/internal.h |  8 ++++++++
 fs/erofs/super.c    |  5 +++++
 4 files changed, 51 insertions(+), 1 deletion(-)
 create mode 100644 fs/erofs/fscache.c

diff --git a/fs/erofs/Makefile b/fs/erofs/Makefile
index 756fe2d65272..f9a3609625aa 100644
--- a/fs/erofs/Makefile
+++ b/fs/erofs/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
 obj-$(CONFIG_EROFS_FS) += erofs.o
-erofs-objs := super.o inode.o data.o namei.o dir.o utils.o pcpubuf.o
+erofs-objs := super.o inode.o data.o namei.o dir.o utils.o pcpubuf.o fscache.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
diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c
new file mode 100644
index 000000000000..cf550fdedd1e
--- /dev/null
+++ b/fs/erofs/fscache.c
@@ -0,0 +1,37 @@
+#include "internal.h"
+
+int erofs_fscache_init(struct erofs_sb_info *sbi, char *bootstrap_path)
+{
+	sbi->volume = fscache_acquire_volume("erofs", NULL, 0);
+	if (!sbi->volume) {
+		printk("fscache_acquire_volume() failed\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * TODO: @object_size is 0 since erofs can not get size of bootstrap
+	 * file.
+	 */
+	sbi->bootstrap = fscache_acquire_cookie(sbi->volume, 0,
+			 bootstrap_path, strlen(bootstrap_path),
+			 NULL, 0,
+			 1 /*TODO: we don't want FSCACHE_COOKIE_NO_DATA_TO_READ set */
+			 );
+
+	if (!sbi->bootstrap) {
+		printk("fscache_acquire_cookie() for bootstrap failed\n");
+		/* cleanup for sbi->volume is delayed to erofs_fscache_cleanup() */
+		return -EINVAL;
+	}
+
+	fscache_use_cookie(sbi->bootstrap, false);
+
+	return 0;
+}
+
+void erofs_fscache_cleanup(struct erofs_sb_info *sbi)
+{
+	fscache_unuse_cookie(sbi->bootstrap, NULL, NULL);
+	fscache_relinquish_cookie(sbi->bootstrap, false);
+	fscache_relinquish_volume(sbi->volume, 0, false);
+}
diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
index cf69d9c9cbed..8136ec63a9de 100644
--- a/fs/erofs/internal.h
+++ b/fs/erofs/internal.h
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/iomap.h>
+#include <linux/fscache.h>
 #include "erofs_fs.h"
 
 /* redefine pr_fmt "erofs: " */
@@ -106,6 +107,9 @@ struct erofs_sb_info {
 	/* pseudo inode to manage cached pages */
 	struct inode *managed_cache;
 
+	struct fscache_volume *volume;
+	struct fscache_cookie *bootstrap;
+
 	struct erofs_sb_lz4_info lz4;
 #endif	/* CONFIG_EROFS_FS_ZIP */
 	struct erofs_dev_context *devs;
@@ -569,6 +573,10 @@ static inline int z_erofs_load_lzma_config(struct super_block *sb,
 }
 #endif	/* !CONFIG_EROFS_FS_ZIP */
 
+/* fscache.c */
+int erofs_fscache_init(struct erofs_sb_info *sbi, char *bootstrap_path);
+void erofs_fscache_cleanup(struct erofs_sb_info *sbi);
+
 #define EFSCORRUPTED    EUCLEAN         /* Filesystem is corrupted */
 
 #endif	/* __EROFS_INTERNAL_H */
diff --git a/fs/erofs/super.c b/fs/erofs/super.c
index 51695f6d4449..f2a5f4cd53fd 100644
--- a/fs/erofs/super.c
+++ b/fs/erofs/super.c
@@ -665,6 +665,10 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
 	else
 		sbi->dax_dev = NULL;
 
+	err = erofs_fscache_init(sbi, ctx->opt.bootstrap_path);
+	if (err)
+		return err;
+
 	err = erofs_read_superblock(sb);
 	if (err)
 		return err;
@@ -823,6 +827,7 @@ static void erofs_kill_sb(struct super_block *sb)
 
 	erofs_free_dev_context(sbi->devs);
 	fs_put_dax(sbi->dax_dev);
+	erofs_fscache_cleanup(sbi);
 	kfree(sbi);
 	sb->s_fs_info = NULL;
 }
-- 
2.27.0



More information about the Linux-erofs mailing list