Commit 419c93e0 authored by Steven Whitehouse's avatar Steven Whitehouse

[GFS2] Add gfs2meta filesystem

In order to separate out the filesystem's metadata from "normal"
files and directories, a new filesystem type has been created.
It is called gfs2meta and mounting it gives access to the files
that were previously under .gfs2_admin (well still are until mkfs
is altered, which is next on the adgenda).

Its not currently possible to mount both gfs2 and gfs2meta on the
same block device at the same time. A future patch will allow that
to happen.
Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent b4dc7291
...@@ -64,11 +64,17 @@ static int __init init_gfs2_fs(void) ...@@ -64,11 +64,17 @@ static int __init init_gfs2_fs(void)
if (error) if (error)
goto fail; goto fail;
error = register_filesystem(&gfs2meta_fs_type);
if (error)
goto fail_unregister;
printk("GFS2 (built %s %s) installed\n", __DATE__, __TIME__); printk("GFS2 (built %s %s) installed\n", __DATE__, __TIME__);
return 0; return 0;
fail: fail_unregister:
unregister_filesystem(&gfs2_fs_type);
fail:
if (gfs2_bufdata_cachep) if (gfs2_bufdata_cachep)
kmem_cache_destroy(gfs2_bufdata_cachep); kmem_cache_destroy(gfs2_bufdata_cachep);
...@@ -90,6 +96,7 @@ static int __init init_gfs2_fs(void) ...@@ -90,6 +96,7 @@ static int __init init_gfs2_fs(void)
static void __exit exit_gfs2_fs(void) static void __exit exit_gfs2_fs(void)
{ {
unregister_filesystem(&gfs2_fs_type); unregister_filesystem(&gfs2_fs_type);
unregister_filesystem(&gfs2meta_fs_type);
kmem_cache_destroy(gfs2_bufdata_cachep); kmem_cache_destroy(gfs2_bufdata_cachep);
kmem_cache_destroy(gfs2_inode_cachep); kmem_cache_destroy(gfs2_inode_cachep);
......
...@@ -113,9 +113,9 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) ...@@ -113,9 +113,9 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
return sdp; 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_magic = GFS2_MAGIC;
sb->s_op = &gfs2_super_ops; sb->s_op = &gfs2_super_ops;
...@@ -123,18 +123,10 @@ static void init_vfs(struct gfs2_sbd *sdp) ...@@ -123,18 +123,10 @@ static void init_vfs(struct gfs2_sbd *sdp)
sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_maxbytes = MAX_LFS_FILESIZE;
if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME)) 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. */ /* Don't let the VFS update atimes. GFS2 handles this itself. */
sb->s_flags |= MS_NOATIME | MS_NODIRATIME; 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) static int init_names(struct gfs2_sbd *sdp, int silent)
...@@ -291,18 +283,16 @@ static struct inode *gfs2_lookup_root(struct gfs2_sbd *sdp, ...@@ -291,18 +283,16 @@ static struct inode *gfs2_lookup_root(struct gfs2_sbd *sdp,
error = gfs2_glock_get(sdp, inum->no_addr, error = gfs2_glock_get(sdp, inum->no_addr,
&gfs2_inode_glops, CREATE, &gl); &gfs2_inode_glops, CREATE, &gl);
if (!error) { if (!error) {
error = gfs2_inode_get(gl, inum, error = gfs2_inode_get(gl, inum, CREATE, &ip);
CREATE, &ip);
if (!error) { if (!error) {
if (!error) gfs2_inode_min_init(ip, DT_DIR);
gfs2_inode_min_init(ip, DT_DIR);
inode = gfs2_ip2v(ip); inode = gfs2_ip2v(ip);
gfs2_inode_put(ip); gfs2_inode_put(ip);
gfs2_glock_put(gl);
return inode; return inode;
} }
gfs2_glock_put(gl); gfs2_glock_put(gl);
} }
return ERR_PTR(error); return ERR_PTR(error);
} }
...@@ -310,6 +300,7 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) ...@@ -310,6 +300,7 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
{ {
struct super_block *sb = sdp->sd_vfs; struct super_block *sb = sdp->sd_vfs;
struct gfs2_holder sb_gh; struct gfs2_holder sb_gh;
struct gfs2_inum *inum;
struct inode *inode; struct inode *inode;
int error = 0; int error = 0;
...@@ -332,14 +323,15 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) ...@@ -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 */ /* Set up the buffer cache and SB for real */
error = -EINVAL;
if (sdp->sd_sb.sb_bsize < bdev_hardsect_size(sb->s_bdev)) { 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 " fs_err(sdp, "FS block size (%u) is too small for device "
"block size (%u)\n", "block size (%u)\n",
sdp->sd_sb.sb_bsize, bdev_hardsect_size(sb->s_bdev)); sdp->sd_sb.sb_bsize, bdev_hardsect_size(sb->s_bdev));
goto out; goto out;
} }
if (sdp->sd_sb.sb_bsize > PAGE_SIZE) { if (sdp->sd_sb.sb_bsize > PAGE_SIZE) {
error = -EINVAL;
fs_err(sdp, "FS block size (%u) is too big for machine " fs_err(sdp, "FS block size (%u) is too big for machine "
"page size (%u)\n", "page size (%u)\n",
sdp->sd_sb.sb_bsize, (unsigned int)PAGE_SIZE); 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) ...@@ -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); sb_set_blocksize(sb, sdp->sd_sb.sb_bsize);
/* Get the root inode */ /* 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)) { if (IS_ERR(inode)) {
error = PTR_ERR(inode); error = PTR_ERR(inode);
fs_err(sdp, "can't read in root inode: %d\n", error); 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) ...@@ -366,10 +361,8 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
error = -ENOMEM; error = -ENOMEM;
iput(inode); iput(inode);
} }
out: out:
gfs2_glock_dq_uninit(&sb_gh); gfs2_glock_dq_uninit(&sb_gh);
return error; return error;
} }
...@@ -791,7 +784,15 @@ static int fill_super(struct super_block *sb, void *data, int silent) ...@@ -791,7 +784,15 @@ static int fill_super(struct super_block *sb, void *data, int silent)
goto fail; 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); error = init_names(sdp, silent);
if (error) if (error)
...@@ -881,11 +882,24 @@ static struct super_block *gfs2_get_sb(struct file_system_type *fs_type, ...@@ -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); 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 = { struct file_system_type gfs2_fs_type = {
.name = "gfs2", .name = "gfs2",
.fs_flags = FS_REQUIRES_DEV, .fs_flags = FS_REQUIRES_DEV,
.get_sb = gfs2_get_sb, .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, .owner = THIS_MODULE,
}; };
...@@ -11,5 +11,6 @@ ...@@ -11,5 +11,6 @@
#define __OPS_FSTYPE_DOT_H__ #define __OPS_FSTYPE_DOT_H__
extern struct file_system_type gfs2_fs_type; extern struct file_system_type gfs2_fs_type;
extern struct file_system_type gfs2meta_fs_type;
#endif /* __OPS_FSTYPE_DOT_H__ */ #endif /* __OPS_FSTYPE_DOT_H__ */
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