summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/main.c9
-rw-r--r--fs/gfs2/ops_fstype.c58
-rw-r--r--fs/gfs2/ops_fstype.h1
3 files changed, 45 insertions, 23 deletions
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index c54177790318..c8d17b7ba60b 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -64,11 +64,17 @@ static int __init init_gfs2_fs(void)
if (error)
goto fail;
+ error = register_filesystem(&gfs2meta_fs_type);
+ if (error)
+ goto fail_unregister;
+
printk("GFS2 (built %s %s) installed\n", __DATE__, __TIME__);
return 0;
- fail:
+fail_unregister:
+ unregister_filesystem(&gfs2_fs_type);
+fail:
if (gfs2_bufdata_cachep)
kmem_cache_destroy(gfs2_bufdata_cachep);
@@ -90,6 +96,7 @@ static int __init init_gfs2_fs(void)
static void __exit exit_gfs2_fs(void)
{
unregister_filesystem(&gfs2_fs_type);
+ unregister_filesystem(&gfs2meta_fs_type);
kmem_cache_destroy(gfs2_bufdata_cachep);
kmem_cache_destroy(gfs2_inode_cachep);
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index c3b830bd838b..8d6d94143561 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -113,9 +113,9 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
return sdp;
}
-static void init_vfs(struct gfs2_sbd *sdp)
+static void init_vfs(struct super_block *sb, unsigned noatime)
{
- struct super_block *sb = sdp->sd_vfs;
+ struct gfs2_sbd *sdp = sb->s_fs_info;
sb->s_magic = GFS2_MAGIC;
sb->s_op = &gfs2_super_ops;
@@ -123,18 +123,10 @@ static void init_vfs(struct gfs2_sbd *sdp)
sb->s_maxbytes = MAX_LFS_FILESIZE;
if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME))
- set_bit(SDF_NOATIME, &sdp->sd_flags);
+ set_bit(noatime, &sdp->sd_flags);
/* Don't let the VFS update atimes. GFS2 handles this itself. */
sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
-
- /* Set up the buffer cache and fill in some fake block size values
- to allow us to read-in the on-disk superblock. */
- sdp->sd_sb.sb_bsize = sb_min_blocksize(sb, GFS2_BASIC_BLOCK);
- sdp->sd_sb.sb_bsize_shift = sb->s_blocksize_bits;
- sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift -
- GFS2_BASIC_BLOCK_SHIFT;
- sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift;
}
static int init_names(struct gfs2_sbd *sdp, int silent)
@@ -291,18 +283,16 @@ static struct inode *gfs2_lookup_root(struct gfs2_sbd *sdp,
error = gfs2_glock_get(sdp, inum->no_addr,
&gfs2_inode_glops, CREATE, &gl);
if (!error) {
- error = gfs2_inode_get(gl, inum,
- CREATE, &ip);
+ error = gfs2_inode_get(gl, inum, CREATE, &ip);
if (!error) {
- if (!error)
- gfs2_inode_min_init(ip, DT_DIR);
+ gfs2_inode_min_init(ip, DT_DIR);
inode = gfs2_ip2v(ip);
gfs2_inode_put(ip);
+ gfs2_glock_put(gl);
return inode;
}
gfs2_glock_put(gl);
}
-
return ERR_PTR(error);
}
@@ -310,6 +300,7 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
{
struct super_block *sb = sdp->sd_vfs;
struct gfs2_holder sb_gh;
+ struct gfs2_inum *inum;
struct inode *inode;
int error = 0;
@@ -332,14 +323,15 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
}
/* Set up the buffer cache and SB for real */
- error = -EINVAL;
if (sdp->sd_sb.sb_bsize < bdev_hardsect_size(sb->s_bdev)) {
+ error = -EINVAL;
fs_err(sdp, "FS block size (%u) is too small for device "
"block size (%u)\n",
sdp->sd_sb.sb_bsize, bdev_hardsect_size(sb->s_bdev));
goto out;
}
if (sdp->sd_sb.sb_bsize > PAGE_SIZE) {
+ error = -EINVAL;
fs_err(sdp, "FS block size (%u) is too big for machine "
"page size (%u)\n",
sdp->sd_sb.sb_bsize, (unsigned int)PAGE_SIZE);
@@ -353,7 +345,10 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
sb_set_blocksize(sb, sdp->sd_sb.sb_bsize);
/* Get the root inode */
- inode = gfs2_lookup_root(sdp, &sdp->sd_sb.sb_root_dir);
+ inum = &sdp->sd_sb.sb_root_dir;
+ if (sb->s_type == &gfs2meta_fs_type)
+ inum = &sdp->sd_sb.sb_master_dir;
+ inode = gfs2_lookup_root(sdp, inum);
if (IS_ERR(inode)) {
error = PTR_ERR(inode);
fs_err(sdp, "can't read in root inode: %d\n", error);
@@ -366,10 +361,8 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
error = -ENOMEM;
iput(inode);
}
-
out:
gfs2_glock_dq_uninit(&sb_gh);
-
return error;
}
@@ -791,7 +784,15 @@ static int fill_super(struct super_block *sb, void *data, int silent)
goto fail;
}
- init_vfs(sdp);
+ init_vfs(sb, SDF_NOATIME);
+
+ /* Set up the buffer cache and fill in some fake block size values
+ to allow us to read-in the on-disk superblock. */
+ sdp->sd_sb.sb_bsize = sb_min_blocksize(sb, GFS2_BASIC_BLOCK);
+ sdp->sd_sb.sb_bsize_shift = sb->s_blocksize_bits;
+ sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift -
+ GFS2_BASIC_BLOCK_SHIFT;
+ sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift;
error = init_names(sdp, silent);
if (error)
@@ -881,11 +882,24 @@ static struct super_block *gfs2_get_sb(struct file_system_type *fs_type,
return get_sb_bdev(fs_type, flags, dev_name, data, fill_super);
}
+static void gfs2_kill_sb(struct super_block *sb)
+{
+ kill_block_super(sb);
+}
+
struct file_system_type gfs2_fs_type = {
.name = "gfs2",
.fs_flags = FS_REQUIRES_DEV,
.get_sb = gfs2_get_sb,
- .kill_sb = kill_block_super,
+ .kill_sb = gfs2_kill_sb,
+ .owner = THIS_MODULE,
+};
+
+struct file_system_type gfs2meta_fs_type = {
+ .name = "gfs2meta",
+ .fs_flags = FS_REQUIRES_DEV,
+ .get_sb = gfs2_get_sb,
+ .kill_sb = gfs2_kill_sb,
.owner = THIS_MODULE,
};
diff --git a/fs/gfs2/ops_fstype.h b/fs/gfs2/ops_fstype.h
index 7008364e76ea..c6452874483d 100644
--- a/fs/gfs2/ops_fstype.h
+++ b/fs/gfs2/ops_fstype.h
@@ -11,5 +11,6 @@
#define __OPS_FSTYPE_DOT_H__
extern struct file_system_type gfs2_fs_type;
+extern struct file_system_type gfs2meta_fs_type;
#endif /* __OPS_FSTYPE_DOT_H__ */