Commit e6242465 authored by Gao Xiang's avatar Gao Xiang

erofs: decouple basic mount options from fs_context

Previously, EROFS mount options are all in the basic types, so
erofs_fs_context can be directly copied with assignment. However,
when the multiple device feature is introduced, it's hard to handle
multiple device information like the other basic mount options.

Let's separate basic mount option usage from fs_context, thus
multiple device information can be handled gracefully then.

No logic changes.

Link: https://lore.kernel.org/r/20211007070224.12833-1-hsiangkao@linux.alibaba.comReviewed-by: default avatarChao Yu <chao@kernel.org>
Reviewed-by: default avatarLiu Bo <bo.liu@linux.alibaba.com>
Signed-off-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
parent 5b6e7e12
...@@ -192,7 +192,7 @@ static struct page *erofs_read_inode(struct inode *inode, ...@@ -192,7 +192,7 @@ static struct page *erofs_read_inode(struct inode *inode,
inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec; inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec;
inode->i_flags &= ~S_DAX; inode->i_flags &= ~S_DAX;
if (test_opt(&sbi->ctx, DAX_ALWAYS) && S_ISREG(inode->i_mode) && if (test_opt(&sbi->opt, DAX_ALWAYS) && S_ISREG(inode->i_mode) &&
vi->datalayout == EROFS_INODE_FLAT_PLAIN) vi->datalayout == EROFS_INODE_FLAT_PLAIN)
inode->i_flags |= S_DAX; inode->i_flags |= S_DAX;
if (!nblks) if (!nblks)
......
...@@ -47,7 +47,7 @@ typedef u64 erofs_off_t; ...@@ -47,7 +47,7 @@ typedef u64 erofs_off_t;
/* data type for filesystem-wide blocks number */ /* data type for filesystem-wide blocks number */
typedef u32 erofs_blk_t; typedef u32 erofs_blk_t;
struct erofs_fs_context { struct erofs_mount_opts {
#ifdef CONFIG_EROFS_FS_ZIP #ifdef CONFIG_EROFS_FS_ZIP
/* current strategy of how to use managed cache */ /* current strategy of how to use managed cache */
unsigned char cache_strategy; unsigned char cache_strategy;
...@@ -60,6 +60,10 @@ struct erofs_fs_context { ...@@ -60,6 +60,10 @@ struct erofs_fs_context {
unsigned int mount_opt; unsigned int mount_opt;
}; };
struct erofs_fs_context {
struct erofs_mount_opts opt;
};
/* all filesystem-wide lz4 configurations */ /* all filesystem-wide lz4 configurations */
struct erofs_sb_lz4_info { struct erofs_sb_lz4_info {
/* # of pages needed for EROFS lz4 rolling decompression */ /* # of pages needed for EROFS lz4 rolling decompression */
...@@ -69,6 +73,8 @@ struct erofs_sb_lz4_info { ...@@ -69,6 +73,8 @@ struct erofs_sb_lz4_info {
}; };
struct erofs_sb_info { struct erofs_sb_info {
struct erofs_mount_opts opt; /* options */
#ifdef CONFIG_EROFS_FS_ZIP #ifdef CONFIG_EROFS_FS_ZIP
/* list for all registered superblocks, mainly for shrinker */ /* list for all registered superblocks, mainly for shrinker */
struct list_head list; struct list_head list;
...@@ -108,8 +114,6 @@ struct erofs_sb_info { ...@@ -108,8 +114,6 @@ struct erofs_sb_info {
u8 volume_name[16]; /* volume name */ u8 volume_name[16]; /* volume name */
u32 feature_compat; u32 feature_compat;
u32 feature_incompat; u32 feature_incompat;
struct erofs_fs_context ctx; /* options */
}; };
#define EROFS_SB(sb) ((struct erofs_sb_info *)(sb)->s_fs_info) #define EROFS_SB(sb) ((struct erofs_sb_info *)(sb)->s_fs_info)
...@@ -121,9 +125,9 @@ struct erofs_sb_info { ...@@ -121,9 +125,9 @@ struct erofs_sb_info {
#define EROFS_MOUNT_DAX_ALWAYS 0x00000040 #define EROFS_MOUNT_DAX_ALWAYS 0x00000040
#define EROFS_MOUNT_DAX_NEVER 0x00000080 #define EROFS_MOUNT_DAX_NEVER 0x00000080
#define clear_opt(ctx, option) ((ctx)->mount_opt &= ~EROFS_MOUNT_##option) #define clear_opt(opt, option) ((opt)->mount_opt &= ~EROFS_MOUNT_##option)
#define set_opt(ctx, option) ((ctx)->mount_opt |= EROFS_MOUNT_##option) #define set_opt(opt, option) ((opt)->mount_opt |= EROFS_MOUNT_##option)
#define test_opt(ctx, option) ((ctx)->mount_opt & EROFS_MOUNT_##option) #define test_opt(opt, option) ((opt)->mount_opt & EROFS_MOUNT_##option)
enum { enum {
EROFS_ZIP_CACHE_DISABLED, EROFS_ZIP_CACHE_DISABLED,
......
...@@ -340,15 +340,15 @@ static int erofs_read_superblock(struct super_block *sb) ...@@ -340,15 +340,15 @@ static int erofs_read_superblock(struct super_block *sb)
static void erofs_default_options(struct erofs_fs_context *ctx) static void erofs_default_options(struct erofs_fs_context *ctx)
{ {
#ifdef CONFIG_EROFS_FS_ZIP #ifdef CONFIG_EROFS_FS_ZIP
ctx->cache_strategy = EROFS_ZIP_CACHE_READAROUND; ctx->opt.cache_strategy = EROFS_ZIP_CACHE_READAROUND;
ctx->max_sync_decompress_pages = 3; ctx->opt.max_sync_decompress_pages = 3;
ctx->readahead_sync_decompress = false; ctx->opt.readahead_sync_decompress = false;
#endif #endif
#ifdef CONFIG_EROFS_FS_XATTR #ifdef CONFIG_EROFS_FS_XATTR
set_opt(ctx, XATTR_USER); set_opt(&ctx->opt, XATTR_USER);
#endif #endif
#ifdef CONFIG_EROFS_FS_POSIX_ACL #ifdef CONFIG_EROFS_FS_POSIX_ACL
set_opt(ctx, POSIX_ACL); set_opt(&ctx->opt, POSIX_ACL);
#endif #endif
} }
...@@ -392,12 +392,12 @@ static bool erofs_fc_set_dax_mode(struct fs_context *fc, unsigned int mode) ...@@ -392,12 +392,12 @@ static bool erofs_fc_set_dax_mode(struct fs_context *fc, unsigned int mode)
switch (mode) { switch (mode) {
case EROFS_MOUNT_DAX_ALWAYS: case EROFS_MOUNT_DAX_ALWAYS:
warnfc(fc, "DAX enabled. Warning: EXPERIMENTAL, use at your own risk"); warnfc(fc, "DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
set_opt(ctx, DAX_ALWAYS); set_opt(&ctx->opt, DAX_ALWAYS);
clear_opt(ctx, DAX_NEVER); clear_opt(&ctx->opt, DAX_NEVER);
return true; return true;
case EROFS_MOUNT_DAX_NEVER: case EROFS_MOUNT_DAX_NEVER:
set_opt(ctx, DAX_NEVER); set_opt(&ctx->opt, DAX_NEVER);
clear_opt(ctx, DAX_ALWAYS); clear_opt(&ctx->opt, DAX_ALWAYS);
return true; return true;
default: default:
DBG_BUGON(1); DBG_BUGON(1);
...@@ -424,9 +424,9 @@ static int erofs_fc_parse_param(struct fs_context *fc, ...@@ -424,9 +424,9 @@ static int erofs_fc_parse_param(struct fs_context *fc,
case Opt_user_xattr: case Opt_user_xattr:
#ifdef CONFIG_EROFS_FS_XATTR #ifdef CONFIG_EROFS_FS_XATTR
if (result.boolean) if (result.boolean)
set_opt(ctx, XATTR_USER); set_opt(&ctx->opt, XATTR_USER);
else else
clear_opt(ctx, XATTR_USER); clear_opt(&ctx->opt, XATTR_USER);
#else #else
errorfc(fc, "{,no}user_xattr options not supported"); errorfc(fc, "{,no}user_xattr options not supported");
#endif #endif
...@@ -434,16 +434,16 @@ static int erofs_fc_parse_param(struct fs_context *fc, ...@@ -434,16 +434,16 @@ static int erofs_fc_parse_param(struct fs_context *fc,
case Opt_acl: case Opt_acl:
#ifdef CONFIG_EROFS_FS_POSIX_ACL #ifdef CONFIG_EROFS_FS_POSIX_ACL
if (result.boolean) if (result.boolean)
set_opt(ctx, POSIX_ACL); set_opt(&ctx->opt, POSIX_ACL);
else else
clear_opt(ctx, POSIX_ACL); clear_opt(&ctx->opt, POSIX_ACL);
#else #else
errorfc(fc, "{,no}acl options not supported"); errorfc(fc, "{,no}acl options not supported");
#endif #endif
break; break;
case Opt_cache_strategy: case Opt_cache_strategy:
#ifdef CONFIG_EROFS_FS_ZIP #ifdef CONFIG_EROFS_FS_ZIP
ctx->cache_strategy = result.uint_32; ctx->opt.cache_strategy = result.uint_32;
#else #else
errorfc(fc, "compression not supported, cache_strategy ignored"); errorfc(fc, "compression not supported, cache_strategy ignored");
#endif #endif
...@@ -540,15 +540,16 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) ...@@ -540,15 +540,16 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
return -ENOMEM; return -ENOMEM;
sb->s_fs_info = sbi; sb->s_fs_info = sbi;
sbi->opt = ctx->opt;
sbi->dax_dev = fs_dax_get_by_bdev(sb->s_bdev); sbi->dax_dev = fs_dax_get_by_bdev(sb->s_bdev);
err = erofs_read_superblock(sb); err = erofs_read_superblock(sb);
if (err) if (err)
return err; return err;
if (test_opt(ctx, DAX_ALWAYS) && if (test_opt(&sbi->opt, DAX_ALWAYS) &&
!dax_supported(sbi->dax_dev, sb->s_bdev, EROFS_BLKSIZ, 0, bdev_nr_sectors(sb->s_bdev))) { !dax_supported(sbi->dax_dev, sb->s_bdev, EROFS_BLKSIZ, 0, bdev_nr_sectors(sb->s_bdev))) {
errorfc(fc, "DAX unsupported by block device. Turning off DAX."); errorfc(fc, "DAX unsupported by block device. Turning off DAX.");
clear_opt(ctx, DAX_ALWAYS); clear_opt(&sbi->opt, DAX_ALWAYS);
} }
sb->s_flags |= SB_RDONLY | SB_NOATIME; sb->s_flags |= SB_RDONLY | SB_NOATIME;
sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_maxbytes = MAX_LFS_FILESIZE;
...@@ -557,13 +558,11 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) ...@@ -557,13 +558,11 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
sb->s_op = &erofs_sops; sb->s_op = &erofs_sops;
sb->s_xattr = erofs_xattr_handlers; sb->s_xattr = erofs_xattr_handlers;
if (test_opt(ctx, POSIX_ACL)) if (test_opt(&sbi->opt, POSIX_ACL))
sb->s_flags |= SB_POSIXACL; sb->s_flags |= SB_POSIXACL;
else else
sb->s_flags &= ~SB_POSIXACL; sb->s_flags &= ~SB_POSIXACL;
sbi->ctx = *ctx;
#ifdef CONFIG_EROFS_FS_ZIP #ifdef CONFIG_EROFS_FS_ZIP
xa_init(&sbi->managed_pslots); xa_init(&sbi->managed_pslots);
#endif #endif
...@@ -607,12 +606,12 @@ static int erofs_fc_reconfigure(struct fs_context *fc) ...@@ -607,12 +606,12 @@ static int erofs_fc_reconfigure(struct fs_context *fc)
DBG_BUGON(!sb_rdonly(sb)); DBG_BUGON(!sb_rdonly(sb));
if (test_opt(ctx, POSIX_ACL)) if (test_opt(&ctx->opt, POSIX_ACL))
fc->sb_flags |= SB_POSIXACL; fc->sb_flags |= SB_POSIXACL;
else else
fc->sb_flags &= ~SB_POSIXACL; fc->sb_flags &= ~SB_POSIXACL;
sbi->ctx = *ctx; sbi->opt = ctx->opt;
fc->sb_flags |= SB_RDONLY; fc->sb_flags |= SB_RDONLY;
return 0; return 0;
...@@ -640,7 +639,6 @@ static int erofs_init_fs_context(struct fs_context *fc) ...@@ -640,7 +639,6 @@ static int erofs_init_fs_context(struct fs_context *fc)
erofs_default_options(fc->fs_private); erofs_default_options(fc->fs_private);
fc->ops = &erofs_context_ops; fc->ops = &erofs_context_ops;
return 0; return 0;
} }
...@@ -763,31 +761,31 @@ static int erofs_statfs(struct dentry *dentry, struct kstatfs *buf) ...@@ -763,31 +761,31 @@ static int erofs_statfs(struct dentry *dentry, struct kstatfs *buf)
static int erofs_show_options(struct seq_file *seq, struct dentry *root) static int erofs_show_options(struct seq_file *seq, struct dentry *root)
{ {
struct erofs_sb_info *sbi = EROFS_SB(root->d_sb); struct erofs_sb_info *sbi = EROFS_SB(root->d_sb);
struct erofs_fs_context *ctx = &sbi->ctx; struct erofs_mount_opts *opt = &sbi->opt;
#ifdef CONFIG_EROFS_FS_XATTR #ifdef CONFIG_EROFS_FS_XATTR
if (test_opt(ctx, XATTR_USER)) if (test_opt(opt, XATTR_USER))
seq_puts(seq, ",user_xattr"); seq_puts(seq, ",user_xattr");
else else
seq_puts(seq, ",nouser_xattr"); seq_puts(seq, ",nouser_xattr");
#endif #endif
#ifdef CONFIG_EROFS_FS_POSIX_ACL #ifdef CONFIG_EROFS_FS_POSIX_ACL
if (test_opt(ctx, POSIX_ACL)) if (test_opt(opt, POSIX_ACL))
seq_puts(seq, ",acl"); seq_puts(seq, ",acl");
else else
seq_puts(seq, ",noacl"); seq_puts(seq, ",noacl");
#endif #endif
#ifdef CONFIG_EROFS_FS_ZIP #ifdef CONFIG_EROFS_FS_ZIP
if (ctx->cache_strategy == EROFS_ZIP_CACHE_DISABLED) if (opt->cache_strategy == EROFS_ZIP_CACHE_DISABLED)
seq_puts(seq, ",cache_strategy=disabled"); seq_puts(seq, ",cache_strategy=disabled");
else if (ctx->cache_strategy == EROFS_ZIP_CACHE_READAHEAD) else if (opt->cache_strategy == EROFS_ZIP_CACHE_READAHEAD)
seq_puts(seq, ",cache_strategy=readahead"); seq_puts(seq, ",cache_strategy=readahead");
else if (ctx->cache_strategy == EROFS_ZIP_CACHE_READAROUND) else if (opt->cache_strategy == EROFS_ZIP_CACHE_READAROUND)
seq_puts(seq, ",cache_strategy=readaround"); seq_puts(seq, ",cache_strategy=readaround");
#endif #endif
if (test_opt(ctx, DAX_ALWAYS)) if (test_opt(opt, DAX_ALWAYS))
seq_puts(seq, ",dax=always"); seq_puts(seq, ",dax=always");
if (test_opt(ctx, DAX_NEVER)) if (test_opt(opt, DAX_NEVER))
seq_puts(seq, ",dax=never"); seq_puts(seq, ",dax=never");
return 0; return 0;
} }
......
...@@ -429,7 +429,7 @@ static int shared_getxattr(struct inode *inode, struct getxattr_iter *it) ...@@ -429,7 +429,7 @@ static int shared_getxattr(struct inode *inode, struct getxattr_iter *it)
static bool erofs_xattr_user_list(struct dentry *dentry) static bool erofs_xattr_user_list(struct dentry *dentry)
{ {
return test_opt(&EROFS_SB(dentry->d_sb)->ctx, XATTR_USER); return test_opt(&EROFS_SB(dentry->d_sb)->opt, XATTR_USER);
} }
static bool erofs_xattr_trusted_list(struct dentry *dentry) static bool erofs_xattr_trusted_list(struct dentry *dentry)
...@@ -476,7 +476,7 @@ static int erofs_xattr_generic_get(const struct xattr_handler *handler, ...@@ -476,7 +476,7 @@ static int erofs_xattr_generic_get(const struct xattr_handler *handler,
switch (handler->flags) { switch (handler->flags) {
case EROFS_XATTR_INDEX_USER: case EROFS_XATTR_INDEX_USER:
if (!test_opt(&sbi->ctx, XATTR_USER)) if (!test_opt(&sbi->opt, XATTR_USER))
return -EOPNOTSUPP; return -EOPNOTSUPP;
break; break;
case EROFS_XATTR_INDEX_TRUSTED: case EROFS_XATTR_INDEX_TRUSTED:
......
...@@ -695,7 +695,7 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe, ...@@ -695,7 +695,7 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe,
goto err_out; goto err_out;
/* preload all compressed pages (maybe downgrade role if necessary) */ /* preload all compressed pages (maybe downgrade role if necessary) */
if (should_alloc_managed_pages(fe, sbi->ctx.cache_strategy, map->m_la)) if (should_alloc_managed_pages(fe, sbi->opt.cache_strategy, map->m_la))
cache_strategy = TRYALLOC; cache_strategy = TRYALLOC;
else else
cache_strategy = DONTALLOC; cache_strategy = DONTALLOC;
...@@ -796,7 +796,7 @@ static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io, ...@@ -796,7 +796,7 @@ static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io,
/* Use workqueue and sync decompression for atomic contexts only */ /* Use workqueue and sync decompression for atomic contexts only */
if (in_atomic() || irqs_disabled()) { if (in_atomic() || irqs_disabled()) {
queue_work(z_erofs_workqueue, &io->u.work); queue_work(z_erofs_workqueue, &io->u.work);
sbi->ctx.readahead_sync_decompress = true; sbi->opt.readahead_sync_decompress = true;
return; return;
} }
z_erofs_decompressqueue_work(&io->u.work); z_erofs_decompressqueue_work(&io->u.work);
...@@ -1411,8 +1411,8 @@ static void z_erofs_readahead(struct readahead_control *rac) ...@@ -1411,8 +1411,8 @@ static void z_erofs_readahead(struct readahead_control *rac)
struct erofs_sb_info *const sbi = EROFS_I_SB(inode); struct erofs_sb_info *const sbi = EROFS_I_SB(inode);
unsigned int nr_pages = readahead_count(rac); unsigned int nr_pages = readahead_count(rac);
bool sync = (sbi->ctx.readahead_sync_decompress && bool sync = (sbi->opt.readahead_sync_decompress &&
nr_pages <= sbi->ctx.max_sync_decompress_pages); nr_pages <= sbi->opt.max_sync_decompress_pages);
struct z_erofs_decompress_frontend f = DECOMPRESS_FRONTEND_INIT(inode); struct z_erofs_decompress_frontend f = DECOMPRESS_FRONTEND_INIT(inode);
struct page *page, *head = NULL; struct page *page, *head = NULL;
LIST_HEAD(pagepool); LIST_HEAD(pagepool);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment