diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2008-08-08 08:45:13 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2008-08-13 04:59:40 -0400 |
commit | 9b8df98fc8973ad1c5f0d7c4cf71c7fb84fe22c5 (patch) | |
tree | 6a0445afd83d0f7a63a301c2e146647abf59ad82 /fs/gfs2/ops_super.c | |
parent | c1e817d03a7de57a963654c35e6e80af9a5dbff5 (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.c | 57 |
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 | |||
72 | static 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 | |||
155 | static int gfs2_sync_fs(struct super_block *sb, int wait) | 182 | static 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 | |||
298 | static void gfs2_drop_inode(struct inode *inode) | 326 | static 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 | ||
364 | static 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 | |||
417 | static void gfs2_delete_inode(struct inode *inode) | 458 | static 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 | |||
483 | static struct inode *gfs2_alloc_inode(struct super_block *sb) | 522 | static struct inode *gfs2_alloc_inode(struct super_block *sb) |
484 | { | 523 | { |
485 | struct gfs2_inode *ip; | 524 | struct gfs2_inode *ip; |