aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-03-02 16:33:41 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2006-03-02 16:33:41 -0500
commit419c93e0b6b9eef0bf26b8ad415f2a5bf4300119 (patch)
treed2333ff0833cd5470b12e103a410a77158a15881
parentb4dc72911d149d7d6b7ffb512bd68906f1cbd33a (diff)
[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: Steven Whitehouse <swhiteho@redhat.com>
-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)
64 if (error) 64 if (error)
65 goto fail; 65 goto fail;
66 66
67 error = register_filesystem(&gfs2meta_fs_type);
68 if (error)
69 goto fail_unregister;
70
67 printk("GFS2 (built %s %s) installed\n", __DATE__, __TIME__); 71 printk("GFS2 (built %s %s) installed\n", __DATE__, __TIME__);
68 72
69 return 0; 73 return 0;
70 74
71 fail: 75fail_unregister:
76 unregister_filesystem(&gfs2_fs_type);
77fail:
72 if (gfs2_bufdata_cachep) 78 if (gfs2_bufdata_cachep)
73 kmem_cache_destroy(gfs2_bufdata_cachep); 79 kmem_cache_destroy(gfs2_bufdata_cachep);
74 80
@@ -90,6 +96,7 @@ static int __init init_gfs2_fs(void)
90static void __exit exit_gfs2_fs(void) 96static void __exit exit_gfs2_fs(void)
91{ 97{
92 unregister_filesystem(&gfs2_fs_type); 98 unregister_filesystem(&gfs2_fs_type);
99 unregister_filesystem(&gfs2meta_fs_type);
93 100
94 kmem_cache_destroy(gfs2_bufdata_cachep); 101 kmem_cache_destroy(gfs2_bufdata_cachep);
95 kmem_cache_destroy(gfs2_inode_cachep); 102 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)
113 return sdp; 113 return sdp;
114} 114}
115 115
116static void init_vfs(struct gfs2_sbd *sdp) 116static void init_vfs(struct super_block *sb, unsigned noatime)
117{ 117{
118 struct super_block *sb = sdp->sd_vfs; 118 struct gfs2_sbd *sdp = sb->s_fs_info;
119 119
120 sb->s_magic = GFS2_MAGIC; 120 sb->s_magic = GFS2_MAGIC;
121 sb->s_op = &gfs2_super_ops; 121 sb->s_op = &gfs2_super_ops;
@@ -123,18 +123,10 @@ static void init_vfs(struct gfs2_sbd *sdp)
123 sb->s_maxbytes = MAX_LFS_FILESIZE; 123 sb->s_maxbytes = MAX_LFS_FILESIZE;
124 124
125 if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME)) 125 if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME))
126 set_bit(SDF_NOATIME, &sdp->sd_flags); 126 set_bit(noatime, &sdp->sd_flags);
127 127
128 /* Don't let the VFS update atimes. GFS2 handles this itself. */ 128 /* Don't let the VFS update atimes. GFS2 handles this itself. */
129 sb->s_flags |= MS_NOATIME | MS_NODIRATIME; 129 sb->s_flags |= MS_NOATIME | MS_NODIRATIME;
130
131 /* Set up the buffer cache and fill in some fake block size values
132 to allow us to read-in the on-disk superblock. */
133 sdp->sd_sb.sb_bsize = sb_min_blocksize(sb, GFS2_BASIC_BLOCK);
134 sdp->sd_sb.sb_bsize_shift = sb->s_blocksize_bits;
135 sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift -
136 GFS2_BASIC_BLOCK_SHIFT;
137 sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift;
138} 130}
139 131
140static int init_names(struct gfs2_sbd *sdp, int silent) 132static int init_names(struct gfs2_sbd *sdp, int silent)
@@ -291,18 +283,16 @@ static struct inode *gfs2_lookup_root(struct gfs2_sbd *sdp,
291 error = gfs2_glock_get(sdp, inum->no_addr, 283 error = gfs2_glock_get(sdp, inum->no_addr,
292 &gfs2_inode_glops, CREATE, &gl); 284 &gfs2_inode_glops, CREATE, &gl);
293 if (!error) { 285 if (!error) {
294 error = gfs2_inode_get(gl, inum, 286 error = gfs2_inode_get(gl, inum, CREATE, &ip);
295 CREATE, &ip);
296 if (!error) { 287 if (!error) {
297 if (!error) 288 gfs2_inode_min_init(ip, DT_DIR);
298 gfs2_inode_min_init(ip, DT_DIR);
299 inode = gfs2_ip2v(ip); 289 inode = gfs2_ip2v(ip);
300 gfs2_inode_put(ip); 290 gfs2_inode_put(ip);
291 gfs2_glock_put(gl);
301 return inode; 292 return inode;
302 } 293 }
303 gfs2_glock_put(gl); 294 gfs2_glock_put(gl);
304 } 295 }
305
306 return ERR_PTR(error); 296 return ERR_PTR(error);
307} 297}
308 298
@@ -310,6 +300,7 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
310{ 300{
311 struct super_block *sb = sdp->sd_vfs; 301 struct super_block *sb = sdp->sd_vfs;
312 struct gfs2_holder sb_gh; 302 struct gfs2_holder sb_gh;
303 struct gfs2_inum *inum;
313 struct inode *inode; 304 struct inode *inode;
314 int error = 0; 305 int error = 0;
315 306
@@ -332,14 +323,15 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
332 } 323 }
333 324
334 /* Set up the buffer cache and SB for real */ 325 /* Set up the buffer cache and SB for real */
335 error = -EINVAL;
336 if (sdp->sd_sb.sb_bsize < bdev_hardsect_size(sb->s_bdev)) { 326 if (sdp->sd_sb.sb_bsize < bdev_hardsect_size(sb->s_bdev)) {
327 error = -EINVAL;
337 fs_err(sdp, "FS block size (%u) is too small for device " 328 fs_err(sdp, "FS block size (%u) is too small for device "
338 "block size (%u)\n", 329 "block size (%u)\n",
339 sdp->sd_sb.sb_bsize, bdev_hardsect_size(sb->s_bdev)); 330 sdp->sd_sb.sb_bsize, bdev_hardsect_size(sb->s_bdev));
340 goto out; 331 goto out;
341 } 332 }
342 if (sdp->sd_sb.sb_bsize > PAGE_SIZE) { 333 if (sdp->sd_sb.sb_bsize > PAGE_SIZE) {
334 error = -EINVAL;
343 fs_err(sdp, "FS block size (%u) is too big for machine " 335 fs_err(sdp, "FS block size (%u) is too big for machine "
344 "page size (%u)\n", 336 "page size (%u)\n",
345 sdp->sd_sb.sb_bsize, (unsigned int)PAGE_SIZE); 337 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 sb_set_blocksize(sb, sdp->sd_sb.sb_bsize); 345 sb_set_blocksize(sb, sdp->sd_sb.sb_bsize);
354 346
355 /* Get the root inode */ 347 /* Get the root inode */
356 inode = gfs2_lookup_root(sdp, &sdp->sd_sb.sb_root_dir); 348 inum = &sdp->sd_sb.sb_root_dir;
349 if (sb->s_type == &gfs2meta_fs_type)
350 inum = &sdp->sd_sb.sb_master_dir;
351 inode = gfs2_lookup_root(sdp, inum);
357 if (IS_ERR(inode)) { 352 if (IS_ERR(inode)) {
358 error = PTR_ERR(inode); 353 error = PTR_ERR(inode);
359 fs_err(sdp, "can't read in root inode: %d\n", error); 354 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 error = -ENOMEM; 361 error = -ENOMEM;
367 iput(inode); 362 iput(inode);
368 } 363 }
369
370out: 364out:
371 gfs2_glock_dq_uninit(&sb_gh); 365 gfs2_glock_dq_uninit(&sb_gh);
372
373 return error; 366 return error;
374} 367}
375 368
@@ -791,7 +784,15 @@ static int fill_super(struct super_block *sb, void *data, int silent)
791 goto fail; 784 goto fail;
792 } 785 }
793 786
794 init_vfs(sdp); 787 init_vfs(sb, SDF_NOATIME);
788
789 /* Set up the buffer cache and fill in some fake block size values
790 to allow us to read-in the on-disk superblock. */
791 sdp->sd_sb.sb_bsize = sb_min_blocksize(sb, GFS2_BASIC_BLOCK);
792 sdp->sd_sb.sb_bsize_shift = sb->s_blocksize_bits;
793 sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift -
794 GFS2_BASIC_BLOCK_SHIFT;
795 sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift;
795 796
796 error = init_names(sdp, silent); 797 error = init_names(sdp, silent);
797 if (error) 798 if (error)
@@ -881,11 +882,24 @@ static struct super_block *gfs2_get_sb(struct file_system_type *fs_type,
881 return get_sb_bdev(fs_type, flags, dev_name, data, fill_super); 882 return get_sb_bdev(fs_type, flags, dev_name, data, fill_super);
882} 883}
883 884
885static void gfs2_kill_sb(struct super_block *sb)
886{
887 kill_block_super(sb);
888}
889
884struct file_system_type gfs2_fs_type = { 890struct file_system_type gfs2_fs_type = {
885 .name = "gfs2", 891 .name = "gfs2",
886 .fs_flags = FS_REQUIRES_DEV, 892 .fs_flags = FS_REQUIRES_DEV,
887 .get_sb = gfs2_get_sb, 893 .get_sb = gfs2_get_sb,
888 .kill_sb = kill_block_super, 894 .kill_sb = gfs2_kill_sb,
895 .owner = THIS_MODULE,
896};
897
898struct file_system_type gfs2meta_fs_type = {
899 .name = "gfs2meta",
900 .fs_flags = FS_REQUIRES_DEV,
901 .get_sb = gfs2_get_sb,
902 .kill_sb = gfs2_kill_sb,
889 .owner = THIS_MODULE, 903 .owner = THIS_MODULE,
890}; 904};
891 905
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 @@
11#define __OPS_FSTYPE_DOT_H__ 11#define __OPS_FSTYPE_DOT_H__
12 12
13extern struct file_system_type gfs2_fs_type; 13extern struct file_system_type gfs2_fs_type;
14extern struct file_system_type gfs2meta_fs_type;
14 15
15#endif /* __OPS_FSTYPE_DOT_H__ */ 16#endif /* __OPS_FSTYPE_DOT_H__ */