diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/gfs2/main.c | 9 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 58 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.h | 1 |
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: | 75 | fail_unregister: |
76 | unregister_filesystem(&gfs2_fs_type); | ||
77 | fail: | ||
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) | |||
90 | static void __exit exit_gfs2_fs(void) | 96 | static 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 | ||
116 | static void init_vfs(struct gfs2_sbd *sdp) | 116 | static 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 | ||
140 | static int init_names(struct gfs2_sbd *sdp, int silent) | 132 | 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 | 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 | |||
370 | out: | 364 | out: |
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 | ||
885 | static void gfs2_kill_sb(struct super_block *sb) | ||
886 | { | ||
887 | kill_block_super(sb); | ||
888 | } | ||
889 | |||
884 | struct file_system_type gfs2_fs_type = { | 890 | struct 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 | |||
898 | struct 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 | ||
13 | extern struct file_system_type gfs2_fs_type; | 13 | extern struct file_system_type gfs2_fs_type; |
14 | extern struct file_system_type gfs2meta_fs_type; | ||
14 | 15 | ||
15 | #endif /* __OPS_FSTYPE_DOT_H__ */ | 16 | #endif /* __OPS_FSTYPE_DOT_H__ */ |