Commit 1b17a46c authored by Eric Sandeen's avatar Eric Sandeen Committed by Jan Kara

isofs: convert isofs to use the new mount API

This also renames iso9660_options to isofs_options, for
consistency.
Signed-off-by: default avatarEric Sandeen <sandeen@redhat.com>
cc: Jan Kara <jack@suse.cz>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
Message-Id: <409e28da-9c19-427a-acfb-78788f0a23b8@redhat.com>
parent 5a6cb47e
...@@ -21,11 +21,12 @@ ...@@ -21,11 +21,12 @@
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/statfs.h> #include <linux/statfs.h>
#include <linux/cdrom.h> #include <linux/cdrom.h>
#include <linux/parser.h>
#include <linux/mpage.h> #include <linux/mpage.h>
#include <linux/user_namespace.h> #include <linux/user_namespace.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/fs_context.h>
#include <linux/fs_parser.h>
#include "isofs.h" #include "isofs.h"
#include "zisofs.h" #include "zisofs.h"
...@@ -110,10 +111,10 @@ static void destroy_inodecache(void) ...@@ -110,10 +111,10 @@ static void destroy_inodecache(void)
kmem_cache_destroy(isofs_inode_cachep); kmem_cache_destroy(isofs_inode_cachep);
} }
static int isofs_remount(struct super_block *sb, int *flags, char *data) static int isofs_reconfigure(struct fs_context *fc)
{ {
sync_filesystem(sb); sync_filesystem(fc->root->d_sb);
if (!(*flags & SB_RDONLY)) if (!(fc->sb_flags & SB_RDONLY))
return -EROFS; return -EROFS;
return 0; return 0;
} }
...@@ -123,7 +124,6 @@ static const struct super_operations isofs_sops = { ...@@ -123,7 +124,6 @@ static const struct super_operations isofs_sops = {
.free_inode = isofs_free_inode, .free_inode = isofs_free_inode,
.put_super = isofs_put_super, .put_super = isofs_put_super,
.statfs = isofs_statfs, .statfs = isofs_statfs,
.remount_fs = isofs_remount,
.show_options = isofs_show_options, .show_options = isofs_show_options,
}; };
...@@ -145,7 +145,7 @@ static const struct dentry_operations isofs_dentry_ops[] = { ...@@ -145,7 +145,7 @@ static const struct dentry_operations isofs_dentry_ops[] = {
#endif #endif
}; };
struct iso9660_options{ struct isofs_options{
unsigned int rock:1; unsigned int rock:1;
unsigned int joliet:1; unsigned int joliet:1;
unsigned int cruft:1; unsigned int cruft:1;
...@@ -289,197 +289,161 @@ isofs_dentry_cmpi_ms(const struct dentry *dentry, ...@@ -289,197 +289,161 @@ isofs_dentry_cmpi_ms(const struct dentry *dentry,
#endif #endif
enum { enum {
Opt_block, Opt_check_r, Opt_check_s, Opt_cruft, Opt_gid, Opt_ignore, Opt_block, Opt_check, Opt_cruft, Opt_gid, Opt_ignore, Opt_iocharset,
Opt_iocharset, Opt_map_a, Opt_map_n, Opt_map_o, Opt_mode, Opt_nojoliet, Opt_map, Opt_mode, Opt_nojoliet, Opt_norock, Opt_sb, Opt_session,
Opt_norock, Opt_sb, Opt_session, Opt_uid, Opt_unhide, Opt_utf8, Opt_err, Opt_uid, Opt_unhide, Opt_utf8, Opt_err, Opt_nocompress, Opt_hide,
Opt_nocompress, Opt_hide, Opt_showassoc, Opt_dmode, Opt_overriderockperm, Opt_showassoc, Opt_dmode, Opt_overriderockperm,
}; };
static const match_table_t tokens = { static const struct constant_table isofs_param_map[] = {
{Opt_norock, "norock"}, {"acorn", 'a'},
{Opt_nojoliet, "nojoliet"}, {"a", 'a'},
{Opt_unhide, "unhide"}, {"normal", 'n'},
{Opt_hide, "hide"}, {"n", 'n'},
{Opt_showassoc, "showassoc"}, {"off", 'o'},
{Opt_cruft, "cruft"}, {"o", 'o'},
{Opt_utf8, "utf8"}, {}
{Opt_iocharset, "iocharset=%s"},
{Opt_map_a, "map=acorn"},
{Opt_map_a, "map=a"},
{Opt_map_n, "map=normal"},
{Opt_map_n, "map=n"},
{Opt_map_o, "map=off"},
{Opt_map_o, "map=o"},
{Opt_session, "session=%u"},
{Opt_sb, "sbsector=%u"},
{Opt_check_r, "check=relaxed"},
{Opt_check_r, "check=r"},
{Opt_check_s, "check=strict"},
{Opt_check_s, "check=s"},
{Opt_uid, "uid=%u"},
{Opt_gid, "gid=%u"},
{Opt_mode, "mode=%u"},
{Opt_dmode, "dmode=%u"},
{Opt_overriderockperm, "overriderockperm"},
{Opt_block, "block=%u"},
{Opt_ignore, "conv=binary"},
{Opt_ignore, "conv=b"},
{Opt_ignore, "conv=text"},
{Opt_ignore, "conv=t"},
{Opt_ignore, "conv=mtext"},
{Opt_ignore, "conv=m"},
{Opt_ignore, "conv=auto"},
{Opt_ignore, "conv=a"},
{Opt_nocompress, "nocompress"},
{Opt_err, NULL}
}; };
static int parse_options(char *options, struct iso9660_options *popt) static const struct constant_table isofs_param_check[] = {
{ {"relaxed", 'r'},
char *p; {"r", 'r'},
int option; {"strict", 's'},
unsigned int uv; {"s", 's'},
{}
popt->map = 'n'; };
popt->rock = 1;
popt->joliet = 1;
popt->cruft = 0;
popt->hide = 0;
popt->showassoc = 0;
popt->check = 'u'; /* unset */
popt->nocompress = 0;
popt->blocksize = 1024;
popt->fmode = popt->dmode = ISOFS_INVALID_MODE;
popt->uid_set = 0;
popt->gid_set = 0;
popt->gid = GLOBAL_ROOT_GID;
popt->uid = GLOBAL_ROOT_UID;
popt->iocharset = NULL;
popt->overriderockperm = 0;
popt->session=-1;
popt->sbsector=-1;
if (!options)
return 1;
while ((p = strsep(&options, ",")) != NULL) {
int token;
substring_t args[MAX_OPT_ARGS];
unsigned n;
if (!*p)
continue;
token = match_token(p, tokens, args); static const struct fs_parameter_spec isofs_param_spec[] = {
switch (token) { fsparam_flag ("norock", Opt_norock),
case Opt_norock: fsparam_flag ("nojoliet", Opt_nojoliet),
popt->rock = 0; fsparam_flag ("unhide", Opt_unhide),
break; fsparam_flag ("hide", Opt_hide),
case Opt_nojoliet: fsparam_flag ("showassoc", Opt_showassoc),
popt->joliet = 0; fsparam_flag ("cruft", Opt_cruft),
break; fsparam_flag ("utf8", Opt_utf8),
case Opt_hide: fsparam_string ("iocharset", Opt_iocharset),
popt->hide = 1; fsparam_enum ("map", Opt_map, isofs_param_map),
break; fsparam_u32 ("session", Opt_session),
case Opt_unhide: fsparam_u32 ("sbsector", Opt_sb),
case Opt_showassoc: fsparam_enum ("check", Opt_check, isofs_param_check),
popt->showassoc = 1; fsparam_u32 ("uid", Opt_uid),
break; fsparam_u32 ("gid", Opt_gid),
case Opt_cruft: /* Note: mode/dmode historically accepted %u not strictly %o */
popt->cruft = 1; fsparam_u32 ("mode", Opt_mode),
break; fsparam_u32 ("dmode", Opt_dmode),
fsparam_flag ("overriderockperm", Opt_overriderockperm),
fsparam_u32 ("block", Opt_block),
fsparam_string ("conv", Opt_ignore),
fsparam_flag ("nocompress", Opt_nocompress),
{}
};
static int isofs_parse_param(struct fs_context *fc,
struct fs_parameter *param)
{
struct isofs_options *popt = fc->fs_private;
struct fs_parse_result result;
int opt;
kuid_t uid;
kgid_t gid;
unsigned int n;
/* There are no remountable options */
if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE)
return 0;
opt = fs_parse(fc, isofs_param_spec, param, &result);
if (opt < 0)
return opt;
switch (opt) {
case Opt_norock:
popt->rock = 0;
break;
case Opt_nojoliet:
popt->joliet = 0;
break;
case Opt_hide:
popt->hide = 1;
break;
case Opt_unhide:
case Opt_showassoc:
popt->showassoc = 1;
break;
case Opt_cruft:
popt->cruft = 1;
break;
#ifdef CONFIG_JOLIET #ifdef CONFIG_JOLIET
case Opt_utf8: case Opt_utf8:
kfree(popt->iocharset); kfree(popt->iocharset);
popt->iocharset = kstrdup("utf8", GFP_KERNEL); popt->iocharset = kstrdup("utf8", GFP_KERNEL);
if (!popt->iocharset) if (!popt->iocharset)
return 0; return -ENOMEM;
break; break;
case Opt_iocharset: case Opt_iocharset:
kfree(popt->iocharset); kfree(popt->iocharset);
popt->iocharset = match_strdup(&args[0]); popt->iocharset = kstrdup(param->string, GFP_KERNEL);
if (!popt->iocharset) if (!popt->iocharset)
return 0; return -ENOMEM;
break; break;
#endif #endif
case Opt_map_a: case Opt_map:
popt->map = 'a'; popt->map = result.uint_32;
break; break;
case Opt_map_o: case Opt_session:
popt->map = 'o'; n = result.uint_32;
break; /*
case Opt_map_n: * Track numbers are supposed to be in range 1-99, the
popt->map = 'n'; * mount option starts indexing at 0.
break; */
case Opt_session: if (n >= 99)
if (match_int(&args[0], &option)) return -EINVAL;
return 0; popt->session = n + 1;
n = option; break;
/* case Opt_sb:
* Track numbers are supposed to be in range 1-99, the popt->sbsector = result.uint_32;
* mount option starts indexing at 0. break;
*/ case Opt_check:
if (n >= 99) popt->check = result.uint_32;
return 0; break;
popt->session = n + 1; case Opt_ignore:
break; break;
case Opt_sb: case Opt_uid:
if (match_int(&args[0], &option)) uid = make_kuid(current_user_ns(), result.uint_32);
return 0; if (!uid_valid(uid))
popt->sbsector = option; return -EINVAL;
break; popt->uid = uid;
case Opt_check_r: popt->uid_set = 1;
popt->check = 'r'; break;
break; case Opt_gid:
case Opt_check_s: gid = make_kgid(current_user_ns(), result.uint_32);
popt->check = 's'; if (!gid_valid(gid))
break; return -EINVAL;
case Opt_ignore: popt->gid = gid;
break; popt->gid_set = 1;
case Opt_uid: break;
if (match_uint(&args[0], &uv)) case Opt_mode:
return 0; popt->fmode = result.uint_32;
popt->uid = make_kuid(current_user_ns(), uv); break;
if (!uid_valid(popt->uid)) case Opt_dmode:
return 0; popt->dmode = result.uint_32;
popt->uid_set = 1; break;
break; case Opt_overriderockperm:
case Opt_gid: popt->overriderockperm = 1;
if (match_uint(&args[0], &uv)) break;
return 0; case Opt_block:
popt->gid = make_kgid(current_user_ns(), uv); n = result.uint_32;
if (!gid_valid(popt->gid)) if (n != 512 && n != 1024 && n != 2048)
return 0; return -EINVAL;
popt->gid_set = 1; popt->blocksize = n;
break; break;
case Opt_mode: case Opt_nocompress:
if (match_int(&args[0], &option)) popt->nocompress = 1;
return 0; break;
popt->fmode = option; default:
break; return -EINVAL;
case Opt_dmode:
if (match_int(&args[0], &option))
return 0;
popt->dmode = option;
break;
case Opt_overriderockperm:
popt->overriderockperm = 1;
break;
case Opt_block:
if (match_int(&args[0], &option))
return 0;
n = option;
if (n != 512 && n != 1024 && n != 2048)
return 0;
popt->blocksize = n;
break;
case Opt_nocompress:
popt->nocompress = 1;
break;
default:
return 0;
}
} }
return 1; return 0;
} }
/* /*
...@@ -615,7 +579,7 @@ static bool rootdir_empty(struct super_block *sb, unsigned long block) ...@@ -615,7 +579,7 @@ static bool rootdir_empty(struct super_block *sb, unsigned long block)
/* /*
* Initialize the superblock and read the root inode. * Initialize the superblock and read the root inode.
*/ */
static int isofs_fill_super(struct super_block *s, void *data, int silent) static int isofs_fill_super(struct super_block *s, struct fs_context *fc)
{ {
struct buffer_head *bh = NULL, *pri_bh = NULL; struct buffer_head *bh = NULL, *pri_bh = NULL;
struct hs_primary_descriptor *h_pri = NULL; struct hs_primary_descriptor *h_pri = NULL;
...@@ -623,7 +587,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -623,7 +587,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
struct iso_supplementary_descriptor *sec = NULL; struct iso_supplementary_descriptor *sec = NULL;
struct iso_directory_record *rootp; struct iso_directory_record *rootp;
struct inode *inode; struct inode *inode;
struct iso9660_options opt; struct isofs_options *opt = fc->fs_private;
struct isofs_sb_info *sbi; struct isofs_sb_info *sbi;
unsigned long first_data_zone; unsigned long first_data_zone;
int joliet_level = 0; int joliet_level = 0;
...@@ -631,15 +595,13 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -631,15 +595,13 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
int orig_zonesize; int orig_zonesize;
int table, error = -EINVAL; int table, error = -EINVAL;
unsigned int vol_desc_start; unsigned int vol_desc_start;
int silent = fc->sb_flags & SB_SILENT;
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi) if (!sbi)
return -ENOMEM; return -ENOMEM;
s->s_fs_info = sbi; s->s_fs_info = sbi;
if (!parse_options((char *)data, &opt))
goto out_freesbi;
/* /*
* First of all, get the hardware blocksize for this device. * First of all, get the hardware blocksize for this device.
* If we don't know what it is, or the hardware blocksize is * If we don't know what it is, or the hardware blocksize is
...@@ -655,14 +617,14 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -655,14 +617,14 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
bdev_logical_block_size(s->s_bdev)); bdev_logical_block_size(s->s_bdev));
goto out_freesbi; goto out_freesbi;
} }
opt.blocksize = sb_min_blocksize(s, opt.blocksize); opt->blocksize = sb_min_blocksize(s, opt->blocksize);
sbi->s_high_sierra = 0; /* default is iso9660 */ sbi->s_high_sierra = 0; /* default is iso9660 */
sbi->s_session = opt.session; sbi->s_session = opt->session;
sbi->s_sbsector = opt.sbsector; sbi->s_sbsector = opt->sbsector;
vol_desc_start = (opt.sbsector != -1) ? vol_desc_start = (opt->sbsector != -1) ?
opt.sbsector : isofs_get_last_session(s,opt.session); opt->sbsector : isofs_get_last_session(s, opt->session);
for (iso_blknum = vol_desc_start+16; for (iso_blknum = vol_desc_start+16;
iso_blknum < vol_desc_start+100; iso_blknum++) { iso_blknum < vol_desc_start+100; iso_blknum++) {
...@@ -696,7 +658,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -696,7 +658,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
else if (isonum_711(vdp->type) == ISO_VD_SUPPLEMENTARY) { else if (isonum_711(vdp->type) == ISO_VD_SUPPLEMENTARY) {
sec = (struct iso_supplementary_descriptor *)vdp; sec = (struct iso_supplementary_descriptor *)vdp;
if (sec->escape[0] == 0x25 && sec->escape[1] == 0x2f) { if (sec->escape[0] == 0x25 && sec->escape[1] == 0x2f) {
if (opt.joliet) { if (opt->joliet) {
if (sec->escape[2] == 0x40) if (sec->escape[2] == 0x40)
joliet_level = 1; joliet_level = 1;
else if (sec->escape[2] == 0x43) else if (sec->escape[2] == 0x43)
...@@ -721,7 +683,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -721,7 +683,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
goto out_freebh; goto out_freebh;
sbi->s_high_sierra = 1; sbi->s_high_sierra = 1;
opt.rock = 0; opt->rock = 0;
h_pri = (struct hs_primary_descriptor *)vdp; h_pri = (struct hs_primary_descriptor *)vdp;
goto root_found; goto root_found;
} }
...@@ -749,7 +711,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -749,7 +711,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
goto out_freebh; goto out_freebh;
} }
if (joliet_level && (!pri || !opt.rock)) { if (joliet_level && (!pri || !opt->rock)) {
/* This is the case of Joliet with the norock mount flag. /* This is the case of Joliet with the norock mount flag.
* A disc with both Joliet and Rock Ridge is handled later * A disc with both Joliet and Rock Ridge is handled later
*/ */
...@@ -780,7 +742,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -780,7 +742,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
* blocks that were 512 bytes (which should only very rarely * blocks that were 512 bytes (which should only very rarely
* happen.) * happen.)
*/ */
if (orig_zonesize < opt.blocksize) if (orig_zonesize < opt->blocksize)
goto out_bad_size; goto out_bad_size;
/* RDE: convert log zone size to bit shift */ /* RDE: convert log zone size to bit shift */
...@@ -865,10 +827,10 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -865,10 +827,10 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
#ifdef CONFIG_JOLIET #ifdef CONFIG_JOLIET
if (joliet_level) { if (joliet_level) {
char *p = opt.iocharset ? opt.iocharset : CONFIG_NLS_DEFAULT; char *p = opt->iocharset ? opt->iocharset : CONFIG_NLS_DEFAULT;
if (strcmp(p, "utf8") != 0) { if (strcmp(p, "utf8") != 0) {
sbi->s_nls_iocharset = opt.iocharset ? sbi->s_nls_iocharset = opt->iocharset ?
load_nls(opt.iocharset) : load_nls_default(); load_nls(opt->iocharset) : load_nls_default();
if (!sbi->s_nls_iocharset) if (!sbi->s_nls_iocharset)
goto out_freesbi; goto out_freesbi;
} }
...@@ -876,29 +838,29 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -876,29 +838,29 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
#endif #endif
s->s_op = &isofs_sops; s->s_op = &isofs_sops;
s->s_export_op = &isofs_export_ops; s->s_export_op = &isofs_export_ops;
sbi->s_mapping = opt.map; sbi->s_mapping = opt->map;
sbi->s_rock = (opt.rock ? 2 : 0); sbi->s_rock = (opt->rock ? 2 : 0);
sbi->s_rock_offset = -1; /* initial offset, will guess until SP is found*/ sbi->s_rock_offset = -1; /* initial offset, will guess until SP is found*/
sbi->s_cruft = opt.cruft; sbi->s_cruft = opt->cruft;
sbi->s_hide = opt.hide; sbi->s_hide = opt->hide;
sbi->s_showassoc = opt.showassoc; sbi->s_showassoc = opt->showassoc;
sbi->s_uid = opt.uid; sbi->s_uid = opt->uid;
sbi->s_gid = opt.gid; sbi->s_gid = opt->gid;
sbi->s_uid_set = opt.uid_set; sbi->s_uid_set = opt->uid_set;
sbi->s_gid_set = opt.gid_set; sbi->s_gid_set = opt->gid_set;
sbi->s_nocompress = opt.nocompress; sbi->s_nocompress = opt->nocompress;
sbi->s_overriderockperm = opt.overriderockperm; sbi->s_overriderockperm = opt->overriderockperm;
/* /*
* It would be incredibly stupid to allow people to mark every file * It would be incredibly stupid to allow people to mark every file
* on the disk as suid, so we merely allow them to set the default * on the disk as suid, so we merely allow them to set the default
* permissions. * permissions.
*/ */
if (opt.fmode != ISOFS_INVALID_MODE) if (opt->fmode != ISOFS_INVALID_MODE)
sbi->s_fmode = opt.fmode & 0777; sbi->s_fmode = opt->fmode & 0777;
else else
sbi->s_fmode = ISOFS_INVALID_MODE; sbi->s_fmode = ISOFS_INVALID_MODE;
if (opt.dmode != ISOFS_INVALID_MODE) if (opt->dmode != ISOFS_INVALID_MODE)
sbi->s_dmode = opt.dmode & 0777; sbi->s_dmode = opt->dmode & 0777;
else else
sbi->s_dmode = ISOFS_INVALID_MODE; sbi->s_dmode = ISOFS_INVALID_MODE;
...@@ -960,12 +922,12 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -960,12 +922,12 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
} }
} }
if (opt.check == 'u') { if (opt->check == 'u') {
/* Only Joliet is case insensitive by default */ /* Only Joliet is case insensitive by default */
if (joliet_level) if (joliet_level)
opt.check = 'r'; opt->check = 'r';
else else
opt.check = 's'; opt->check = 's';
} }
sbi->s_joliet_level = joliet_level; sbi->s_joliet_level = joliet_level;
...@@ -980,9 +942,9 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -980,9 +942,9 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
table = 0; table = 0;
if (joliet_level) if (joliet_level)
table += 2; table += 2;
if (opt.check == 'r') if (opt->check == 'r')
table++; table++;
sbi->s_check = opt.check; sbi->s_check = opt->check;
if (table) if (table)
s->s_d_op = &isofs_dentry_ops[table - 1]; s->s_d_op = &isofs_dentry_ops[table - 1];
...@@ -994,7 +956,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -994,7 +956,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
goto out_no_inode; goto out_no_inode;
} }
kfree(opt.iocharset); kfree(opt->iocharset);
return 0; return 0;
...@@ -1023,7 +985,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -1023,7 +985,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
goto out_freebh; goto out_freebh;
out_bad_size: out_bad_size:
printk(KERN_WARNING "ISOFS: Logical zone size(%d) < hardware blocksize(%u)\n", printk(KERN_WARNING "ISOFS: Logical zone size(%d) < hardware blocksize(%u)\n",
orig_zonesize, opt.blocksize); orig_zonesize, opt->blocksize);
goto out_freebh; goto out_freebh;
out_unknown_format: out_unknown_format:
if (!silent) if (!silent)
...@@ -1033,7 +995,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) ...@@ -1033,7 +995,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
brelse(bh); brelse(bh);
brelse(pri_bh); brelse(pri_bh);
out_freesbi: out_freesbi:
kfree(opt.iocharset); kfree(opt->iocharset);
kfree(sbi); kfree(sbi);
s->s_fs_info = NULL; s->s_fs_info = NULL;
return error; return error;
...@@ -1567,18 +1529,63 @@ struct inode *__isofs_iget(struct super_block *sb, ...@@ -1567,18 +1529,63 @@ struct inode *__isofs_iget(struct super_block *sb,
return inode; return inode;
} }
static struct dentry *isofs_mount(struct file_system_type *fs_type, static int isofs_get_tree(struct fs_context *fc)
int flags, const char *dev_name, void *data)
{ {
return mount_bdev(fs_type, flags, dev_name, data, isofs_fill_super); return get_tree_bdev(fc, isofs_fill_super);
}
static void isofs_free_fc(struct fs_context *fc)
{
kfree(fc->fs_private);
}
static const struct fs_context_operations isofs_context_ops = {
.parse_param = isofs_parse_param,
.get_tree = isofs_get_tree,
.reconfigure = isofs_reconfigure,
.free = isofs_free_fc,
};
static int isofs_init_fs_context(struct fs_context *fc)
{
struct isofs_options *opt;
opt = kzalloc(sizeof(*opt), GFP_KERNEL);
if (!opt)
return -ENOMEM;
opt->map = 'n';
opt->rock = 1;
opt->joliet = 1;
opt->cruft = 0;
opt->hide = 0;
opt->showassoc = 0;
opt->check = 'u'; /* unset */
opt->nocompress = 0;
opt->blocksize = 1024;
opt->fmode = opt->dmode = ISOFS_INVALID_MODE;
opt->uid_set = 0;
opt->gid_set = 0;
opt->gid = GLOBAL_ROOT_GID;
opt->uid = GLOBAL_ROOT_UID;
opt->iocharset = NULL;
opt->overriderockperm = 0;
opt->session = -1;
opt->sbsector = -1;
fc->fs_private = opt;
fc->ops = &isofs_context_ops;
return 0;
} }
static struct file_system_type iso9660_fs_type = { static struct file_system_type iso9660_fs_type = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "iso9660", .name = "iso9660",
.mount = isofs_mount,
.kill_sb = kill_block_super, .kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV, .fs_flags = FS_REQUIRES_DEV,
.init_fs_context = isofs_init_fs_context,
.parameters = isofs_param_spec,
}; };
MODULE_ALIAS_FS("iso9660"); MODULE_ALIAS_FS("iso9660");
MODULE_ALIAS("iso9660"); MODULE_ALIAS("iso9660");
......
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