From: Gao Xiang hsiangkao@linux.alibaba.com
anolis inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IB5UKT
Reference: https://gitee.com/anolis/cloud-kernel/commit/30d2fb2e9a8e
--------------------------------
ANBZ: #1666
commit 3c265d7dcefab21a58ca5454c0f778412bde0870 upstream.
Introduce one anonymous inode for data blobs so that erofs can cache metadata directly within such anonymous inode.
Signed-off-by: Jeffle Xu jefflexu@linux.alibaba.com Reviewed-by: Gao Xiang hsiangkao@linux.alibaba.com Link: https://lore.kernel.org/r/20220425122143.56815-14-jefflexu@linux.alibaba.com Acked-by: Chao Yu chao@kernel.org Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Signed-off-by: Huang Jianan jnhuang@linux.alibaba.com Reviewed-by: Jeffle Xu jefflexu@linux.alibaba.com Signed-off-by: Baokun Li libaokun1@huawei.com --- fs/erofs/fscache.c | 39 ++++++++++++++++++++++++++++++++++++--- fs/erofs/internal.h | 6 ++++-- 2 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c index fbda7da6ced9..7659f8ae65c3 100644 --- a/fs/erofs/fscache.c +++ b/fs/erofs/fscache.c @@ -30,11 +30,16 @@ const struct fscache_cookie_def erofs_fscache_inode_object_def = { .type = FSCACHE_COOKIE_TYPE_DATAFILE, };
+static const struct address_space_operations erofs_fscache_meta_aops = { +}; + int erofs_fscache_register_cookie(struct super_block *sb, - struct erofs_fscache **fscache, char *name) + struct erofs_fscache **fscache, + char *name, bool need_inode) { struct erofs_fscache *ctx; struct fscache_cookie *cookie; + int ret;
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) @@ -46,15 +51,40 @@ int erofs_fscache_register_cookie(struct super_block *sb, NULL, 0, NULL, 0, true); if (!cookie) { erofs_err(sb, "failed to get cookie for %s", name); - kfree(ctx); - return -EINVAL; + ret = -EINVAL; + goto err; }
//fscache_use_cookie(cookie, false); ctx->cookie = cookie;
+ if (need_inode) { + struct inode *const inode = new_inode(sb); + + if (!inode) { + erofs_err(sb, "failed to get anon inode for %s", name); + ret = -ENOMEM; + goto err_cookie; + } + + set_nlink(inode, 1); + inode->i_size = OFFSET_MAX; + inode->i_mapping->a_ops = &erofs_fscache_meta_aops; + mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); + + ctx->inode = inode; + } + *fscache = ctx; return 0; + +err_cookie: +// fscache_unuse_cookie(ctx->cookie, NULL, NULL); + fscache_relinquish_cookie(ctx->cookie, NULL, false); + ctx->cookie = NULL; +err: + kfree(ctx); + return ret; }
void erofs_fscache_unregister_cookie(struct erofs_fscache **fscache) @@ -68,6 +98,9 @@ void erofs_fscache_unregister_cookie(struct erofs_fscache **fscache) fscache_relinquish_cookie(ctx->cookie, NULL, false); ctx->cookie = NULL;
+ iput(ctx->inode); + ctx->inode = NULL; + kfree(ctx); *fscache = NULL; } diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index cd89fb654a11..22844d047566 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -81,6 +81,7 @@ struct erofs_fs_context {
struct erofs_fscache { struct fscache_cookie *cookie; + struct inode *inode; };
struct erofs_sb_info { @@ -484,7 +485,8 @@ int erofs_fscache_register_fs(struct super_block *sb); void erofs_fscache_unregister_fs(struct super_block *sb);
int erofs_fscache_register_cookie(struct super_block *sb, - struct erofs_fscache **fscache, char *name); + struct erofs_fscache **fscache, + char *name, bool need_inode); void erofs_fscache_unregister_cookie(struct erofs_fscache **fscache); #else static inline int erofs_fscache_register(void) @@ -500,7 +502,7 @@ static inline void erofs_fscache_unregister_fs(struct super_block *sb) {}
static inline int erofs_fscache_register_cookie(struct super_block *sb, struct erofs_fscache **fscache, - char *name) + char *name, bool need_inode) { return -EOPNOTSUPP; }