mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 09:16:33 +00:00
jfs: convert jfs to use the new mount api
Convert the jfs filesystem to use the new mount API. Tested by comparing random mount & remount options before and after the change. Signed-off-by: Eric Sandeen <sandeen@redhat.com> Link: https://lore.kernel.org/r/20240926171947.682881-1-sandeen@redhat.com Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
5b00a0f96d
commit
945be8ca81
@ -24,6 +24,7 @@
|
|||||||
#define JFS_ERR_REMOUNT_RO 0x00000002 /* remount read-only */
|
#define JFS_ERR_REMOUNT_RO 0x00000002 /* remount read-only */
|
||||||
#define JFS_ERR_CONTINUE 0x00000004 /* continue */
|
#define JFS_ERR_CONTINUE 0x00000004 /* continue */
|
||||||
#define JFS_ERR_PANIC 0x00000008 /* panic */
|
#define JFS_ERR_PANIC 0x00000008 /* panic */
|
||||||
|
#define JFS_ERR_MASK (JFS_ERR_REMOUNT_RO|JFS_ERR_CONTINUE|JFS_ERR_PANIC)
|
||||||
|
|
||||||
/* Quota support */
|
/* Quota support */
|
||||||
#define JFS_USRQUOTA 0x00000010
|
#define JFS_USRQUOTA 0x00000010
|
||||||
|
465
fs/jfs/super.c
465
fs/jfs/super.c
@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/parser.h>
|
|
||||||
#include <linux/completion.h>
|
#include <linux/completion.h>
|
||||||
#include <linux/vfs.h>
|
#include <linux/vfs.h>
|
||||||
#include <linux/quotaops.h>
|
#include <linux/quotaops.h>
|
||||||
#include <linux/mount.h>
|
#include <linux/fs_context.h>
|
||||||
|
#include <linux/fs_parser.h>
|
||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/posix_acl.h>
|
#include <linux/posix_acl.h>
|
||||||
@ -210,240 +210,195 @@ enum {
|
|||||||
Opt_discard, Opt_nodiscard, Opt_discard_minblk
|
Opt_discard, Opt_nodiscard, Opt_discard_minblk
|
||||||
};
|
};
|
||||||
|
|
||||||
static const match_table_t tokens = {
|
static const struct constant_table jfs_param_errors[] = {
|
||||||
{Opt_integrity, "integrity"},
|
{"continue", JFS_ERR_CONTINUE},
|
||||||
{Opt_nointegrity, "nointegrity"},
|
{"remount-ro", JFS_ERR_REMOUNT_RO},
|
||||||
{Opt_iocharset, "iocharset=%s"},
|
{"panic", JFS_ERR_PANIC},
|
||||||
{Opt_resize, "resize=%u"},
|
{}
|
||||||
{Opt_resize_nosize, "resize"},
|
|
||||||
{Opt_errors, "errors=%s"},
|
|
||||||
{Opt_ignore, "noquota"},
|
|
||||||
{Opt_quota, "quota"},
|
|
||||||
{Opt_usrquota, "usrquota"},
|
|
||||||
{Opt_grpquota, "grpquota"},
|
|
||||||
{Opt_uid, "uid=%u"},
|
|
||||||
{Opt_gid, "gid=%u"},
|
|
||||||
{Opt_umask, "umask=%u"},
|
|
||||||
{Opt_discard, "discard"},
|
|
||||||
{Opt_nodiscard, "nodiscard"},
|
|
||||||
{Opt_discard_minblk, "discard=%u"},
|
|
||||||
{Opt_err, NULL}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
|
static const struct fs_parameter_spec jfs_param_spec[] = {
|
||||||
int *flag)
|
fsparam_flag_no ("integrity", Opt_integrity),
|
||||||
|
fsparam_string ("iocharset", Opt_iocharset),
|
||||||
|
fsparam_u64 ("resize", Opt_resize),
|
||||||
|
fsparam_flag ("resize", Opt_resize_nosize),
|
||||||
|
fsparam_enum ("errors", Opt_errors, jfs_param_errors),
|
||||||
|
fsparam_flag ("quota", Opt_quota),
|
||||||
|
fsparam_flag ("noquota", Opt_ignore),
|
||||||
|
fsparam_flag ("usrquota", Opt_usrquota),
|
||||||
|
fsparam_flag ("grpquota", Opt_grpquota),
|
||||||
|
fsparam_uid ("uid", Opt_uid),
|
||||||
|
fsparam_gid ("gid", Opt_gid),
|
||||||
|
fsparam_u32oct ("umask", Opt_umask),
|
||||||
|
fsparam_flag ("discard", Opt_discard),
|
||||||
|
fsparam_u32 ("discard", Opt_discard_minblk),
|
||||||
|
fsparam_flag ("nodiscard", Opt_nodiscard),
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jfs_context {
|
||||||
|
int flag;
|
||||||
|
kuid_t uid;
|
||||||
|
kgid_t gid;
|
||||||
|
uint umask;
|
||||||
|
uint minblks_trim;
|
||||||
|
void *nls_map;
|
||||||
|
bool resize;
|
||||||
|
s64 newLVSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int jfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
||||||
{
|
{
|
||||||
void *nls_map = (void *)-1; /* -1: no change; NULL: none */
|
struct jfs_context *ctx = fc->fs_private;
|
||||||
char *p;
|
int reconfigure = (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE);
|
||||||
struct jfs_sb_info *sbi = JFS_SBI(sb);
|
struct fs_parse_result result;
|
||||||
|
struct nls_table *nls_map;
|
||||||
|
int opt;
|
||||||
|
|
||||||
*newLVSize = 0;
|
opt = fs_parse(fc, jfs_param_spec, param, &result);
|
||||||
|
if (opt < 0)
|
||||||
|
return opt;
|
||||||
|
|
||||||
if (!options)
|
switch (opt) {
|
||||||
return 1;
|
case Opt_integrity:
|
||||||
|
if (result.negated)
|
||||||
while ((p = strsep(&options, ",")) != NULL) {
|
ctx->flag |= JFS_NOINTEGRITY;
|
||||||
substring_t args[MAX_OPT_ARGS];
|
else
|
||||||
int token;
|
ctx->flag &= ~JFS_NOINTEGRITY;
|
||||||
if (!*p)
|
break;
|
||||||
continue;
|
case Opt_ignore:
|
||||||
|
/* Silently ignore the quota options */
|
||||||
token = match_token(p, tokens, args);
|
/* Don't do anything ;-) */
|
||||||
switch (token) {
|
break;
|
||||||
case Opt_integrity:
|
case Opt_iocharset:
|
||||||
*flag &= ~JFS_NOINTEGRITY;
|
if (ctx->nls_map && ctx->nls_map != (void *) -1) {
|
||||||
break;
|
unload_nls(ctx->nls_map);
|
||||||
case Opt_nointegrity:
|
ctx->nls_map = NULL;
|
||||||
*flag |= JFS_NOINTEGRITY;
|
}
|
||||||
break;
|
if (!strcmp(param->string, "none"))
|
||||||
case Opt_ignore:
|
ctx->nls_map = NULL;
|
||||||
/* Silently ignore the quota options */
|
else {
|
||||||
/* Don't do anything ;-) */
|
nls_map = load_nls(param->string);
|
||||||
break;
|
if (!nls_map) {
|
||||||
case Opt_iocharset:
|
pr_err("JFS: charset not found\n");
|
||||||
if (nls_map && nls_map != (void *) -1)
|
return -EINVAL;
|
||||||
unload_nls(nls_map);
|
|
||||||
if (!strcmp(args[0].from, "none"))
|
|
||||||
nls_map = NULL;
|
|
||||||
else {
|
|
||||||
nls_map = load_nls(args[0].from);
|
|
||||||
if (!nls_map) {
|
|
||||||
pr_err("JFS: charset not found\n");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
ctx->nls_map = nls_map;
|
||||||
case Opt_resize:
|
|
||||||
{
|
|
||||||
char *resize = args[0].from;
|
|
||||||
int rc = kstrtoll(resize, 0, newLVSize);
|
|
||||||
|
|
||||||
if (rc)
|
|
||||||
goto cleanup;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Opt_resize_nosize:
|
|
||||||
{
|
|
||||||
*newLVSize = sb_bdev_nr_blocks(sb);
|
|
||||||
if (*newLVSize == 0)
|
|
||||||
pr_err("JFS: Cannot determine volume size\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Opt_errors:
|
|
||||||
{
|
|
||||||
char *errors = args[0].from;
|
|
||||||
if (!errors || !*errors)
|
|
||||||
goto cleanup;
|
|
||||||
if (!strcmp(errors, "continue")) {
|
|
||||||
*flag &= ~JFS_ERR_REMOUNT_RO;
|
|
||||||
*flag &= ~JFS_ERR_PANIC;
|
|
||||||
*flag |= JFS_ERR_CONTINUE;
|
|
||||||
} else if (!strcmp(errors, "remount-ro")) {
|
|
||||||
*flag &= ~JFS_ERR_CONTINUE;
|
|
||||||
*flag &= ~JFS_ERR_PANIC;
|
|
||||||
*flag |= JFS_ERR_REMOUNT_RO;
|
|
||||||
} else if (!strcmp(errors, "panic")) {
|
|
||||||
*flag &= ~JFS_ERR_CONTINUE;
|
|
||||||
*flag &= ~JFS_ERR_REMOUNT_RO;
|
|
||||||
*flag |= JFS_ERR_PANIC;
|
|
||||||
} else {
|
|
||||||
pr_err("JFS: %s is an invalid error handler\n",
|
|
||||||
errors);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case Opt_resize:
|
||||||
|
if (!reconfigure)
|
||||||
|
return -EINVAL;
|
||||||
|
ctx->resize = true;
|
||||||
|
ctx->newLVSize = result.uint_64;
|
||||||
|
break;
|
||||||
|
case Opt_resize_nosize:
|
||||||
|
if (!reconfigure)
|
||||||
|
return -EINVAL;
|
||||||
|
ctx->resize = true;
|
||||||
|
break;
|
||||||
|
case Opt_errors:
|
||||||
|
ctx->flag &= ~JFS_ERR_MASK;
|
||||||
|
ctx->flag |= result.uint_32;
|
||||||
|
break;
|
||||||
|
|
||||||
#ifdef CONFIG_QUOTA
|
#ifdef CONFIG_QUOTA
|
||||||
case Opt_quota:
|
case Opt_quota:
|
||||||
case Opt_usrquota:
|
case Opt_usrquota:
|
||||||
*flag |= JFS_USRQUOTA;
|
ctx->flag |= JFS_USRQUOTA;
|
||||||
break;
|
break;
|
||||||
case Opt_grpquota:
|
case Opt_grpquota:
|
||||||
*flag |= JFS_GRPQUOTA;
|
ctx->flag |= JFS_GRPQUOTA;
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
case Opt_usrquota:
|
case Opt_usrquota:
|
||||||
case Opt_grpquota:
|
case Opt_grpquota:
|
||||||
case Opt_quota:
|
case Opt_quota:
|
||||||
pr_err("JFS: quota operations not supported\n");
|
pr_err("JFS: quota operations not supported\n");
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case Opt_uid:
|
case Opt_uid:
|
||||||
{
|
ctx->uid = result.uid;
|
||||||
char *uid = args[0].from;
|
break;
|
||||||
uid_t val;
|
|
||||||
int rc = kstrtouint(uid, 0, &val);
|
|
||||||
|
|
||||||
if (rc)
|
case Opt_gid:
|
||||||
goto cleanup;
|
ctx->gid = result.gid;
|
||||||
sbi->uid = make_kuid(current_user_ns(), val);
|
break;
|
||||||
if (!uid_valid(sbi->uid))
|
|
||||||
goto cleanup;
|
case Opt_umask:
|
||||||
break;
|
if (result.uint_32 & ~0777) {
|
||||||
|
pr_err("JFS: Invalid value of umask\n");
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
ctx->umask = result.uint_32;
|
||||||
|
break;
|
||||||
|
|
||||||
case Opt_gid:
|
case Opt_discard:
|
||||||
{
|
/* if set to 1, even copying files will cause
|
||||||
char *gid = args[0].from;
|
* trimming :O
|
||||||
gid_t val;
|
* -> user has more control over the online trimming
|
||||||
int rc = kstrtouint(gid, 0, &val);
|
*/
|
||||||
|
ctx->minblks_trim = 64;
|
||||||
|
ctx->flag |= JFS_DISCARD;
|
||||||
|
break;
|
||||||
|
|
||||||
if (rc)
|
case Opt_nodiscard:
|
||||||
goto cleanup;
|
ctx->flag &= ~JFS_DISCARD;
|
||||||
sbi->gid = make_kgid(current_user_ns(), val);
|
break;
|
||||||
if (!gid_valid(sbi->gid))
|
|
||||||
goto cleanup;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Opt_umask:
|
case Opt_discard_minblk:
|
||||||
{
|
ctx->minblks_trim = result.uint_32;
|
||||||
char *umask = args[0].from;
|
ctx->flag |= JFS_DISCARD;
|
||||||
int rc = kstrtouint(umask, 8, &sbi->umask);
|
break;
|
||||||
|
|
||||||
if (rc)
|
default:
|
||||||
goto cleanup;
|
return -EINVAL;
|
||||||
if (sbi->umask & ~0777) {
|
|
||||||
pr_err("JFS: Invalid value of umask\n");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Opt_discard:
|
|
||||||
/* if set to 1, even copying files will cause
|
|
||||||
* trimming :O
|
|
||||||
* -> user has more control over the online trimming
|
|
||||||
*/
|
|
||||||
sbi->minblks_trim = 64;
|
|
||||||
if (bdev_max_discard_sectors(sb->s_bdev))
|
|
||||||
*flag |= JFS_DISCARD;
|
|
||||||
else
|
|
||||||
pr_err("JFS: discard option not supported on device\n");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Opt_nodiscard:
|
|
||||||
*flag &= ~JFS_DISCARD;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Opt_discard_minblk:
|
|
||||||
{
|
|
||||||
char *minblks_trim = args[0].from;
|
|
||||||
int rc;
|
|
||||||
if (bdev_max_discard_sectors(sb->s_bdev)) {
|
|
||||||
*flag |= JFS_DISCARD;
|
|
||||||
rc = kstrtouint(minblks_trim, 0,
|
|
||||||
&sbi->minblks_trim);
|
|
||||||
if (rc)
|
|
||||||
goto cleanup;
|
|
||||||
} else
|
|
||||||
pr_err("JFS: discard option not supported on device\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
printk("jfs: Unrecognized mount option \"%s\" or missing value\n",
|
|
||||||
p);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nls_map != (void *) -1) {
|
|
||||||
/* Discard old (if remount) */
|
|
||||||
unload_nls(sbi->nls_tab);
|
|
||||||
sbi->nls_tab = nls_map;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (nls_map && nls_map != (void *) -1)
|
|
||||||
unload_nls(nls_map);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int jfs_remount(struct super_block *sb, int *flags, char *data)
|
static int jfs_reconfigure(struct fs_context *fc)
|
||||||
{
|
{
|
||||||
s64 newLVSize = 0;
|
struct jfs_context *ctx = fc->fs_private;
|
||||||
|
struct super_block *sb = fc->root->d_sb;
|
||||||
|
int readonly = fc->sb_flags & SB_RDONLY;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int flag = JFS_SBI(sb)->flag;
|
int flag = ctx->flag;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
sync_filesystem(sb);
|
sync_filesystem(sb);
|
||||||
if (!parse_options(data, sb, &newLVSize, &flag))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (newLVSize) {
|
/* Transfer results of parsing to the sbi */
|
||||||
|
JFS_SBI(sb)->flag = ctx->flag;
|
||||||
|
JFS_SBI(sb)->uid = ctx->uid;
|
||||||
|
JFS_SBI(sb)->gid = ctx->gid;
|
||||||
|
JFS_SBI(sb)->umask = ctx->umask;
|
||||||
|
JFS_SBI(sb)->minblks_trim = ctx->minblks_trim;
|
||||||
|
if (ctx->nls_map != (void *) -1) {
|
||||||
|
unload_nls(JFS_SBI(sb)->nls_tab);
|
||||||
|
JFS_SBI(sb)->nls_tab = ctx->nls_map;
|
||||||
|
}
|
||||||
|
ctx->nls_map = NULL;
|
||||||
|
|
||||||
|
if (ctx->resize) {
|
||||||
if (sb_rdonly(sb)) {
|
if (sb_rdonly(sb)) {
|
||||||
pr_err("JFS: resize requires volume to be mounted read-write\n");
|
pr_err("JFS: resize requires volume to be mounted read-write\n");
|
||||||
return -EROFS;
|
return -EROFS;
|
||||||
}
|
}
|
||||||
rc = jfs_extendfs(sb, newLVSize, 0);
|
|
||||||
|
if (!ctx->newLVSize) {
|
||||||
|
ctx->newLVSize = sb_bdev_nr_blocks(sb);
|
||||||
|
if (ctx->newLVSize == 0)
|
||||||
|
pr_err("JFS: Cannot determine volume size\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = jfs_extendfs(sb, ctx->newLVSize, 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sb_rdonly(sb) && !(*flags & SB_RDONLY)) {
|
if (sb_rdonly(sb) && !readonly) {
|
||||||
/*
|
/*
|
||||||
* Invalidate any previously read metadata. fsck may have
|
* Invalidate any previously read metadata. fsck may have
|
||||||
* changed the on-disk data since we mounted r/o
|
* changed the on-disk data since we mounted r/o
|
||||||
@ -459,7 +414,7 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
|
|||||||
dquot_resume(sb, -1);
|
dquot_resume(sb, -1);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (!sb_rdonly(sb) && (*flags & SB_RDONLY)) {
|
if (!sb_rdonly(sb) && readonly) {
|
||||||
rc = dquot_suspend(sb, -1);
|
rc = dquot_suspend(sb, -1);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
@ -467,7 +422,7 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
|
|||||||
JFS_SBI(sb)->flag = flag;
|
JFS_SBI(sb)->flag = flag;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
if ((JFS_SBI(sb)->flag & JFS_NOINTEGRITY) != (flag & JFS_NOINTEGRITY))
|
if ((JFS_SBI(sb)->flag & JFS_NOINTEGRITY) != (flag & JFS_NOINTEGRITY)) {
|
||||||
if (!sb_rdonly(sb)) {
|
if (!sb_rdonly(sb)) {
|
||||||
rc = jfs_umount_rw(sb);
|
rc = jfs_umount_rw(sb);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -477,18 +432,20 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
|
|||||||
ret = jfs_mount_rw(sb, 1);
|
ret = jfs_mount_rw(sb, 1);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
JFS_SBI(sb)->flag = flag;
|
JFS_SBI(sb)->flag = flag;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int jfs_fill_super(struct super_block *sb, void *data, int silent)
|
static int jfs_fill_super(struct super_block *sb, struct fs_context *fc)
|
||||||
{
|
{
|
||||||
|
struct jfs_context *ctx = fc->fs_private;
|
||||||
|
int silent = fc->sb_flags & SB_SILENT;
|
||||||
struct jfs_sb_info *sbi;
|
struct jfs_sb_info *sbi;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
int rc;
|
int rc;
|
||||||
s64 newLVSize = 0;
|
int ret = -EINVAL;
|
||||||
int flag, ret = -EINVAL;
|
|
||||||
|
|
||||||
jfs_info("In jfs_read_super: s_flags=0x%lx", sb->s_flags);
|
jfs_info("In jfs_read_super: s_flags=0x%lx", sb->s_flags);
|
||||||
|
|
||||||
@ -501,24 +458,34 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
|
|||||||
sb->s_time_min = 0;
|
sb->s_time_min = 0;
|
||||||
sb->s_time_max = U32_MAX;
|
sb->s_time_max = U32_MAX;
|
||||||
sbi->sb = sb;
|
sbi->sb = sb;
|
||||||
sbi->uid = INVALID_UID;
|
|
||||||
sbi->gid = INVALID_GID;
|
|
||||||
sbi->umask = -1;
|
|
||||||
|
|
||||||
/* initialize the mount flag and determine the default error handler */
|
/* Transfer results of parsing to the sbi */
|
||||||
flag = JFS_ERR_REMOUNT_RO;
|
sbi->flag = ctx->flag;
|
||||||
|
sbi->uid = ctx->uid;
|
||||||
|
sbi->gid = ctx->gid;
|
||||||
|
sbi->umask = ctx->umask;
|
||||||
|
if (ctx->nls_map != (void *) -1) {
|
||||||
|
unload_nls(sbi->nls_tab);
|
||||||
|
sbi->nls_tab = ctx->nls_map;
|
||||||
|
}
|
||||||
|
ctx->nls_map = NULL;
|
||||||
|
|
||||||
if (!parse_options((char *) data, sb, &newLVSize, &flag))
|
if (sbi->flag & JFS_DISCARD) {
|
||||||
goto out_kfree;
|
if (!bdev_max_discard_sectors(sb->s_bdev)) {
|
||||||
sbi->flag = flag;
|
pr_err("JFS: discard option not supported on device\n");
|
||||||
|
sbi->flag &= ~JFS_DISCARD;
|
||||||
|
} else {
|
||||||
|
sbi->minblks_trim = ctx->minblks_trim;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_JFS_POSIX_ACL
|
#ifdef CONFIG_JFS_POSIX_ACL
|
||||||
sb->s_flags |= SB_POSIXACL;
|
sb->s_flags |= SB_POSIXACL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (newLVSize) {
|
if (ctx->resize) {
|
||||||
pr_err("resize option for remount only\n");
|
pr_err("resize option for remount only\n");
|
||||||
goto out_kfree;
|
goto out_unload;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -608,7 +575,6 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
|
|||||||
sbi->direct_inode = NULL;
|
sbi->direct_inode = NULL;
|
||||||
out_unload:
|
out_unload:
|
||||||
unload_nls(sbi->nls_tab);
|
unload_nls(sbi->nls_tab);
|
||||||
out_kfree:
|
|
||||||
kfree(sbi);
|
kfree(sbi);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -664,10 +630,9 @@ static int jfs_unfreeze(struct super_block *sb)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dentry *jfs_do_mount(struct file_system_type *fs_type,
|
static int jfs_get_tree(struct fs_context *fc)
|
||||||
int flags, const char *dev_name, void *data)
|
|
||||||
{
|
{
|
||||||
return mount_bdev(fs_type, flags, dev_name, data, jfs_fill_super);
|
return get_tree_bdev(fc, jfs_fill_super);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int jfs_sync_fs(struct super_block *sb, int wait)
|
static int jfs_sync_fs(struct super_block *sb, int wait)
|
||||||
@ -886,7 +851,6 @@ static const struct super_operations jfs_super_operations = {
|
|||||||
.freeze_fs = jfs_freeze,
|
.freeze_fs = jfs_freeze,
|
||||||
.unfreeze_fs = jfs_unfreeze,
|
.unfreeze_fs = jfs_unfreeze,
|
||||||
.statfs = jfs_statfs,
|
.statfs = jfs_statfs,
|
||||||
.remount_fs = jfs_remount,
|
|
||||||
.show_options = jfs_show_options,
|
.show_options = jfs_show_options,
|
||||||
#ifdef CONFIG_QUOTA
|
#ifdef CONFIG_QUOTA
|
||||||
.quota_read = jfs_quota_read,
|
.quota_read = jfs_quota_read,
|
||||||
@ -902,12 +866,71 @@ static const struct export_operations jfs_export_operations = {
|
|||||||
.get_parent = jfs_get_parent,
|
.get_parent = jfs_get_parent,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void jfs_init_options(struct fs_context *fc, struct jfs_context *ctx)
|
||||||
|
{
|
||||||
|
if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) {
|
||||||
|
struct super_block *sb = fc->root->d_sb;
|
||||||
|
|
||||||
|
/* Copy over current option values and mount flags */
|
||||||
|
ctx->uid = JFS_SBI(sb)->uid;
|
||||||
|
ctx->gid = JFS_SBI(sb)->gid;
|
||||||
|
ctx->umask = JFS_SBI(sb)->umask;
|
||||||
|
ctx->nls_map = (void *)-1;
|
||||||
|
ctx->minblks_trim = JFS_SBI(sb)->minblks_trim;
|
||||||
|
ctx->flag = JFS_SBI(sb)->flag;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Initialize the mount flag and determine the default
|
||||||
|
* error handler
|
||||||
|
*/
|
||||||
|
ctx->flag = JFS_ERR_REMOUNT_RO;
|
||||||
|
ctx->uid = INVALID_UID;
|
||||||
|
ctx->gid = INVALID_GID;
|
||||||
|
ctx->umask = -1;
|
||||||
|
ctx->nls_map = (void *)-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void jfs_free_fc(struct fs_context *fc)
|
||||||
|
{
|
||||||
|
struct jfs_context *ctx = fc->fs_private;
|
||||||
|
|
||||||
|
if (ctx->nls_map != (void *) -1)
|
||||||
|
unload_nls(ctx->nls_map);
|
||||||
|
kfree(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct fs_context_operations jfs_context_ops = {
|
||||||
|
.parse_param = jfs_parse_param,
|
||||||
|
.get_tree = jfs_get_tree,
|
||||||
|
.reconfigure = jfs_reconfigure,
|
||||||
|
.free = jfs_free_fc,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int jfs_init_fs_context(struct fs_context *fc)
|
||||||
|
{
|
||||||
|
struct jfs_context *ctx;
|
||||||
|
|
||||||
|
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
|
||||||
|
if (!ctx)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
jfs_init_options(fc, ctx);
|
||||||
|
|
||||||
|
fc->fs_private = ctx;
|
||||||
|
fc->ops = &jfs_context_ops;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct file_system_type jfs_fs_type = {
|
static struct file_system_type jfs_fs_type = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "jfs",
|
.name = "jfs",
|
||||||
.mount = jfs_do_mount,
|
|
||||||
.kill_sb = kill_block_super,
|
.kill_sb = kill_block_super,
|
||||||
.fs_flags = FS_REQUIRES_DEV,
|
.fs_flags = FS_REQUIRES_DEV,
|
||||||
|
.init_fs_context = jfs_init_fs_context,
|
||||||
|
.parameters = jfs_param_spec,
|
||||||
};
|
};
|
||||||
MODULE_ALIAS_FS("jfs");
|
MODULE_ALIAS_FS("jfs");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user