Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 169179
b: refs/heads/master
c: f55073f
h: refs/heads/master
i:
  169177: 480fa4c
  169175: 4ad1e56
v: v3
  • Loading branch information
Steven Whitehouse committed Dec 3, 2009
1 parent 3b84ae2 commit 2d6c64a
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 27 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7e71c55ee73988d0cb61045660b899eaac23bf8f
refs/heads/master: f55073ff1eaf99f6b3bc62134a456638bca043a3
135 changes: 118 additions & 17 deletions trunk/fs/gfs2/ops_fstype.c
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@ void gfs2_online_uevent(struct gfs2_sbd *sdp)
* Returns: errno
*/

static int fill_super(struct super_block *sb, void *data, int silent)
static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent)
{
struct gfs2_sbd *sdp;
struct gfs2_holder mount_gh;
Expand All @@ -1125,17 +1125,7 @@ static int fill_super(struct super_block *sb, void *data, int silent)
printk(KERN_WARNING "GFS2: can't alloc struct gfs2_sbd\n");
return -ENOMEM;
}

sdp->sd_args.ar_quota = GFS2_QUOTA_DEFAULT;
sdp->sd_args.ar_data = GFS2_DATA_DEFAULT;
sdp->sd_args.ar_commit = 60;
sdp->sd_args.ar_errors = GFS2_ERRORS_DEFAULT;

error = gfs2_mount_args(sdp, &sdp->sd_args, data);
if (error) {
printk(KERN_WARNING "GFS2: can't parse mount arguments\n");
goto fail;
}
sdp->sd_args = *args;

if (sdp->sd_args.ar_spectator) {
sb->s_flags |= MS_RDONLY;
Expand Down Expand Up @@ -1243,18 +1233,125 @@ static int fill_super(struct super_block *sb, void *data, int silent)
return error;
}

static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data, struct vfsmount *mnt)
static int set_gfs2_super(struct super_block *s, void *data)
{
return get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt);
s->s_bdev = data;
s->s_dev = s->s_bdev->bd_dev;

/*
* We set the bdi here to the queue backing, file systems can
* overwrite this in ->fill_super()
*/
s->s_bdi = &bdev_get_queue(s->s_bdev)->backing_dev_info;
return 0;
}

static int test_meta_super(struct super_block *s, void *ptr)
static int test_gfs2_super(struct super_block *s, void *ptr)
{
struct block_device *bdev = ptr;
return (bdev == s->s_bdev);
}

/**
* gfs2_get_sb - Get the GFS2 superblock
* @fs_type: The GFS2 filesystem type
* @flags: Mount flags
* @dev_name: The name of the device
* @data: The mount arguments
* @mnt: The vfsmnt for this mount
*
* Q. Why not use get_sb_bdev() ?
* A. We need to select one of two root directories to mount, independent
* of whether this is the initial, or subsequent, mount of this sb
*
* Returns: 0 or -ve on error
*/

static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data, struct vfsmount *mnt)
{
struct block_device *bdev;
struct super_block *s;
fmode_t mode = FMODE_READ;
int error;
struct gfs2_args args;
struct gfs2_sbd *sdp;

if (!(flags & MS_RDONLY))
mode |= FMODE_WRITE;

bdev = open_bdev_exclusive(dev_name, mode, fs_type);
if (IS_ERR(bdev))
return PTR_ERR(bdev);

/*
* once the super is inserted into the list by sget, s_umount
* will protect the lockfs code from trying to start a snapshot
* while we are mounting
*/
mutex_lock(&bdev->bd_fsfreeze_mutex);
if (bdev->bd_fsfreeze_count > 0) {
mutex_unlock(&bdev->bd_fsfreeze_mutex);
error = -EBUSY;
goto error_bdev;
}
s = sget(fs_type, test_gfs2_super, set_gfs2_super, bdev);
mutex_unlock(&bdev->bd_fsfreeze_mutex);
error = PTR_ERR(s);
if (IS_ERR(s))
goto error_bdev;

memset(&args, 0, sizeof(args));
args.ar_quota = GFS2_QUOTA_DEFAULT;
args.ar_data = GFS2_DATA_DEFAULT;
args.ar_commit = 60;
args.ar_errors = GFS2_ERRORS_DEFAULT;

error = gfs2_mount_args(&args, data);
if (error) {
printk(KERN_WARNING "GFS2: can't parse mount arguments\n");
if (s->s_root)
goto error_super;
deactivate_locked_super(s);
return error;
}

if (s->s_root) {
error = -EBUSY;
if ((flags ^ s->s_flags) & MS_RDONLY)
goto error_super;
close_bdev_exclusive(bdev, mode);
} else {
char b[BDEVNAME_SIZE];

s->s_flags = flags;
s->s_mode = mode;
strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
sb_set_blocksize(s, block_size(bdev));
error = fill_super(s, &args, flags & MS_SILENT ? 1 : 0);
if (error) {
deactivate_locked_super(s);
return error;
}
s->s_flags |= MS_ACTIVE;
bdev->bd_super = s;
}

sdp = s->s_fs_info;
mnt->mnt_sb = s;
if (args.ar_meta)
mnt->mnt_root = dget(sdp->sd_master_dir);
else
mnt->mnt_root = dget(sdp->sd_root_dir);
return 0;

error_super:
deactivate_locked_super(s);
error_bdev:
close_bdev_exclusive(bdev, mode);
return error;
}

static int set_meta_super(struct super_block *s, void *ptr)
{
return -EINVAL;
Expand All @@ -1274,13 +1371,17 @@ static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags,
dev_name, error);
return error;
}
s = sget(&gfs2_fs_type, test_meta_super, set_meta_super,
s = sget(&gfs2_fs_type, test_gfs2_super, set_meta_super,
path.dentry->d_inode->i_sb->s_bdev);
path_put(&path);
if (IS_ERR(s)) {
printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n");
return PTR_ERR(s);
}
if ((flags ^ s->s_flags) & MS_RDONLY) {
deactivate_locked_super(s);
return -EBUSY;
}
sdp = s->s_fs_info;
mnt->mnt_sb = s;
mnt->mnt_root = dget(sdp->sd_master_dir);
Expand Down
16 changes: 8 additions & 8 deletions trunk/fs/gfs2/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,13 @@ static const match_table_t tokens = {

/**
* gfs2_mount_args - Parse mount options
* @sdp:
* @data:
* @args: The structure into which the parsed options will be written
* @options: The options to parse
*
* Return: errno
*/

int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
int gfs2_mount_args(struct gfs2_args *args, char *options)
{
char *o;
int token;
Expand Down Expand Up @@ -157,7 +157,7 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
break;
case Opt_debug:
if (args->ar_errors == GFS2_ERRORS_PANIC) {
fs_info(sdp, "-o debug and -o errors=panic "
printk(KERN_WARNING "GFS2: -o debug and -o errors=panic "
"are mutually exclusive.\n");
return -EINVAL;
}
Expand Down Expand Up @@ -210,7 +210,7 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
case Opt_commit:
rv = match_int(&tmp[0], &args->ar_commit);
if (rv || args->ar_commit <= 0) {
fs_info(sdp, "commit mount option requires a positive numeric argument\n");
printk(KERN_WARNING "GFS2: commit mount option requires a positive numeric argument\n");
return rv ? rv : -EINVAL;
}
break;
Expand All @@ -219,15 +219,15 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
break;
case Opt_err_panic:
if (args->ar_debug) {
fs_info(sdp, "-o debug and -o errors=panic "
printk(KERN_WARNING "GFS2: -o debug and -o errors=panic "
"are mutually exclusive.\n");
return -EINVAL;
}
args->ar_errors = GFS2_ERRORS_PANIC;
break;
case Opt_error:
default:
fs_info(sdp, "invalid mount option: %s\n", o);
printk(KERN_WARNING "GFS2: invalid mount option: %s\n", o);
return -EINVAL;
}
}
Expand Down Expand Up @@ -1062,7 +1062,7 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
spin_lock(&gt->gt_spin);
args.ar_commit = gt->gt_log_flush_secs;
spin_unlock(&gt->gt_spin);
error = gfs2_mount_args(sdp, &args, data);
error = gfs2_mount_args(&args, data);
if (error)
return error;

Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/gfs2/super.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp)

extern void gfs2_jindex_free(struct gfs2_sbd *sdp);

extern int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *data);
extern int gfs2_mount_args(struct gfs2_args *args, char *data);

extern struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid);
extern int gfs2_jdesc_check(struct gfs2_jdesc *jd);
Expand Down

0 comments on commit 2d6c64a

Please sign in to comment.