Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+68 -20
+22 -5
fs/nilfs2/inode.c
··· 37 37 struct nilfs_iget_args { 38 38 u64 ino; 39 39 __u64 cno; 40 + struct nilfs_root *root; 40 41 int for_gc; 41 42 }; 42 43 ··· 285 284 struct nilfs_sb_info *sbi = NILFS_SB(sb); 286 285 struct inode *inode; 287 286 struct nilfs_inode_info *ii; 287 + struct nilfs_root *root; 288 288 int err = -ENOMEM; 289 289 ino_t ino; 290 290 ··· 296 294 mapping_set_gfp_mask(inode->i_mapping, 297 295 mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); 298 296 297 + root = NILFS_I(dir)->i_root; 299 298 ii = NILFS_I(inode); 300 299 ii->i_state = 1 << NILFS_I_NEW; 300 + ii->i_root = root; 301 301 302 302 err = nilfs_ifile_create_inode(sbi->s_ifile, &ino, &ii->i_bh); 303 303 if (unlikely(err)) ··· 488 484 struct nilfs_iget_args *args = opaque; 489 485 struct nilfs_inode_info *ii; 490 486 491 - if (args->ino != inode->i_ino) 487 + if (args->ino != inode->i_ino || args->root != NILFS_I(inode)->i_root) 492 488 return 0; 493 489 494 490 ii = NILFS_I(inode); ··· 506 502 if (args->for_gc) { 507 503 NILFS_I(inode)->i_state = 1 << NILFS_I_GCINODE; 508 504 NILFS_I(inode)->i_cno = args->cno; 505 + NILFS_I(inode)->i_root = NULL; 506 + } else { 507 + if (args->root && args->ino == NILFS_ROOT_INO) 508 + nilfs_get_root(args->root); 509 + NILFS_I(inode)->i_root = args->root; 509 510 } 510 511 return 0; 511 512 } 512 513 513 - struct inode *nilfs_iget(struct super_block *sb, unsigned long ino) 514 + struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, 515 + unsigned long ino) 514 516 { 515 - struct nilfs_iget_args args = { .ino = ino, .cno = 0, .for_gc = 0 }; 517 + struct nilfs_iget_args args = { 518 + .ino = ino, .root = root, .cno = 0, .for_gc = 0 519 + }; 516 520 struct inode *inode; 517 521 int err; 518 522 ··· 542 530 struct inode *nilfs_iget_for_gc(struct super_block *sb, unsigned long ino, 543 531 __u64 cno) 544 532 { 545 - struct nilfs_iget_args args = { .ino = ino, .cno = cno, .for_gc = 1 }; 533 + struct nilfs_iget_args args = { 534 + .ino = ino, .root = NULL, .cno = cno, .for_gc = 1 535 + }; 546 536 struct inode *inode; 547 537 int err; 548 538 ··· 696 682 nilfs_bmap_clear(ii->i_bmap); 697 683 698 684 nilfs_btnode_cache_clear(&ii->i_btnode_cache); 685 + 686 + if (ii->i_root && inode->i_ino == NILFS_ROOT_INO) 687 + nilfs_put_root(ii->i_root); 699 688 } 700 689 701 690 void nilfs_evict_inode(struct inode *inode) ··· 707 690 struct super_block *sb = inode->i_sb; 708 691 struct nilfs_inode_info *ii = NILFS_I(inode); 709 692 710 - if (inode->i_nlink || unlikely(is_bad_inode(inode))) { 693 + if (inode->i_nlink || !ii->i_root || unlikely(is_bad_inode(inode))) { 711 694 if (inode->i_data.nrpages) 712 695 truncate_inode_pages(&inode->i_data, 0); 713 696 end_writeback(inode);
+3 -2
fs/nilfs2/namei.c
··· 70 70 ino = nilfs_inode_by_name(dir, &dentry->d_name); 71 71 inode = NULL; 72 72 if (ino) { 73 - inode = nilfs_iget(dir->i_sb, ino); 73 + inode = nilfs_iget(dir->i_sb, NILFS_I(dir)->i_root, ino); 74 74 if (IS_ERR(inode)) 75 75 return ERR_CAST(inode); 76 76 } ··· 87 87 if (!ino) 88 88 return ERR_PTR(-ENOENT); 89 89 90 - inode = nilfs_iget(child->d_inode->i_sb, ino); 90 + inode = nilfs_iget(child->d_inode->i_sb, 91 + NILFS_I(child->d_inode)->i_root, ino); 91 92 if (IS_ERR(inode)) 92 93 return ERR_CAST(inode); 93 94 return d_obtain_alias(inode);
+5 -2
fs/nilfs2/nilfs.h
··· 59 59 #endif 60 60 struct buffer_head *i_bh; /* i_bh contains a new or dirty 61 61 disk inode */ 62 + struct nilfs_root *i_root; 62 63 struct inode vfs_inode; 63 64 }; 64 65 ··· 248 247 extern void nilfs_set_inode_flags(struct inode *); 249 248 extern int nilfs_read_inode_common(struct inode *, struct nilfs_inode *); 250 249 extern void nilfs_write_inode_common(struct inode *, struct nilfs_inode *, int); 251 - extern struct inode *nilfs_iget(struct super_block *, unsigned long); 250 + struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, 251 + unsigned long ino); 252 252 extern struct inode *nilfs_iget_for_gc(struct super_block *sb, 253 253 unsigned long ino, __u64 cno); 254 254 extern void nilfs_update_inode(struct inode *, struct buffer_head *); ··· 287 285 int flip); 288 286 extern int nilfs_commit_super(struct nilfs_sb_info *, int); 289 287 extern int nilfs_cleanup_super(struct nilfs_sb_info *); 290 - extern int nilfs_attach_checkpoint(struct nilfs_sb_info *, __u64); 288 + int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt, 289 + struct nilfs_root **root); 291 290 extern void nilfs_detach_checkpoint(struct nilfs_sb_info *); 292 291 293 292 /* gcinode.c */
+8 -4
fs/nilfs2/recovery.c
··· 504 504 505 505 static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs, 506 506 struct nilfs_sb_info *sbi, 507 + struct nilfs_root *root, 507 508 struct list_head *head, 508 509 unsigned long *nr_salvaged_blocks) 509 510 { ··· 516 515 int err = 0, err2 = 0; 517 516 518 517 list_for_each_entry_safe(rb, n, head, list) { 519 - inode = nilfs_iget(sbi->s_super, rb->ino); 518 + inode = nilfs_iget(sbi->s_super, root, rb->ino); 520 519 if (IS_ERR(inode)) { 521 520 err = PTR_ERR(inode); 522 521 inode = NULL; ··· 579 578 */ 580 579 static int nilfs_do_roll_forward(struct the_nilfs *nilfs, 581 580 struct nilfs_sb_info *sbi, 581 + struct nilfs_root *root, 582 582 struct nilfs_recovery_info *ri) 583 583 { 584 584 struct buffer_head *bh_sum = NULL; ··· 651 649 goto failed; 652 650 if (flags & NILFS_SS_LOGEND) { 653 651 err = nilfs_recover_dsync_blocks( 654 - nilfs, sbi, &dsync_blocks, 652 + nilfs, sbi, root, &dsync_blocks, 655 653 &nsalvaged_blocks); 656 654 if (unlikely(err)) 657 655 goto failed; ··· 748 746 struct nilfs_sb_info *sbi, 749 747 struct nilfs_recovery_info *ri) 750 748 { 749 + struct nilfs_root *root; 751 750 int err; 752 751 753 752 if (ri->ri_lsegs_start == 0 || ri->ri_lsegs_end == 0) 754 753 return 0; 755 754 756 - err = nilfs_attach_checkpoint(sbi, ri->ri_cno); 755 + err = nilfs_attach_checkpoint(sbi, ri->ri_cno, true, &root); 757 756 if (unlikely(err)) { 758 757 printk(KERN_ERR 759 758 "NILFS: error loading the latest checkpoint.\n"); 760 759 return err; 761 760 } 762 761 763 - err = nilfs_do_roll_forward(nilfs, sbi, ri); 762 + err = nilfs_do_roll_forward(nilfs, sbi, root, ri); 764 763 if (unlikely(err)) 765 764 goto failed; 766 765 ··· 792 789 793 790 failed: 794 791 nilfs_detach_checkpoint(sbi); 792 + nilfs_put_root(root); 795 793 return err; 796 794 } 797 795
+30 -7
fs/nilfs2/super.c
··· 391 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 397 struct the_nilfs *nilfs = sbi->s_nilfs; 398 + struct nilfs_root *root; 397 399 struct nilfs_checkpoint *raw_cp; 398 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 408 down_write(&nilfs->ns_super_sem); 402 409 list_add(&sbi->s_list, &nilfs->ns_supers); 403 410 up_write(&nilfs->ns_super_sem); 404 411 405 - err = -ENOMEM; 406 412 sbi->s_ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size); 407 413 if (!sbi->s_ifile) 408 414 goto delist; ··· 434 428 atomic_set(&sbi->s_blocks_count, le64_to_cpu(raw_cp->cp_blocks_count)); 435 429 436 430 nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, cno, bh_cp); 431 + 432 + *rootp = root; 437 433 return 0; 438 434 439 435 failed_bh: ··· 448 440 down_write(&nilfs->ns_super_sem); 449 441 list_del_init(&sbi->s_list); 450 442 up_write(&nilfs->ns_super_sem); 443 + nilfs_put_root(root); 451 444 452 445 return err; 453 446 } ··· 560 551 nilfs_nfs_get_inode(struct super_block *sb, u64 ino, u32 generation) 561 552 { 562 553 struct inode *inode; 554 + struct nilfs_root *root; 563 555 564 556 if (ino < NILFS_FIRST_INO(sb) && ino != NILFS_ROOT_INO && 565 557 ino != NILFS_SKETCH_INO) 566 558 return ERR_PTR(-ESTALE); 567 559 568 - inode = nilfs_iget(sb, ino); 560 + root = nilfs_lookup_root(NILFS_SB(sb)->s_nilfs, 561 + NILFS_CPTREE_CURRENT_CNO); 562 + if (!root) 563 + return ERR_PTR(-ESTALE); 564 + 565 + /* new file handle type is required to export snapshots */ 566 + inode = nilfs_iget(sb, root, ino); 567 + nilfs_put_root(root); 569 568 if (IS_ERR(inode)) 570 569 return ERR_CAST(inode); 571 570 if (generation && inode->i_generation != generation) { ··· 832 815 struct the_nilfs *nilfs) 833 816 { 834 817 struct nilfs_sb_info *sbi; 818 + struct nilfs_root *fsroot; 835 819 struct inode *root; 836 820 __u64 cno; 837 - int err; 821 + int err, curr_mnt; 838 822 839 823 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); 840 824 if (!sbi) ··· 877 859 goto failed_sbi; 878 860 879 861 cno = nilfs_last_cno(nilfs); 862 + curr_mnt = true; 880 863 881 864 if (sb->s_flags & MS_RDONLY) { 882 865 if (nilfs_test_opt(sbi, SNAPSHOT)) { ··· 900 881 goto failed_sbi; 901 882 } 902 883 cno = sbi->s_snapshot_cno; 884 + curr_mnt = false; 903 885 } 904 886 } 905 887 906 - err = nilfs_attach_checkpoint(sbi, cno); 888 + err = nilfs_attach_checkpoint(sbi, cno, curr_mnt, &fsroot); 907 889 if (err) { 908 890 printk(KERN_ERR "NILFS: error loading a checkpoint" 909 891 " (checkpoint number=%llu).\n", (unsigned long long)cno); ··· 917 897 goto failed_checkpoint; 918 898 } 919 899 920 - root = nilfs_iget(sb, NILFS_ROOT_INO); 900 + root = nilfs_iget(sb, fsroot, NILFS_ROOT_INO); 921 901 if (IS_ERR(root)) { 922 902 printk(KERN_ERR "NILFS: get root inode failed\n"); 923 903 err = PTR_ERR(root); ··· 937 917 goto failed_segctor; 938 918 } 939 919 920 + nilfs_put_root(fsroot); 921 + 940 922 if (!(sb->s_flags & MS_RDONLY)) { 941 923 down_write(&nilfs->ns_sem); 942 924 nilfs_setup_super(sbi); ··· 957 935 958 936 failed_checkpoint: 959 937 nilfs_detach_checkpoint(sbi); 938 + nilfs_put_root(fsroot); 960 939 961 940 failed_sbi: 962 941 put_nilfs(nilfs);