aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/ops_super.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2008-08-08 08:45:13 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2008-08-13 04:59:40 -0400
commit9b8df98fc8973ad1c5f0d7c4cf71c7fb84fe22c5 (patch)
tree6a0445afd83d0f7a63a301c2e146647abf59ad82 /fs/gfs2/ops_super.c
parentc1e817d03a7de57a963654c35e6e80af9a5dbff5 (diff)
GFS2: Fix metafs mounts
This patch is intended to fix the issues reported in bz #457798. Instead of having the metafs as a separate filesystem, it becomes a second root of gfs2. As a result it will appear as type gfs2 in /proc/mounts, but it is still possible (for backwards compatibility purposes) to mount it as type gfs2meta. A new mount flag "meta" is introduced so that its possible to tell the two cases apart in /proc/mounts. As a result it becomes possible to mount type gfs2 with -o meta and get the same result as mounting type gfs2meta. So it is possible to mount just the metafs on its own. Currently if you do this, its then impossible to mount the "normal" root of the gfs2 filesystem without first unmounting the metafs root. I'm not sure if thats a feature or a bug :-) Either way, this is a great improvement on the previous scheme and I've verified that it works ok with bind mounts on both the "normal" root and the metafs root in various combinations. There were also a bunch of functions in super.c which didn't belong there, so this moves them into ops_fstype.c where they can be static. Hopefully the mount/umount sequence is now more obvious as a result. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com> Cc: Alexander Viro <aviro@redhat.com>
Diffstat (limited to 'fs/gfs2/ops_super.c')
-rw-r--r--fs/gfs2/ops_super.c57
1 files changed, 48 insertions, 9 deletions
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index f66ea0f7a356..8f332d26b5dd 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -63,6 +63,39 @@ static int gfs2_write_inode(struct inode *inode, int sync)
63} 63}
64 64
65/** 65/**
66 * gfs2_make_fs_ro - Turn a Read-Write FS into a Read-Only one
67 * @sdp: the filesystem
68 *
69 * Returns: errno
70 */
71
72static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
73{
74 struct gfs2_holder t_gh;
75 int error;
76
77 gfs2_quota_sync(sdp);
78 gfs2_statfs_sync(sdp);
79
80 error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE,
81 &t_gh);
82 if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
83 return error;
84
85 gfs2_meta_syncfs(sdp);
86 gfs2_log_shutdown(sdp);
87
88 clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
89
90 if (t_gh.gh_gl)
91 gfs2_glock_dq_uninit(&t_gh);
92
93 gfs2_quota_cleanup(sdp);
94
95 return error;
96}
97
98/**
66 * gfs2_put_super - Unmount the filesystem 99 * gfs2_put_super - Unmount the filesystem
67 * @sb: The VFS superblock 100 * @sb: The VFS superblock
68 * 101 *
@@ -73,12 +106,6 @@ static void gfs2_put_super(struct super_block *sb)
73 struct gfs2_sbd *sdp = sb->s_fs_info; 106 struct gfs2_sbd *sdp = sb->s_fs_info;
74 int error; 107 int error;
75 108
76 if (!sdp)
77 return;
78
79 if (!strncmp(sb->s_type->name, "gfs2meta", 8))
80 return; /* Nothing to do */
81
82 /* Unfreeze the filesystem, if we need to */ 109 /* Unfreeze the filesystem, if we need to */
83 110
84 mutex_lock(&sdp->sd_freeze_lock); 111 mutex_lock(&sdp->sd_freeze_lock);
@@ -101,7 +128,6 @@ static void gfs2_put_super(struct super_block *sb)
101 128
102 /* Release stuff */ 129 /* Release stuff */
103 130
104 iput(sdp->sd_master_dir);
105 iput(sdp->sd_jindex); 131 iput(sdp->sd_jindex);
106 iput(sdp->sd_inum_inode); 132 iput(sdp->sd_inum_inode);
107 iput(sdp->sd_statfs_inode); 133 iput(sdp->sd_statfs_inode);
@@ -152,6 +178,7 @@ static void gfs2_write_super(struct super_block *sb)
152 * 178 *
153 * Flushes the log to disk. 179 * Flushes the log to disk.
154 */ 180 */
181
155static int gfs2_sync_fs(struct super_block *sb, int wait) 182static int gfs2_sync_fs(struct super_block *sb, int wait)
156{ 183{
157 sb->s_dirt = 0; 184 sb->s_dirt = 0;
@@ -295,6 +322,7 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
295 * inode's blocks, or alternatively pass the baton on to another 322 * inode's blocks, or alternatively pass the baton on to another
296 * node for later deallocation. 323 * node for later deallocation.
297 */ 324 */
325
298static void gfs2_drop_inode(struct inode *inode) 326static void gfs2_drop_inode(struct inode *inode)
299{ 327{
300 struct gfs2_inode *ip = GFS2_I(inode); 328 struct gfs2_inode *ip = GFS2_I(inode);
@@ -333,6 +361,16 @@ static void gfs2_clear_inode(struct inode *inode)
333 } 361 }
334} 362}
335 363
364static int is_ancestor(const struct dentry *d1, const struct dentry *d2)
365{
366 do {
367 if (d1 == d2)
368 return 1;
369 d1 = d1->d_parent;
370 } while (!IS_ROOT(d1));
371 return 0;
372}
373
336/** 374/**
337 * gfs2_show_options - Show mount options for /proc/mounts 375 * gfs2_show_options - Show mount options for /proc/mounts
338 * @s: seq_file structure 376 * @s: seq_file structure
@@ -346,6 +384,8 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
346 struct gfs2_sbd *sdp = mnt->mnt_sb->s_fs_info; 384 struct gfs2_sbd *sdp = mnt->mnt_sb->s_fs_info;
347 struct gfs2_args *args = &sdp->sd_args; 385 struct gfs2_args *args = &sdp->sd_args;
348 386
387 if (is_ancestor(mnt->mnt_root, sdp->sd_master_dir))
388 seq_printf(s, ",meta");
349 if (args->ar_lockproto[0]) 389 if (args->ar_lockproto[0])
350 seq_printf(s, ",lockproto=%s", args->ar_lockproto); 390 seq_printf(s, ",lockproto=%s", args->ar_lockproto);
351 if (args->ar_locktable[0]) 391 if (args->ar_locktable[0])
@@ -414,6 +454,7 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
414 * conversion on the iopen lock, but we can change that later. This 454 * conversion on the iopen lock, but we can change that later. This
415 * is safe, just less efficient. 455 * is safe, just less efficient.
416 */ 456 */
457
417static void gfs2_delete_inode(struct inode *inode) 458static void gfs2_delete_inode(struct inode *inode)
418{ 459{
419 struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; 460 struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
@@ -478,8 +519,6 @@ out:
478 clear_inode(inode); 519 clear_inode(inode);
479} 520}
480 521
481
482
483static struct inode *gfs2_alloc_inode(struct super_block *sb) 522static struct inode *gfs2_alloc_inode(struct super_block *sb)
484{ 523{
485 struct gfs2_inode *ip; 524 struct gfs2_inode *ip;