aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2010-08-15 12:54:52 -0400
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2010-10-22 20:24:36 -0400
commitf11459ad7dab9e9eb5a05b8bd3bec338ea8f485d (patch)
tree91808a1f88f6ad24f381473e1bde22f10cac49e6 /fs
parentab4d8f7ebf33beff97e766d18db47f1ea9635769 (diff)
nilfs2: do not allocate multiple super block instances for a device
This stops allocating multiple super block instances for a device. All snapshots and a current mode mount (i.e. latest tree) will be controlled with nilfs_root objects that are kept within an sb instance. nilfs_get_sb() is rewritten so that it always has a root object for the latest tree and snapshots make additional root objects. The root dentry of the latest tree is binded to sb->s_root even if it isn't attached on a directory. Root dentries of snapshots or the latest tree are binded to mnt->mnt_root on which they are mounted. With this patch, nilfs_find_sbinfo() function, nilfs->ns_supers list, and nilfs->ns_current back pointer, are deleted. In addition, init_nilfs() and load_nilfs() are simplified since they will be called once for a device, not repeatedly called for mount points. Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Diffstat (limited to 'fs')
-rw-r--r--fs/nilfs2/sb.h5
-rw-r--r--fs/nilfs2/super.c216
-rw-r--r--fs/nilfs2/the_nilfs.c89
-rw-r--r--fs/nilfs2/the_nilfs.h16
4 files changed, 101 insertions, 225 deletions
diff --git a/fs/nilfs2/sb.h b/fs/nilfs2/sb.h
index 3cc3675c3abe..35a07157b980 100644
--- a/fs/nilfs2/sb.h
+++ b/fs/nilfs2/sb.h
@@ -42,9 +42,6 @@ struct nilfs_sc_info;
42 * NILFS super-block data in memory 42 * NILFS super-block data in memory
43 */ 43 */
44struct nilfs_sb_info { 44struct nilfs_sb_info {
45 /* Snapshot status */
46 __u64 s_snapshot_cno; /* Checkpoint number */
47
48 /* Mount options */ 45 /* Mount options */
49 unsigned long s_mount_opt; 46 unsigned long s_mount_opt;
50 uid_t s_resuid; 47 uid_t s_resuid;
@@ -57,8 +54,6 @@ struct nilfs_sb_info {
57 /* Fundamental members */ 54 /* Fundamental members */
58 struct super_block *s_super; /* reverse pointer to super_block */ 55 struct super_block *s_super; /* reverse pointer to super_block */
59 struct the_nilfs *s_nilfs; 56 struct the_nilfs *s_nilfs;
60 struct list_head s_list; /* list head for nilfs->ns_supers */
61 atomic_t s_count; /* reference count */
62 57
63 /* Segment constructor */ 58 /* Segment constructor */
64 struct list_head s_dirty_files; /* dirty files list */ 59 struct list_head s_dirty_files; /* dirty files list */
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index ebeb746c4845..2e58e7c629b5 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -355,16 +355,11 @@ static void nilfs_put_super(struct super_block *sb)
355 nilfs_cleanup_super(sbi); 355 nilfs_cleanup_super(sbi);
356 up_write(&nilfs->ns_sem); 356 up_write(&nilfs->ns_sem);
357 } 357 }
358 down_write(&nilfs->ns_super_sem);
359 if (nilfs->ns_current == sbi)
360 nilfs->ns_current = NULL;
361 list_del_init(&sbi->s_list);
362 up_write(&nilfs->ns_super_sem);
363 358
364 put_nilfs(sbi->s_nilfs); 359 put_nilfs(sbi->s_nilfs);
365 sbi->s_super = NULL; 360 sbi->s_super = NULL;
366 sb->s_fs_info = NULL; 361 sb->s_fs_info = NULL;
367 nilfs_put_sbinfo(sbi); 362 kfree(sbi);
368} 363}
369 364
370static int nilfs_sync_fs(struct super_block *sb, int wait) 365static int nilfs_sync_fs(struct super_block *sb, int wait)
@@ -500,12 +495,12 @@ static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
500{ 495{
501 struct super_block *sb = vfs->mnt_sb; 496 struct super_block *sb = vfs->mnt_sb;
502 struct nilfs_sb_info *sbi = NILFS_SB(sb); 497 struct nilfs_sb_info *sbi = NILFS_SB(sb);
498 struct nilfs_root *root = NILFS_I(vfs->mnt_root->d_inode)->i_root;
503 499
504 if (!nilfs_test_opt(sbi, BARRIER)) 500 if (!nilfs_test_opt(sbi, BARRIER))
505 seq_puts(seq, ",nobarrier"); 501 seq_puts(seq, ",nobarrier");
506 if (nilfs_test_opt(sbi, SNAPSHOT)) 502 if (root->cno != NILFS_CPTREE_CURRENT_CNO)
507 seq_printf(seq, ",cp=%llu", 503 seq_printf(seq, ",cp=%llu", (unsigned long long)root->cno);
508 (unsigned long long int)sbi->s_snapshot_cno);
509 if (nilfs_test_opt(sbi, ERRORS_PANIC)) 504 if (nilfs_test_opt(sbi, ERRORS_PANIC))
510 seq_puts(seq, ",errors=panic"); 505 seq_puts(seq, ",errors=panic");
511 if (nilfs_test_opt(sbi, ERRORS_CONT)) 506 if (nilfs_test_opt(sbi, ERRORS_CONT))
@@ -605,27 +600,11 @@ static int parse_options(char *options, struct super_block *sb, int is_remount)
605 if (match_int(&args[0], &option) || option <= 0) 600 if (match_int(&args[0], &option) || option <= 0)
606 return 0; 601 return 0;
607 if (is_remount) { 602 if (is_remount) {
608 if (!nilfs_test_opt(sbi, SNAPSHOT)) { 603 printk(KERN_ERR
609 printk(KERN_ERR 604 "NILFS: \"%s\" option is invalid "
610 "NILFS: cannot change regular " 605 "for remount.\n", p);
611 "mount to snapshot.\n");
612 return 0;
613 } else if (option != sbi->s_snapshot_cno) {
614 printk(KERN_ERR
615 "NILFS: cannot remount to a "
616 "different snapshot.\n");
617 return 0;
618 }
619 break;
620 }
621 if (!(sb->s_flags & MS_RDONLY)) {
622 printk(KERN_ERR "NILFS: cannot mount snapshot "
623 "read/write. A read-only option is "
624 "required.\n");
625 return 0; 606 return 0;
626 } 607 }
627 sbi->s_snapshot_cno = option;
628 nilfs_set_opt(sbi, SNAPSHOT);
629 break; 608 break;
630 case Opt_norecovery: 609 case Opt_norecovery:
631 nilfs_set_opt(sbi, NORECOVERY); 610 nilfs_set_opt(sbi, NORECOVERY);
@@ -771,16 +750,32 @@ static int nilfs_get_root_dentry(struct super_block *sb,
771 goto out; 750 goto out;
772 } 751 }
773 752
774 dentry = d_alloc_root(inode); 753 if (root->cno == NILFS_CPTREE_CURRENT_CNO) {
775 if (!dentry) { 754 dentry = d_find_alias(inode);
776 iput(inode); 755 if (!dentry) {
777 printk(KERN_ERR "NILFS: get root dentry failed\n"); 756 dentry = d_alloc_root(inode);
778 ret = -ENOMEM; 757 if (!dentry) {
779 goto out; 758 iput(inode);
759 ret = -ENOMEM;
760 goto failed_dentry;
761 }
762 } else {
763 iput(inode);
764 }
765 } else {
766 dentry = d_obtain_alias(inode);
767 if (IS_ERR(dentry)) {
768 ret = PTR_ERR(dentry);
769 goto failed_dentry;
770 }
780 } 771 }
781 *root_dentry = dentry; 772 *root_dentry = dentry;
782 out: 773 out:
783 return ret; 774 return ret;
775
776 failed_dentry:
777 printk(KERN_ERR "NILFS: get root dentry failed\n");
778 goto out;
784} 779}
785 780
786static int nilfs_attach_snapshot(struct super_block *s, __u64 cno, 781static int nilfs_attach_snapshot(struct super_block *s, __u64 cno,
@@ -817,6 +812,25 @@ static int nilfs_attach_snapshot(struct super_block *s, __u64 cno,
817 return ret; 812 return ret;
818} 813}
819 814
815static int nilfs_tree_was_touched(struct dentry *root_dentry)
816{
817 return atomic_read(&root_dentry->d_count) > 1;
818}
819
820/**
821 * nilfs_try_to_shrink_tree() - try to shrink dentries of a checkpoint
822 * @root_dentry: root dentry of the tree to be shrunk
823 *
824 * This function returns true if the tree was in-use.
825 */
826static int nilfs_try_to_shrink_tree(struct dentry *root_dentry)
827{
828 if (have_submounts(root_dentry))
829 return true;
830 shrink_dcache_parent(root_dentry);
831 return nilfs_tree_was_touched(root_dentry);
832}
833
820/** 834/**
821 * nilfs_fill_super() - initialize a super block instance 835 * nilfs_fill_super() - initialize a super block instance
822 * @sb: super_block 836 * @sb: super_block
@@ -845,7 +859,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
845 get_nilfs(nilfs); 859 get_nilfs(nilfs);
846 sbi->s_nilfs = nilfs; 860 sbi->s_nilfs = nilfs;
847 sbi->s_super = sb; 861 sbi->s_super = sb;
848 atomic_set(&sbi->s_count, 1);
849 862
850 err = init_nilfs(nilfs, sbi, (char *)data); 863 err = init_nilfs(nilfs, sbi, (char *)data);
851 if (err) 864 if (err)
@@ -853,7 +866,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
853 866
854 spin_lock_init(&sbi->s_inode_lock); 867 spin_lock_init(&sbi->s_inode_lock);
855 INIT_LIST_HEAD(&sbi->s_dirty_files); 868 INIT_LIST_HEAD(&sbi->s_dirty_files);
856 INIT_LIST_HEAD(&sbi->s_list);
857 869
858 /* 870 /*
859 * Following initialization is overlapped because 871 * Following initialization is overlapped because
@@ -875,20 +887,11 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
875 if (err) 887 if (err)
876 goto failed_sbi; 888 goto failed_sbi;
877 889
878 if (nilfs_test_opt(sbi, SNAPSHOT)) {
879 err = nilfs_attach_snapshot(sb, sbi->s_snapshot_cno,
880 &sb->s_root);
881 if (err)
882 goto failed_sbi;
883
884 goto add_to_supers;
885 }
886
887 cno = nilfs_last_cno(nilfs); 890 cno = nilfs_last_cno(nilfs);
888 err = nilfs_attach_checkpoint(sbi, cno, true, &fsroot); 891 err = nilfs_attach_checkpoint(sbi, cno, true, &fsroot);
889 if (err) { 892 if (err) {
890 printk(KERN_ERR "NILFS: error loading a checkpoint" 893 printk(KERN_ERR "NILFS: error loading last checkpoint "
891 " (checkpoint number=%llu).\n", (unsigned long long)cno); 894 "(checkpoint number=%llu).\n", (unsigned long long)cno);
892 goto failed_sbi; 895 goto failed_sbi;
893 } 896 }
894 897
@@ -910,13 +913,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
910 up_write(&nilfs->ns_sem); 913 up_write(&nilfs->ns_sem);
911 } 914 }
912 915
913 add_to_supers:
914 down_write(&nilfs->ns_super_sem);
915 list_add(&sbi->s_list, &nilfs->ns_supers);
916 if (!nilfs_test_opt(sbi, SNAPSHOT))
917 nilfs->ns_current = sbi;
918 up_write(&nilfs->ns_super_sem);
919
920 return 0; 916 return 0;
921 917
922 failed_segctor: 918 failed_segctor:
@@ -928,7 +924,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
928 failed_sbi: 924 failed_sbi:
929 put_nilfs(nilfs); 925 put_nilfs(nilfs);
930 sb->s_fs_info = NULL; 926 sb->s_fs_info = NULL;
931 nilfs_put_sbinfo(sbi); 927 kfree(sbi);
932 return err; 928 return err;
933} 929}
934 930
@@ -938,13 +934,10 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
938 struct the_nilfs *nilfs = sbi->s_nilfs; 934 struct the_nilfs *nilfs = sbi->s_nilfs;
939 unsigned long old_sb_flags; 935 unsigned long old_sb_flags;
940 struct nilfs_mount_options old_opts; 936 struct nilfs_mount_options old_opts;
941 int was_snapshot, err; 937 int err;
942 938
943 down_write(&nilfs->ns_super_sem);
944 old_sb_flags = sb->s_flags; 939 old_sb_flags = sb->s_flags;
945 old_opts.mount_opt = sbi->s_mount_opt; 940 old_opts.mount_opt = sbi->s_mount_opt;
946 old_opts.snapshot_cno = sbi->s_snapshot_cno;
947 was_snapshot = nilfs_test_opt(sbi, SNAPSHOT);
948 941
949 if (!parse_options(data, sb, 1)) { 942 if (!parse_options(data, sb, 1)) {
950 err = -EINVAL; 943 err = -EINVAL;
@@ -953,11 +946,6 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
953 sb->s_flags = (sb->s_flags & ~MS_POSIXACL); 946 sb->s_flags = (sb->s_flags & ~MS_POSIXACL);
954 947
955 err = -EINVAL; 948 err = -EINVAL;
956 if (was_snapshot && !(*flags & MS_RDONLY)) {
957 printk(KERN_ERR "NILFS (device %s): cannot remount snapshot "
958 "read/write.\n", sb->s_id);
959 goto restore_opts;
960 }
961 949
962 if (!nilfs_valid_fs(nilfs)) { 950 if (!nilfs_valid_fs(nilfs)) {
963 printk(KERN_WARNING "NILFS (device %s): couldn't " 951 printk(KERN_WARNING "NILFS (device %s): couldn't "
@@ -1014,14 +1002,11 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
1014 up_write(&nilfs->ns_sem); 1002 up_write(&nilfs->ns_sem);
1015 } 1003 }
1016 out: 1004 out:
1017 up_write(&nilfs->ns_super_sem);
1018 return 0; 1005 return 0;
1019 1006
1020 restore_opts: 1007 restore_opts:
1021 sb->s_flags = old_sb_flags; 1008 sb->s_flags = old_sb_flags;
1022 sbi->s_mount_opt = old_opts.mount_opt; 1009 sbi->s_mount_opt = old_opts.mount_opt;
1023 sbi->s_snapshot_cno = old_opts.snapshot_cno;
1024 up_write(&nilfs->ns_super_sem);
1025 return err; 1010 return err;
1026} 1011}
1027 1012
@@ -1075,18 +1060,14 @@ static int nilfs_identify(char *data, struct nilfs_super_data *sd)
1075 1060
1076static int nilfs_set_bdev_super(struct super_block *s, void *data) 1061static int nilfs_set_bdev_super(struct super_block *s, void *data)
1077{ 1062{
1078 struct nilfs_super_data *sd = data; 1063 s->s_bdev = data;
1079
1080 s->s_bdev = sd->bdev;
1081 s->s_dev = s->s_bdev->bd_dev; 1064 s->s_dev = s->s_bdev->bd_dev;
1082 return 0; 1065 return 0;
1083} 1066}
1084 1067
1085static int nilfs_test_bdev_super(struct super_block *s, void *data) 1068static int nilfs_test_bdev_super(struct super_block *s, void *data)
1086{ 1069{
1087 struct nilfs_super_data *sd = data; 1070 return (void *)s->s_bdev == data;
1088
1089 return sd->sbi && s->s_fs_info == (void *)sd->sbi;
1090} 1071}
1091 1072
1092static int 1073static int
@@ -1097,7 +1078,8 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
1097 struct super_block *s; 1078 struct super_block *s;
1098 fmode_t mode = FMODE_READ; 1079 fmode_t mode = FMODE_READ;
1099 struct the_nilfs *nilfs; 1080 struct the_nilfs *nilfs;
1100 int err, need_to_close = 1; 1081 struct dentry *root_dentry;
1082 int err, s_new = false;
1101 1083
1102 if (!(flags & MS_RDONLY)) 1084 if (!(flags & MS_RDONLY))
1103 mode |= FMODE_WRITE; 1085 mode |= FMODE_WRITE;
@@ -1106,12 +1088,6 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
1106 if (IS_ERR(sd.bdev)) 1088 if (IS_ERR(sd.bdev))
1107 return PTR_ERR(sd.bdev); 1089 return PTR_ERR(sd.bdev);
1108 1090
1109 /*
1110 * To get mount instance using sget() vfs-routine, NILFS needs
1111 * much more information than normal filesystems to identify mount
1112 * instance. For snapshot mounts, not only a mount type (ro-mount
1113 * or rw-mount) but also a checkpoint number is required.
1114 */
1115 sd.cno = 0; 1091 sd.cno = 0;
1116 sd.flags = flags; 1092 sd.flags = flags;
1117 if (nilfs_identify((char *)data, &sd)) { 1093 if (nilfs_identify((char *)data, &sd)) {
@@ -1127,38 +1103,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
1127 1103
1128 mutex_lock(&nilfs->ns_mount_mutex); 1104 mutex_lock(&nilfs->ns_mount_mutex);
1129 1105
1130 if (!sd.cno) { 1106 s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, sd.bdev);
1131 /*
1132 * Check if an exclusive mount exists or not.
1133 * Snapshot mounts coexist with a current mount
1134 * (i.e. rw-mount or ro-mount), whereas rw-mount and
1135 * ro-mount are mutually exclusive.
1136 */
1137 down_read(&nilfs->ns_super_sem);
1138 if (nilfs->ns_current &&
1139 ((nilfs->ns_current->s_super->s_flags ^ flags)
1140 & MS_RDONLY)) {
1141 up_read(&nilfs->ns_super_sem);
1142 err = -EBUSY;
1143 goto failed_unlock;
1144 }
1145 up_read(&nilfs->ns_super_sem);
1146 }
1147
1148 /*
1149 * Find existing nilfs_sb_info struct
1150 */
1151 sd.sbi = nilfs_find_sbinfo(nilfs, !(flags & MS_RDONLY), sd.cno);
1152
1153 /*
1154 * Get super block instance holding the nilfs_sb_info struct.
1155 * A new instance is allocated if no existing mount is present or
1156 * existing instance has been unmounted.
1157 */
1158 s = sget(fs_type, nilfs_test_bdev_super, nilfs_set_bdev_super, &sd);
1159 if (sd.sbi)
1160 nilfs_put_sbinfo(sd.sbi);
1161
1162 if (IS_ERR(s)) { 1107 if (IS_ERR(s)) {
1163 err = PTR_ERR(s); 1108 err = PTR_ERR(s);
1164 goto failed_unlock; 1109 goto failed_unlock;
@@ -1167,6 +1112,8 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
1167 if (!s->s_root) { 1112 if (!s->s_root) {
1168 char b[BDEVNAME_SIZE]; 1113 char b[BDEVNAME_SIZE];
1169 1114
1115 s_new = true;
1116
1170 /* New superblock instance created */ 1117 /* New superblock instance created */
1171 s->s_flags = flags; 1118 s->s_flags = flags;
1172 s->s_mode = mode; 1119 s->s_mode = mode;
@@ -1179,16 +1126,53 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
1179 goto cancel_new; 1126 goto cancel_new;
1180 1127
1181 s->s_flags |= MS_ACTIVE; 1128 s->s_flags |= MS_ACTIVE;
1182 need_to_close = 0; 1129 } else if (!sd.cno) {
1130 int busy = false;
1131
1132 if (nilfs_tree_was_touched(s->s_root)) {
1133 busy = nilfs_try_to_shrink_tree(s->s_root);
1134 if (busy && (flags ^ s->s_flags) & MS_RDONLY) {
1135 printk(KERN_ERR "NILFS: the device already "
1136 "has a %s mount.\n",
1137 (s->s_flags & MS_RDONLY) ?
1138 "read-only" : "read/write");
1139 err = -EBUSY;
1140 goto failed_super;
1141 }
1142 }
1143 if (!busy) {
1144 /*
1145 * Try remount to setup mount states if the current
1146 * tree is not mounted and only snapshots use this sb.
1147 */
1148 err = nilfs_remount(s, &flags, data);
1149 if (err)
1150 goto failed_super;
1151 }
1152 }
1153
1154 if (sd.cno) {
1155 err = nilfs_attach_snapshot(s, sd.cno, &root_dentry);
1156 if (err) {
1157 if (s_new)
1158 goto cancel_new;
1159 goto failed_super;
1160 }
1161 } else {
1162 root_dentry = dget(s->s_root);
1183 } 1163 }
1184 1164
1185 mutex_unlock(&nilfs->ns_mount_mutex); 1165 mutex_unlock(&nilfs->ns_mount_mutex);
1186 put_nilfs(nilfs); 1166 put_nilfs(nilfs);
1187 if (need_to_close) 1167 if (!s_new)
1188 close_bdev_exclusive(sd.bdev, mode); 1168 close_bdev_exclusive(sd.bdev, mode);
1189 simple_set_mnt(mnt, s); 1169
1170 mnt->mnt_sb = s;
1171 mnt->mnt_root = root_dentry;
1190 return 0; 1172 return 0;
1191 1173
1174 failed_super:
1175 deactivate_locked_super(s);
1192 failed_unlock: 1176 failed_unlock:
1193 mutex_unlock(&nilfs->ns_mount_mutex); 1177 mutex_unlock(&nilfs->ns_mount_mutex);
1194 put_nilfs(nilfs); 1178 put_nilfs(nilfs);
@@ -1202,7 +1186,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
1202 put_nilfs(nilfs); 1186 put_nilfs(nilfs);
1203 deactivate_locked_super(s); 1187 deactivate_locked_super(s);
1204 /* 1188 /*
1205 * deactivate_locked_super() invokes close_bdev_exclusive(). 1189 * This deactivate_locked_super() invokes close_bdev_exclusive().
1206 * We must finish all post-cleaning before this call; 1190 * We must finish all post-cleaning before this call;
1207 * put_nilfs() needs the block device. 1191 * put_nilfs() needs the block device.
1208 */ 1192 */
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index 89c78562d0e9..960c28797bb2 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -82,11 +82,9 @@ static struct the_nilfs *alloc_nilfs(struct block_device *bdev)
82 atomic_set(&nilfs->ns_count, 1); 82 atomic_set(&nilfs->ns_count, 1);
83 atomic_set(&nilfs->ns_ndirtyblks, 0); 83 atomic_set(&nilfs->ns_ndirtyblks, 0);
84 init_rwsem(&nilfs->ns_sem); 84 init_rwsem(&nilfs->ns_sem);
85 init_rwsem(&nilfs->ns_super_sem);
86 mutex_init(&nilfs->ns_mount_mutex); 85 mutex_init(&nilfs->ns_mount_mutex);
87 init_rwsem(&nilfs->ns_writer_sem); 86 init_rwsem(&nilfs->ns_writer_sem);
88 INIT_LIST_HEAD(&nilfs->ns_list); 87 INIT_LIST_HEAD(&nilfs->ns_list);
89 INIT_LIST_HEAD(&nilfs->ns_supers);
90 INIT_LIST_HEAD(&nilfs->ns_gc_inodes); 88 INIT_LIST_HEAD(&nilfs->ns_gc_inodes);
91 spin_lock_init(&nilfs->ns_last_segment_lock); 89 spin_lock_init(&nilfs->ns_last_segment_lock);
92 nilfs->ns_cptree = RB_ROOT; 90 nilfs->ns_cptree = RB_ROOT;
@@ -307,15 +305,6 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
307 int valid_fs = nilfs_valid_fs(nilfs); 305 int valid_fs = nilfs_valid_fs(nilfs);
308 int err; 306 int err;
309 307
310 if (nilfs_loaded(nilfs)) {
311 if (valid_fs ||
312 ((s_flags & MS_RDONLY) && nilfs_test_opt(sbi, NORECOVERY)))
313 return 0;
314 printk(KERN_ERR "NILFS: the filesystem is in an incomplete "
315 "recovery state.\n");
316 return -EINVAL;
317 }
318
319 if (!valid_fs) { 308 if (!valid_fs) {
320 printk(KERN_WARNING "NILFS warning: mounting unchecked fs\n"); 309 printk(KERN_WARNING "NILFS warning: mounting unchecked fs\n");
321 if (s_flags & MS_RDONLY) { 310 if (s_flags & MS_RDONLY) {
@@ -632,12 +621,7 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs,
632 * 621 *
633 * init_nilfs() performs common initialization per block device (e.g. 622 * init_nilfs() performs common initialization per block device (e.g.
634 * reading the super block, getting disk layout information, initializing 623 * reading the super block, getting disk layout information, initializing
635 * shared fields in the_nilfs). It takes on some portion of the jobs 624 * shared fields in the_nilfs).
636 * typically done by a fill_super() routine. This division arises from
637 * the nature that multiple NILFS instances may be simultaneously
638 * mounted on a device.
639 * For multiple mounts on the same device, only the first mount
640 * invokes these tasks.
641 * 625 *
642 * Return Value: On success, 0 is returned. On error, a negative error 626 * Return Value: On success, 0 is returned. On error, a negative error
643 * code is returned. 627 * code is returned.
@@ -651,27 +635,6 @@ int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data)
651 int err; 635 int err;
652 636
653 down_write(&nilfs->ns_sem); 637 down_write(&nilfs->ns_sem);
654 if (nilfs_init(nilfs)) {
655 /* Load values from existing the_nilfs */
656 sbp = nilfs->ns_sbp[0];
657 err = nilfs_store_magic_and_option(sb, sbp, data);
658 if (err)
659 goto out;
660
661 err = nilfs_check_feature_compatibility(sb, sbp);
662 if (err)
663 goto out;
664
665 blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
666 if (sb->s_blocksize != blocksize &&
667 !sb_set_blocksize(sb, blocksize)) {
668 printk(KERN_ERR "NILFS: blocksize %d unfit to device\n",
669 blocksize);
670 err = -EINVAL;
671 }
672 sb->s_maxbytes = nilfs_max_size(sb->s_blocksize_bits);
673 goto out;
674 }
675 638
676 blocksize = sb_min_blocksize(sb, NILFS_MIN_BLOCK_SIZE); 639 blocksize = sb_min_blocksize(sb, NILFS_MIN_BLOCK_SIZE);
677 if (!blocksize) { 640 if (!blocksize) {
@@ -901,56 +864,6 @@ void nilfs_put_root(struct nilfs_root *root)
901 } 864 }
902} 865}
903 866
904/**
905 * nilfs_find_sbinfo - find existing nilfs_sb_info structure
906 * @nilfs: nilfs object
907 * @rw_mount: mount type (non-zero value for read/write mount)
908 * @cno: checkpoint number (zero for read-only mount)
909 *
910 * nilfs_find_sbinfo() returns the nilfs_sb_info structure which
911 * @rw_mount and @cno (in case of snapshots) matched. If no instance
912 * was found, NULL is returned. Although the super block instance can
913 * be unmounted after this function returns, the nilfs_sb_info struct
914 * is kept on memory until nilfs_put_sbinfo() is called.
915 */
916struct nilfs_sb_info *nilfs_find_sbinfo(struct the_nilfs *nilfs,
917 int rw_mount, __u64 cno)
918{
919 struct nilfs_sb_info *sbi;
920
921 down_read(&nilfs->ns_super_sem);
922 /*
923 * The SNAPSHOT flag and sb->s_flags are supposed to be
924 * protected with nilfs->ns_super_sem.
925 */
926 sbi = nilfs->ns_current;
927 if (rw_mount) {
928 if (sbi && !(sbi->s_super->s_flags & MS_RDONLY))
929 goto found; /* read/write mount */
930 else
931 goto out;
932 } else if (cno == 0) {
933 if (sbi && (sbi->s_super->s_flags & MS_RDONLY))
934 goto found; /* read-only mount */
935 else
936 goto out;
937 }
938
939 list_for_each_entry(sbi, &nilfs->ns_supers, s_list) {
940 if (nilfs_test_opt(sbi, SNAPSHOT) &&
941 sbi->s_snapshot_cno == cno)
942 goto found; /* snapshot mount */
943 }
944 out:
945 up_read(&nilfs->ns_super_sem);
946 return NULL;
947
948 found:
949 atomic_inc(&sbi->s_count);
950 up_read(&nilfs->ns_super_sem);
951 return sbi;
952}
953
954int nilfs_checkpoint_is_mounted(struct the_nilfs *nilfs, __u64 cno, 867int nilfs_checkpoint_is_mounted(struct the_nilfs *nilfs, __u64 cno,
955 int snapshot_mount) 868 int snapshot_mount)
956{ 869{
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
index 0afede68a9e1..7b43693a69c5 100644
--- a/fs/nilfs2/the_nilfs.h
+++ b/fs/nilfs2/the_nilfs.h
@@ -52,16 +52,13 @@ enum {
52 * @ns_bdi: backing dev info 52 * @ns_bdi: backing dev info
53 * @ns_writer: back pointer to writable nilfs_sb_info 53 * @ns_writer: back pointer to writable nilfs_sb_info
54 * @ns_sem: semaphore for shared states 54 * @ns_sem: semaphore for shared states
55 * @ns_super_sem: semaphore for global operations across super block instances
56 * @ns_mount_mutex: mutex protecting mount process of nilfs 55 * @ns_mount_mutex: mutex protecting mount process of nilfs
57 * @ns_writer_sem: semaphore protecting ns_writer attach/detach 56 * @ns_writer_sem: semaphore protecting ns_writer attach/detach
58 * @ns_current: back pointer to current mount
59 * @ns_sbh: buffer heads of on-disk super blocks 57 * @ns_sbh: buffer heads of on-disk super blocks
60 * @ns_sbp: pointers to super block data 58 * @ns_sbp: pointers to super block data
61 * @ns_sbwtime: previous write time of super block 59 * @ns_sbwtime: previous write time of super block
62 * @ns_sbwcount: write count of super block 60 * @ns_sbwcount: write count of super block
63 * @ns_sbsize: size of valid data in super block 61 * @ns_sbsize: size of valid data in super block
64 * @ns_supers: list of nilfs super block structs
65 * @ns_seg_seq: segment sequence counter 62 * @ns_seg_seq: segment sequence counter
66 * @ns_segnum: index number of the latest full segment. 63 * @ns_segnum: index number of the latest full segment.
67 * @ns_nextnum: index number of the full segment index to be used next 64 * @ns_nextnum: index number of the full segment index to be used next
@@ -104,17 +101,10 @@ struct the_nilfs {
104 struct backing_dev_info *ns_bdi; 101 struct backing_dev_info *ns_bdi;
105 struct nilfs_sb_info *ns_writer; 102 struct nilfs_sb_info *ns_writer;
106 struct rw_semaphore ns_sem; 103 struct rw_semaphore ns_sem;
107 struct rw_semaphore ns_super_sem;
108 struct mutex ns_mount_mutex; 104 struct mutex ns_mount_mutex;
109 struct rw_semaphore ns_writer_sem; 105 struct rw_semaphore ns_writer_sem;
110 106
111 /* 107 /*
112 * components protected by ns_super_sem
113 */
114 struct nilfs_sb_info *ns_current;
115 struct list_head ns_supers;
116
117 /*
118 * used for 108 * used for
119 * - loading the latest checkpoint exclusively. 109 * - loading the latest checkpoint exclusively.
120 * - allocating a new full segment. 110 * - allocating a new full segment.
@@ -294,12 +284,6 @@ nilfs_detach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
294 up_write(&nilfs->ns_writer_sem); 284 up_write(&nilfs->ns_writer_sem);
295} 285}
296 286
297static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi)
298{
299 if (atomic_dec_and_test(&sbi->s_count))
300 kfree(sbi);
301}
302
303static inline int nilfs_valid_fs(struct the_nilfs *nilfs) 287static inline int nilfs_valid_fs(struct the_nilfs *nilfs)
304{ 288{
305 unsigned valid_fs; 289 unsigned valid_fs;