On Wed, Apr 06, 2022 at 03:56:02PM +0800, Jeffle Xu wrote:
> A new fscache based mode is going to be introduced for erofs, in which
> case on-demand read semantics is implemented through fscache.
> 
> As the first step, register fscache volume for each erofs filesystem.
> That means, data blobs can not be shared among erofs filesystems. In the
> following iteration, we are going to introduce the domain semantics, in
> which case several erofs filesystems can belong to one domain, and data
> blobs can be shared among these erofs filesystems of one domain.
> 
> Signed-off-by: Jeffle Xu <jeffl...@linux.alibaba.com>

Reviewed-by: Gao Xiang <hsiang...@linux.alibaba.com>

Thanks,
Gao Xiang

> ---
>  fs/erofs/Kconfig    | 10 ++++++++++
>  fs/erofs/Makefile   |  1 +
>  fs/erofs/fscache.c  | 37 +++++++++++++++++++++++++++++++++++++
>  fs/erofs/internal.h | 13 +++++++++++++
>  fs/erofs/super.c    |  7 +++++++
>  5 files changed, 68 insertions(+)
>  create mode 100644 fs/erofs/fscache.c
> 
> diff --git a/fs/erofs/Kconfig b/fs/erofs/Kconfig
> index f57255ab88ed..3d05265e3e8e 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 ondemand-read"
> +     depends on CACHEFILES_ONDEMAND && (EROFS_FS=m && FSCACHE || EROFS_FS=y 
> && FSCACHE=y)
> +     default n
> +     help
> +       EROFS is mounted from data blobs and on-demand read semantics is
> +       implemented 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..7a6d0239ebb1
> --- /dev/null
> +++ b/fs/erofs/fscache.c
> @@ -0,0 +1,37 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2022, Alibaba Cloud
> + */
> +#include <linux/fscache.h>
> +#include "internal.h"
> +
> +int erofs_fscache_register_fs(struct super_block *sb)
> +{
> +     struct erofs_sb_info *sbi = EROFS_SB(sb);
> +     struct fscache_volume *volume;
> +     char *name;
> +     int ret = 0;
> +
> +     name = kasprintf(GFP_KERNEL, "erofs,%s", sbi->opt.fsid);
> +     if (!name)
> +             return -ENOMEM;
> +
> +     volume = fscache_acquire_volume(name, NULL, NULL, 0);
> +     if (IS_ERR_OR_NULL(volume)) {
> +             erofs_err(sb, "failed to register volume for %s", name);
> +             ret = volume ? PTR_ERR(volume) : -EOPNOTSUPP;
> +             volume = NULL;
> +     }
> +
> +     sbi->volume = volume;
> +     kfree(name);
> +     return ret;
> +}
> +
> +void erofs_fscache_unregister_fs(struct super_block *sb)
> +{
> +     struct erofs_sb_info *sbi = EROFS_SB(sb);
> +
> +     fscache_relinquish_volume(sbi->volume, NULL, false);
> +     sbi->volume = NULL;
> +}
> diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
> index 05a97533b1e9..952a2f483f94 100644
> --- a/fs/erofs/internal.h
> +++ b/fs/erofs/internal.h
> @@ -74,6 +74,7 @@ struct erofs_mount_opts {
>       unsigned int max_sync_decompress_pages;
>  #endif
>       unsigned int mount_opt;
> +     char *fsid;
>  };
>  
>  struct erofs_dev_context {
> @@ -146,6 +147,9 @@ struct erofs_sb_info {
>       /* sysfs support */
>       struct kobject s_kobj;          /* /sys/fs/erofs/<devname> */
>       struct completion s_kobj_unregister;
> +
> +     /* fscache support */
> +     struct fscache_volume *volume;
>  };
>  
>  #define EROFS_SB(sb) ((struct erofs_sb_info *)(sb)->s_fs_info)
> @@ -618,6 +622,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_fscache_register_fs(struct super_block *sb);
> +void erofs_fscache_unregister_fs(struct super_block *sb);
> +#else
> +static inline int erofs_fscache_register_fs(struct super_block *sb) { return 
> 0; }
> +static inline void erofs_fscache_unregister_fs(struct super_block *sb) {}
> +#endif
> +
>  #define EFSCORRUPTED    EUCLEAN         /* Filesystem is corrupted */
>  
>  #endif       /* __EROFS_INTERNAL_H */
> diff --git a/fs/erofs/super.c b/fs/erofs/super.c
> index 0c4b41130c2f..6590ed1b7d3b 100644
> --- a/fs/erofs/super.c
> +++ b/fs/erofs/super.c
> @@ -601,6 +601,12 @@ static int erofs_fc_fill_super(struct super_block *sb, 
> struct fs_context *fc)
>       sbi->devs = ctx->devs;
>       ctx->devs = NULL;
>  
> +     if (erofs_is_fscache_mode(sb)) {
> +             err = erofs_fscache_register_fs(sb);
> +             if (err)
> +                     return err;
> +     }
> +
>       err = erofs_read_superblock(sb);
>       if (err)
>               return err;
> @@ -757,6 +763,7 @@ static void erofs_kill_sb(struct super_block *sb)
>  
>       erofs_free_dev_context(sbi->devs);
>       fs_put_dax(sbi->dax_dev);
> +     erofs_fscache_unregister_fs(sb);
>       kfree(sbi);
>       sb->s_fs_info = NULL;
>  }
> -- 
> 2.27.0

--
Linux-cachefs mailing list
Linux-cachefs@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-cachefs

Reply via email to