lkml.org 
[lkml]   [2022]   [Aug]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[RFC PATCH 5/5] erofs: support fscache based shared domain
Date
Several erofs filesystems can belong to one domain, and data blobs can
be shared among these erofs filesystems of same domain.

Users could specify domain_id mount option to create or join into a domain.

Signed-off-by: Jia Zhu <zhujia.zj@bytedance.com>
---
fs/erofs/domain.c | 60 +++++++++++++++++++++++++++++++++++++++++++++
fs/erofs/fscache.c | 7 ++++++
fs/erofs/internal.h | 13 ++++++++++
fs/erofs/super.c | 10 ++++++--
4 files changed, 88 insertions(+), 2 deletions(-)

diff --git a/fs/erofs/domain.c b/fs/erofs/domain.c
index 6461e4ee3582..ea7b591b7db1 100644
--- a/fs/erofs/domain.c
+++ b/fs/erofs/domain.c
@@ -13,6 +13,66 @@
static DEFINE_SPINLOCK(erofs_domain_list_lock);
static LIST_HEAD(erofs_domain_list);

+static int erofs_fscache_domain_init_cookie(struct super_block *sb,
+ struct erofs_fscache **fscache, char *name, bool need_inode)
+{
+ int ret;
+ struct inode *inode;
+ struct erofs_fscache *ctx;
+ struct erofs_sb_info *sbi = EROFS_SB(sb);
+ struct erofs_domain *domain = sbi->domain;
+
+ ret = erofs_fscache_register_cookie(sb, &ctx, name, need_inode);
+ if (ret)
+ return ret;
+
+ ctx->name = kstrdup(name, GFP_KERNEL);
+ if (!ctx->name)
+ return -ENOMEM;
+
+ inode = new_inode(domain->mnt->mnt_sb);
+ if (!inode) {
+ kfree(ctx->name);
+ return -ENOMEM;
+ }
+
+ ctx->domain = domain;
+ ctx->anon_inode = inode;
+ inode->i_private = ctx;
+ refcount_set(&ctx->ref, 1);
+ erofs_fscache_domain_get(domain);
+ *fscache = ctx;
+ return 0;
+}
+
+int erofs_domain_register_cookie(struct super_block *sb,
+ struct erofs_fscache **fscache, char *name, bool need_inode)
+{
+ int err;
+ struct inode *inode;
+ struct erofs_fscache *ctx;
+ struct erofs_sb_info *sbi = EROFS_SB(sb);
+ struct erofs_domain *domain = sbi->domain;
+ struct super_block *psb = domain->mnt->mnt_sb;
+
+ mutex_lock(&domain->mutex);
+ list_for_each_entry(inode, &psb->s_inodes, i_sb_list) {
+ ctx = inode->i_private;
+ if (!ctx)
+ continue;
+ if (!strcmp(ctx->name, name)) {
+ *fscache = ctx;
+ refcount_inc(&ctx->ref);
+ mutex_unlock(&domain->mutex);
+ return 0;
+ }
+ }
+ err = erofs_fscache_domain_init_cookie(sb, fscache, name, need_inode);
+ mutex_unlock(&domain->mutex);
+
+ return err;
+}
+
void erofs_fscache_domain_get(struct erofs_domain *domain)
{
if (!domain)
diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c
index 5c918a06ae9a..51425e310e3d 100644
--- a/fs/erofs/fscache.c
+++ b/fs/erofs/fscache.c
@@ -476,6 +476,8 @@ void erofs_fscache_unregister_cookie(struct erofs_fscache **fscache)

if (!ctx)
return;
+ if (ctx->domain && !refcount_dec_and_test(&ctx->ref))
+ return;

fscache_unuse_cookie(ctx->cookie, NULL, NULL);
fscache_relinquish_cookie(ctx->cookie, false);
@@ -483,7 +485,12 @@ void erofs_fscache_unregister_cookie(struct erofs_fscache **fscache)

iput(ctx->inode);
ctx->inode = NULL;
+ iput(ctx->anon_inode);
+ ctx->anon_inode = NULL;
+ erofs_fscache_domain_put(ctx->domain);

+ kfree(ctx->name);
+ ctx->name = NULL;
kfree(ctx);
*fscache = NULL;
}
diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
index bca4e9c57890..1abdad81bfe3 100644
--- a/fs/erofs/internal.h
+++ b/fs/erofs/internal.h
@@ -109,8 +109,12 @@ struct erofs_domain {
};

struct erofs_fscache {
+ refcount_t ref;
struct fscache_cookie *cookie;
struct inode *inode;
+ struct inode *anon_inode;
+ struct erofs_domain *domain;
+ char *name;
};

struct erofs_sb_info {
@@ -627,6 +631,9 @@ int erofs_fscache_register_domain(struct super_block *sb);
int erofs_fscache_register_cookie(struct super_block *sb,
struct erofs_fscache **fscache,
char *name, bool need_inode);
+int erofs_domain_register_cookie(struct super_block *sb,
+ struct erofs_fscache **fscache,
+ char *name, bool need_inode);
void erofs_fscache_unregister_cookie(struct erofs_fscache **fscache);

extern const struct address_space_operations erofs_fscache_access_aops;
@@ -648,6 +655,12 @@ static inline int erofs_fscache_register_cookie(struct super_block *sb,
{
return -EOPNOTSUPP;
}
+static inline int erofs_domain_register_cookie(struct super_block *sb,
+ struct erofs_fscache **fscache,
+ char *name, bool need_inode)
+{
+ return -EOPNOTSUPP;
+}

static inline void erofs_fscache_unregister_cookie(struct erofs_fscache **fscache)
{
diff --git a/fs/erofs/super.c b/fs/erofs/super.c
index bbc63b7d546c..aefe7dfcd4c9 100644
--- a/fs/erofs/super.c
+++ b/fs/erofs/super.c
@@ -245,8 +245,12 @@ static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb,
}

if (erofs_is_fscache_mode(sb)) {
- ret = erofs_fscache_register_cookie(sb, &dif->fscache,
- dif->path, false);
+ if (sbi->opt.domain_id)
+ ret = erofs_domain_register_cookie(sb, &dif->fscache, dif->path,
+ false);
+ else
+ ret = erofs_fscache_register_cookie(sb, &dif->fscache, dif->path,
+ false);
if (ret)
return ret;
} else {
@@ -719,6 +723,8 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
err = erofs_fscache_register_domain(sb);
if (err)
return err;
+ err = erofs_domain_register_cookie(sb, &sbi->s_fscache,
+ sbi->opt.fsid, true);
} else {
err = erofs_fscache_register_fs(sb);
if (err)
--
2.20.1
\
 
 \ /
  Last update: 2022-08-31 14:33    [W:0.211 / U:0.892 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site