aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAbhijith Das <adas@redhat.com>2006-08-25 12:13:37 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-08-25 17:19:55 -0400
commit8638460540749ddb1beca9e9a68d655a6fe6df65 (patch)
treee0b0a65798185a3f00912011906c551c02777982 /fs
parent5f88f1ea16a2fb5f125505053d1bfb7901a88c64 (diff)
[GFS2] Allow mounting of gfs2 and gfs2meta at the same time
This patch allows the simultaneous mounting of gfs2meta and gfs2 filesystems. A restriction however is that a gfs2meta fs may only be mounted if its corresponding gfs2 filesystem is also mounted. Also, a gfs2 filesystem cannot be unmounted before its gfs2meta filesystem. Signed-off-by: Abhijith Das <adas@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/glock.c6
-rw-r--r--fs/gfs2/incore.h2
-rw-r--r--fs/gfs2/ops_fstype.c147
-rw-r--r--fs/gfs2/ops_super.c3
4 files changed, 155 insertions, 3 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 005788fb361f..ef713dbff601 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -1165,7 +1165,13 @@ static void add_to_queue(struct gfs2_holder *gh)
1165 existing = find_holder_by_owner(&gl->gl_holders, gh->gh_owner); 1165 existing = find_holder_by_owner(&gl->gl_holders, gh->gh_owner);
1166 if (existing) { 1166 if (existing) {
1167 print_symbol(KERN_WARNING "original: %s\n", existing->gh_ip); 1167 print_symbol(KERN_WARNING "original: %s\n", existing->gh_ip);
1168 printk(KERN_INFO "pid : %d\n", existing->gh_owner->pid);
1169 printk(KERN_INFO "lock type : %d lock state : %d\n",
1170 existing->gh_gl->gl_name.ln_type, existing->gh_gl->gl_state);
1168 print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip); 1171 print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip);
1172 printk(KERN_INFO "pid : %d\n", gh->gh_owner->pid);
1173 printk(KERN_INFO "lock type : %d lock state : %d\n",
1174 gl->gl_name.ln_type, gl->gl_state);
1169 BUG(); 1175 BUG();
1170 } 1176 }
1171 1177
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 78d3cb511eb8..77f0903d2f3e 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -472,6 +472,7 @@ enum {
472 472
473struct gfs2_sbd { 473struct gfs2_sbd {
474 struct super_block *sd_vfs; 474 struct super_block *sd_vfs;
475 struct super_block *sd_vfs_meta;
475 struct kobject sd_kobj; 476 struct kobject sd_kobj;
476 unsigned long sd_flags; /* SDF_... */ 477 unsigned long sd_flags; /* SDF_... */
477 struct gfs2_sb sd_sb; 478 struct gfs2_sb sd_sb;
@@ -652,6 +653,7 @@ struct gfs2_sbd {
652 /* Debugging crud */ 653 /* Debugging crud */
653 654
654 unsigned long sd_last_warning; 655 unsigned long sd_last_warning;
656 struct vfsmount *sd_gfs2mnt;
655}; 657};
656 658
657#endif /* __INCORE_DOT_H__ */ 659#endif /* __INCORE_DOT_H__ */
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index c66067c84bcf..e5a91ead250c 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -15,6 +15,8 @@
15#include <linux/vmalloc.h> 15#include <linux/vmalloc.h>
16#include <linux/blkdev.h> 16#include <linux/blkdev.h>
17#include <linux/kthread.h> 17#include <linux/kthread.h>
18#include <linux/namei.h>
19#include <linux/mount.h>
18#include <linux/gfs2_ondisk.h> 20#include <linux/gfs2_ondisk.h>
19 21
20#include "gfs2.h" 22#include "gfs2.h"
@@ -813,7 +815,138 @@ static int fill_super(struct super_block *sb, void *data, int silent)
813static int gfs2_get_sb(struct file_system_type *fs_type, int flags, 815static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
814 const char *dev_name, void *data, struct vfsmount *mnt) 816 const char *dev_name, void *data, struct vfsmount *mnt)
815{ 817{
816 return get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt); 818 struct super_block *sb;
819 struct gfs2_sbd *sdp;
820 int error = get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt);
821 if (error)
822 goto out;
823 sb = mnt->mnt_sb;
824 sdp = (struct gfs2_sbd*)sb->s_fs_info;
825 sdp->sd_gfs2mnt = mnt;
826out:
827 return error;
828}
829
830static int fill_super_meta(struct super_block *sb, struct super_block *new,
831 void *data, int silent)
832{
833 struct gfs2_sbd *sdp = sb->s_fs_info;
834 struct inode *inode;
835 int error = 0;
836
837 new->s_fs_info = sdp;
838 sdp->sd_vfs_meta = sb;
839
840 init_vfs(new, SDF_NOATIME);
841
842 /* Get the master inode */
843 inode = igrab(sdp->sd_master_dir);
844
845 new->s_root = d_alloc_root(inode);
846 if (!new->s_root) {
847 fs_err(sdp, "can't get root dentry\n");
848 error = -ENOMEM;
849 iput(inode);
850 }
851 new->s_root->d_op = &gfs2_dops;
852
853 return error;
854}
855static int set_bdev_super(struct super_block *s, void *data)
856{
857 s->s_bdev = data;
858 s->s_dev = s->s_bdev->bd_dev;
859 return 0;
860}
861
862static int test_bdev_super(struct super_block *s, void *data)
863{
864 return (void *)s->s_bdev == data;
865}
866
867static struct super_block* get_gfs2_sb(const char *dev_name)
868{
869 struct kstat stat;
870 struct nameidata nd;
871 struct file_system_type *fstype;
872 struct super_block *sb = NULL, *s;
873 struct list_head *l;
874 int error;
875
876 error = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
877 if (error) {
878 printk(KERN_WARNING "GFS2: path_lookup on %s returned error\n",
879 dev_name);
880 goto out;
881 }
882 error = vfs_getattr(nd.mnt, nd.dentry, &stat);
883
884 fstype = get_fs_type("gfs2");
885 list_for_each(l, &fstype->fs_supers) {
886 s = list_entry(l, struct super_block, s_instances);
887 if ((S_ISBLK(stat.mode) && s->s_dev == stat.rdev) ||
888 (S_ISDIR(stat.mode) && s == nd.dentry->d_inode->i_sb)) {
889 sb = s;
890 goto free_nd;
891 }
892 }
893
894 printk(KERN_WARNING "GFS2: Unrecognized block device or "
895 "mount point %s", dev_name);
896
897free_nd:
898 path_release(&nd);
899out:
900 return sb;
901}
902
903static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags,
904 const char *dev_name, void *data, struct vfsmount *mnt)
905{
906 int error = 0;
907 struct super_block *sb = NULL, *new;
908 struct gfs2_sbd *sdp;
909 char *gfs2mnt = NULL;
910
911 sb = get_gfs2_sb(dev_name);
912 if (!sb) {
913 printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n");
914 error = -ENOENT;
915 goto error;
916 }
917 sdp = (struct gfs2_sbd*) sb->s_fs_info;
918 if (sdp->sd_vfs_meta) {
919 printk(KERN_WARNING "GFS2: gfs2meta mount already exists\n");
920 error = -EBUSY;
921 goto error;
922 }
923 mutex_lock(&sb->s_bdev->bd_mount_mutex);
924 new = sget(fs_type, test_bdev_super, set_bdev_super, sb->s_bdev);
925 mutex_unlock(&sb->s_bdev->bd_mount_mutex);
926 if (IS_ERR(new)) {
927 error = PTR_ERR(new);
928 goto error;
929 }
930 module_put(fs_type->owner);
931 new->s_flags = flags;
932 strlcpy(new->s_id, sb->s_id, sizeof(new->s_id));
933 sb_set_blocksize(new, sb->s_blocksize);
934 error = fill_super_meta(sb, new, data, flags & MS_SILENT ? 1 : 0);
935 if (error) {
936 up_write(&new->s_umount);
937 deactivate_super(new);
938 goto error;
939 }
940
941 new->s_flags |= MS_ACTIVE;
942
943 /* Grab a reference to the gfs2 mount point */
944 atomic_inc(&sdp->sd_gfs2mnt->mnt_count);
945 return simple_set_mnt(mnt, new);
946error:
947 if (gfs2mnt)
948 kfree(gfs2mnt);
949 return error;
817} 950}
818 951
819static void gfs2_kill_sb(struct super_block *sb) 952static void gfs2_kill_sb(struct super_block *sb)
@@ -821,6 +954,14 @@ static void gfs2_kill_sb(struct super_block *sb)
821 kill_block_super(sb); 954 kill_block_super(sb);
822} 955}
823 956
957static void gfs2_kill_sb_meta(struct super_block *sb)
958{
959 struct gfs2_sbd *sdp = sb->s_fs_info;
960 generic_shutdown_super(sb);
961 sdp->sd_vfs_meta = NULL;
962 atomic_dec(&sdp->sd_gfs2mnt->mnt_count);
963}
964
824struct file_system_type gfs2_fs_type = { 965struct file_system_type gfs2_fs_type = {
825 .name = "gfs2", 966 .name = "gfs2",
826 .fs_flags = FS_REQUIRES_DEV, 967 .fs_flags = FS_REQUIRES_DEV,
@@ -832,8 +973,8 @@ struct file_system_type gfs2_fs_type = {
832struct file_system_type gfs2meta_fs_type = { 973struct file_system_type gfs2meta_fs_type = {
833 .name = "gfs2meta", 974 .name = "gfs2meta",
834 .fs_flags = FS_REQUIRES_DEV, 975 .fs_flags = FS_REQUIRES_DEV,
835 .get_sb = gfs2_get_sb, 976 .get_sb = gfs2_get_sb_meta,
836 .kill_sb = gfs2_kill_sb, 977 .kill_sb = gfs2_kill_sb_meta,
837 .owner = THIS_MODULE, 978 .owner = THIS_MODULE,
838}; 979};
839 980
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index 2e392c994ab1..18ed18c729e8 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -78,6 +78,9 @@ static void gfs2_put_super(struct super_block *sb)
78 if (!sdp) 78 if (!sdp)
79 return; 79 return;
80 80
81 if (!strncmp(sb->s_type->name, "gfs2meta", 8))
82 return; /* meta fs. don't do nothin' */
83
81 /* Unfreeze the filesystem, if we need to */ 84 /* Unfreeze the filesystem, if we need to */
82 85
83 mutex_lock(&sdp->sd_freeze_lock); 86 mutex_lock(&sdp->sd_freeze_lock);