diff options
author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-08-25 04:45:44 -0400 |
---|---|---|
committer | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-10-22 20:24:34 -0400 |
commit | 4d8d9293dce503eb0e083e17a02a328d397e7f00 (patch) | |
tree | ffa2dce7f100b1346131adc01cf93e280b225509 /fs/nilfs2/super.c | |
parent | ba65ae4729bf81c58d9fc847f67d57eec525b042 (diff) |
nilfs2: set pointer to root object in inodes
This puts a pointer to nilfs_root object in the private part of
on-memory inode, and makes nilfs_iget function pick up the inode with
the same root object.
Non-root inodes inherit its nilfs_root object from parent inode. That
of the root inode is allocated through nilfs_attach_checkpoint()
function.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Diffstat (limited to 'fs/nilfs2/super.c')
-rw-r--r-- | fs/nilfs2/super.c | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index f3a00a3b2a03..a1c0e38a7706 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -391,18 +391,24 @@ static int nilfs_sync_fs(struct super_block *sb, int wait) | |||
391 | return err; | 391 | return err; |
392 | } | 392 | } |
393 | 393 | ||
394 | int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno) | 394 | int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt, |
395 | struct nilfs_root **rootp) | ||
395 | { | 396 | { |
396 | struct the_nilfs *nilfs = sbi->s_nilfs; | 397 | struct the_nilfs *nilfs = sbi->s_nilfs; |
398 | struct nilfs_root *root; | ||
397 | struct nilfs_checkpoint *raw_cp; | 399 | struct nilfs_checkpoint *raw_cp; |
398 | struct buffer_head *bh_cp; | 400 | struct buffer_head *bh_cp; |
399 | int err; | 401 | int err = -ENOMEM; |
402 | |||
403 | root = nilfs_find_or_create_root( | ||
404 | nilfs, curr_mnt ? NILFS_CPTREE_CURRENT_CNO : cno); | ||
405 | if (!root) | ||
406 | return err; | ||
400 | 407 | ||
401 | down_write(&nilfs->ns_super_sem); | 408 | down_write(&nilfs->ns_super_sem); |
402 | list_add(&sbi->s_list, &nilfs->ns_supers); | 409 | list_add(&sbi->s_list, &nilfs->ns_supers); |
403 | up_write(&nilfs->ns_super_sem); | 410 | up_write(&nilfs->ns_super_sem); |
404 | 411 | ||
405 | err = -ENOMEM; | ||
406 | sbi->s_ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size); | 412 | sbi->s_ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size); |
407 | if (!sbi->s_ifile) | 413 | if (!sbi->s_ifile) |
408 | goto delist; | 414 | goto delist; |
@@ -428,6 +434,8 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno) | |||
428 | atomic_set(&sbi->s_blocks_count, le64_to_cpu(raw_cp->cp_blocks_count)); | 434 | atomic_set(&sbi->s_blocks_count, le64_to_cpu(raw_cp->cp_blocks_count)); |
429 | 435 | ||
430 | nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, cno, bh_cp); | 436 | nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, cno, bh_cp); |
437 | |||
438 | *rootp = root; | ||
431 | return 0; | 439 | return 0; |
432 | 440 | ||
433 | failed_bh: | 441 | failed_bh: |
@@ -440,6 +448,7 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno) | |||
440 | down_write(&nilfs->ns_super_sem); | 448 | down_write(&nilfs->ns_super_sem); |
441 | list_del_init(&sbi->s_list); | 449 | list_del_init(&sbi->s_list); |
442 | up_write(&nilfs->ns_super_sem); | 450 | up_write(&nilfs->ns_super_sem); |
451 | nilfs_put_root(root); | ||
443 | 452 | ||
444 | return err; | 453 | return err; |
445 | } | 454 | } |
@@ -551,12 +560,20 @@ static struct inode * | |||
551 | nilfs_nfs_get_inode(struct super_block *sb, u64 ino, u32 generation) | 560 | nilfs_nfs_get_inode(struct super_block *sb, u64 ino, u32 generation) |
552 | { | 561 | { |
553 | struct inode *inode; | 562 | struct inode *inode; |
563 | struct nilfs_root *root; | ||
554 | 564 | ||
555 | if (ino < NILFS_FIRST_INO(sb) && ino != NILFS_ROOT_INO && | 565 | if (ino < NILFS_FIRST_INO(sb) && ino != NILFS_ROOT_INO && |
556 | ino != NILFS_SKETCH_INO) | 566 | ino != NILFS_SKETCH_INO) |
557 | return ERR_PTR(-ESTALE); | 567 | return ERR_PTR(-ESTALE); |
558 | 568 | ||
559 | inode = nilfs_iget(sb, ino); | 569 | root = nilfs_lookup_root(NILFS_SB(sb)->s_nilfs, |
570 | NILFS_CPTREE_CURRENT_CNO); | ||
571 | if (!root) | ||
572 | return ERR_PTR(-ESTALE); | ||
573 | |||
574 | /* new file handle type is required to export snapshots */ | ||
575 | inode = nilfs_iget(sb, root, ino); | ||
576 | nilfs_put_root(root); | ||
560 | if (IS_ERR(inode)) | 577 | if (IS_ERR(inode)) |
561 | return ERR_CAST(inode); | 578 | return ERR_CAST(inode); |
562 | if (generation && inode->i_generation != generation) { | 579 | if (generation && inode->i_generation != generation) { |
@@ -815,9 +832,10 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
815 | struct the_nilfs *nilfs) | 832 | struct the_nilfs *nilfs) |
816 | { | 833 | { |
817 | struct nilfs_sb_info *sbi; | 834 | struct nilfs_sb_info *sbi; |
835 | struct nilfs_root *fsroot; | ||
818 | struct inode *root; | 836 | struct inode *root; |
819 | __u64 cno; | 837 | __u64 cno; |
820 | int err; | 838 | int err, curr_mnt; |
821 | 839 | ||
822 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); | 840 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); |
823 | if (!sbi) | 841 | if (!sbi) |
@@ -859,6 +877,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
859 | goto failed_sbi; | 877 | goto failed_sbi; |
860 | 878 | ||
861 | cno = nilfs_last_cno(nilfs); | 879 | cno = nilfs_last_cno(nilfs); |
880 | curr_mnt = true; | ||
862 | 881 | ||
863 | if (sb->s_flags & MS_RDONLY) { | 882 | if (sb->s_flags & MS_RDONLY) { |
864 | if (nilfs_test_opt(sbi, SNAPSHOT)) { | 883 | if (nilfs_test_opt(sbi, SNAPSHOT)) { |
@@ -881,10 +900,11 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
881 | goto failed_sbi; | 900 | goto failed_sbi; |
882 | } | 901 | } |
883 | cno = sbi->s_snapshot_cno; | 902 | cno = sbi->s_snapshot_cno; |
903 | curr_mnt = false; | ||
884 | } | 904 | } |
885 | } | 905 | } |
886 | 906 | ||
887 | err = nilfs_attach_checkpoint(sbi, cno); | 907 | err = nilfs_attach_checkpoint(sbi, cno, curr_mnt, &fsroot); |
888 | if (err) { | 908 | if (err) { |
889 | printk(KERN_ERR "NILFS: error loading a checkpoint" | 909 | printk(KERN_ERR "NILFS: error loading a checkpoint" |
890 | " (checkpoint number=%llu).\n", (unsigned long long)cno); | 910 | " (checkpoint number=%llu).\n", (unsigned long long)cno); |
@@ -897,7 +917,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
897 | goto failed_checkpoint; | 917 | goto failed_checkpoint; |
898 | } | 918 | } |
899 | 919 | ||
900 | root = nilfs_iget(sb, NILFS_ROOT_INO); | 920 | root = nilfs_iget(sb, fsroot, NILFS_ROOT_INO); |
901 | if (IS_ERR(root)) { | 921 | if (IS_ERR(root)) { |
902 | printk(KERN_ERR "NILFS: get root inode failed\n"); | 922 | printk(KERN_ERR "NILFS: get root inode failed\n"); |
903 | err = PTR_ERR(root); | 923 | err = PTR_ERR(root); |
@@ -917,6 +937,8 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
917 | goto failed_segctor; | 937 | goto failed_segctor; |
918 | } | 938 | } |
919 | 939 | ||
940 | nilfs_put_root(fsroot); | ||
941 | |||
920 | if (!(sb->s_flags & MS_RDONLY)) { | 942 | if (!(sb->s_flags & MS_RDONLY)) { |
921 | down_write(&nilfs->ns_sem); | 943 | down_write(&nilfs->ns_sem); |
922 | nilfs_setup_super(sbi); | 944 | nilfs_setup_super(sbi); |
@@ -935,6 +957,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
935 | 957 | ||
936 | failed_checkpoint: | 958 | failed_checkpoint: |
937 | nilfs_detach_checkpoint(sbi); | 959 | nilfs_detach_checkpoint(sbi); |
960 | nilfs_put_root(fsroot); | ||
938 | 961 | ||
939 | failed_sbi: | 962 | failed_sbi: |
940 | put_nilfs(nilfs); | 963 | put_nilfs(nilfs); |