From: Jia Zhu zhujia.zj@bytedance.com
anolis inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IB5UKT
Reference: https://gitee.com/anolis/cloud-kernel/commit/f232efaaee43
--------------------------------
ANBZ: #3234
commit a9849560c55e9e4ab9c53d073363dd6e19ec06ef upstream.
Use a pseudo mnt to manage shared cookies.
Signed-off-by: Jia Zhu zhujia.zj@bytedance.com Reviewed-by: Jingbo Xu jefflexu@linux.alibaba.com Link: https://lore.kernel.org/r/20220918043456.147-5-zhujia.zj@bytedance.com Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com 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/893 Signed-off-by: Baokun Li libaokun1@huawei.com --- fs/erofs/fscache.c | 13 +++++++++++++ fs/erofs/internal.h | 1 + fs/erofs/super.c | 33 +++++++++++++++++++++++++++++++-- 3 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c index e6e68436a493..f99e2fd3a146 100644 --- a/fs/erofs/fscache.c +++ b/fs/erofs/fscache.c @@ -7,6 +7,7 @@
static DEFINE_MUTEX(erofs_domain_list_lock); static LIST_HEAD(erofs_domain_list); +static struct vfsmount *erofs_pseudo_mnt;
struct fscache_netfs erofs_fscache_netfs = { .name = "erofs", @@ -279,6 +280,10 @@ static void erofs_fscache_domain_put(struct erofs_domain *domain) mutex_lock(&erofs_domain_list_lock); if (refcount_dec_and_test(&domain->ref)) { list_del(&domain->list); + if (list_empty(&erofs_domain_list)) { + kern_unmount(erofs_pseudo_mnt); + erofs_pseudo_mnt = NULL; + } mutex_unlock(&erofs_domain_list_lock); fscache_relinquish_cookie(domain->volume, NULL, false); kfree(domain->domain_id); @@ -335,6 +340,14 @@ static int erofs_fscache_init_domain(struct super_block *sb) if (err) goto out;
+ if (!erofs_pseudo_mnt) { + erofs_pseudo_mnt = kern_mount(&erofs_fs_type); + if (IS_ERR(erofs_pseudo_mnt)) { + err = PTR_ERR(erofs_pseudo_mnt); + goto out; + } + } + domain->volume = sbi->volume; refcount_set(&domain->ref, 1); list_add(&domain->list, &erofs_domain_list); diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 339b21fffe50..7ec852b7d59d 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -329,6 +329,7 @@ static inline unsigned int erofs_inode_datalayout(unsigned int value) }
extern const struct super_operations erofs_sops; +extern struct file_system_type erofs_fs_type;
extern const struct address_space_operations erofs_raw_access_aops; extern const struct address_space_operations z_erofs_aops; diff --git a/fs/erofs/super.c b/fs/erofs/super.c index 0149e8cb44e6..7b24b6952d30 100644 --- a/fs/erofs/super.c +++ b/fs/erofs/super.c @@ -473,6 +473,13 @@ static int erofs_init_managed_cache(struct super_block *sb) static int erofs_init_managed_cache(struct super_block *sb) { return 0; } #endif
+static int erofs_fc_fill_pseudo_super(struct super_block *sb, struct fs_context *fc) +{ + static const struct tree_descr empty_descr = {""}; + + return simple_fill_super(sb, EROFS_SUPER_MAGIC, &empty_descr); +} + static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) { struct inode *inode; @@ -555,6 +562,11 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) return 0; }
+static int erofs_fc_anon_get_tree(struct fs_context *fc) +{ + return get_tree_nodev(fc, erofs_fc_fill_pseudo_super); +} + static int erofs_fc_get_tree(struct fs_context *fc) { struct erofs_fs_context *ctx = fc->fs_private; @@ -622,10 +634,21 @@ static const struct fs_context_operations erofs_context_ops = { .free = erofs_fc_free, };
+static const struct fs_context_operations erofs_anon_context_ops = { + .get_tree = erofs_fc_anon_get_tree, +}; + static int erofs_init_fs_context(struct fs_context *fc) { - struct erofs_fs_context *ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + struct erofs_fs_context *ctx; + + /* pseudo mount for anon inodes */ + if (fc->sb_flags & SB_KERNMOUNT) { + fc->ops = &erofs_anon_context_ops; + return 0; + }
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; ctx->devs = kzalloc(sizeof(struct erofs_dev_context), GFP_KERNEL); @@ -652,6 +675,12 @@ static void erofs_kill_sb(struct super_block *sb)
WARN_ON(sb->s_magic != EROFS_SUPER_MAGIC);
+ /* pseudo mount for anon inodes */ + if (sb->s_flags & SB_KERNMOUNT) { + kill_anon_super(sb); + return; + } + if (erofs_is_fscache_mode(sb)) kill_anon_super(sb); else @@ -683,7 +712,7 @@ static void erofs_put_super(struct super_block *sb) sbi->s_fscache = NULL; }
-static struct file_system_type erofs_fs_type = { +struct file_system_type erofs_fs_type = { .owner = THIS_MODULE, .name = "erofs", .init_fs_context = erofs_init_fs_context,