diff options
author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-08-15 12:54:52 -0400 |
---|---|---|
committer | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-10-22 20:24:36 -0400 |
commit | f11459ad7dab9e9eb5a05b8bd3bec338ea8f485d (patch) | |
tree | 91808a1f88f6ad24f381473e1bde22f10cac49e6 /fs/nilfs2/the_nilfs.c | |
parent | ab4d8f7ebf33beff97e766d18db47f1ea9635769 (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/nilfs2/the_nilfs.c')
-rw-r--r-- | fs/nilfs2/the_nilfs.c | 89 |
1 files changed, 1 insertions, 88 deletions
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 | */ | ||
916 | struct 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 | |||
954 | int nilfs_checkpoint_is_mounted(struct the_nilfs *nilfs, __u64 cno, | 867 | int nilfs_checkpoint_is_mounted(struct the_nilfs *nilfs, __u64 cno, |
955 | int snapshot_mount) | 868 | int snapshot_mount) |
956 | { | 869 | { |