diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nilfs2/inode.c | 48 | ||||
-rw-r--r-- | fs/nilfs2/nilfs.h | 1 | ||||
-rw-r--r-- | fs/nilfs2/recovery.c | 3 | ||||
-rw-r--r-- | fs/nilfs2/sb.h | 3 | ||||
-rw-r--r-- | fs/nilfs2/segment.c | 43 | ||||
-rw-r--r-- | fs/nilfs2/segment.h | 7 | ||||
-rw-r--r-- | fs/nilfs2/super.c | 42 |
7 files changed, 67 insertions, 80 deletions
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 7306fc7c4962..7e883d5a5033 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
@@ -301,7 +301,7 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) | |||
301 | ii->i_state = 1 << NILFS_I_NEW; | 301 | ii->i_state = 1 << NILFS_I_NEW; |
302 | ii->i_root = root; | 302 | ii->i_root = root; |
303 | 303 | ||
304 | err = nilfs_ifile_create_inode(sbi->s_ifile, &ino, &ii->i_bh); | 304 | err = nilfs_ifile_create_inode(root->ifile, &ino, &ii->i_bh); |
305 | if (unlikely(err)) | 305 | if (unlikely(err)) |
306 | goto failed_ifile_create_inode; | 306 | goto failed_ifile_create_inode; |
307 | /* reference count of i_bh inherits from nilfs_mdt_read_block() */ | 307 | /* reference count of i_bh inherits from nilfs_mdt_read_block() */ |
@@ -358,16 +358,6 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) | |||
358 | return ERR_PTR(err); | 358 | return ERR_PTR(err); |
359 | } | 359 | } |
360 | 360 | ||
361 | void nilfs_free_inode(struct inode *inode) | ||
362 | { | ||
363 | struct super_block *sb = inode->i_sb; | ||
364 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | ||
365 | |||
366 | /* XXX: check error code? Is there any thing I can do? */ | ||
367 | (void) nilfs_ifile_delete_inode(sbi->s_ifile, inode->i_ino); | ||
368 | atomic_dec(&sbi->s_inodes_count); | ||
369 | } | ||
370 | |||
371 | void nilfs_set_inode_flags(struct inode *inode) | 361 | void nilfs_set_inode_flags(struct inode *inode) |
372 | { | 362 | { |
373 | unsigned int flags = NILFS_I(inode)->i_flags; | 363 | unsigned int flags = NILFS_I(inode)->i_flags; |
@@ -431,7 +421,8 @@ int nilfs_read_inode_common(struct inode *inode, | |||
431 | return 0; | 421 | return 0; |
432 | } | 422 | } |
433 | 423 | ||
434 | static int __nilfs_read_inode(struct super_block *sb, unsigned long ino, | 424 | static int __nilfs_read_inode(struct super_block *sb, |
425 | struct nilfs_root *root, unsigned long ino, | ||
435 | struct inode *inode) | 426 | struct inode *inode) |
436 | { | 427 | { |
437 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 428 | struct nilfs_sb_info *sbi = NILFS_SB(sb); |
@@ -441,11 +432,11 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino, | |||
441 | int err; | 432 | int err; |
442 | 433 | ||
443 | down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ | 434 | down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ |
444 | err = nilfs_ifile_get_inode_block(sbi->s_ifile, ino, &bh); | 435 | err = nilfs_ifile_get_inode_block(root->ifile, ino, &bh); |
445 | if (unlikely(err)) | 436 | if (unlikely(err)) |
446 | goto bad_inode; | 437 | goto bad_inode; |
447 | 438 | ||
448 | raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, bh); | 439 | raw_inode = nilfs_ifile_map_inode(root->ifile, ino, bh); |
449 | 440 | ||
450 | err = nilfs_read_inode_common(inode, raw_inode); | 441 | err = nilfs_read_inode_common(inode, raw_inode); |
451 | if (err) | 442 | if (err) |
@@ -468,14 +459,14 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino, | |||
468 | inode, inode->i_mode, | 459 | inode, inode->i_mode, |
469 | huge_decode_dev(le64_to_cpu(raw_inode->i_device_code))); | 460 | huge_decode_dev(le64_to_cpu(raw_inode->i_device_code))); |
470 | } | 461 | } |
471 | nilfs_ifile_unmap_inode(sbi->s_ifile, ino, bh); | 462 | nilfs_ifile_unmap_inode(root->ifile, ino, bh); |
472 | brelse(bh); | 463 | brelse(bh); |
473 | up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ | 464 | up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ |
474 | nilfs_set_inode_flags(inode); | 465 | nilfs_set_inode_flags(inode); |
475 | return 0; | 466 | return 0; |
476 | 467 | ||
477 | failed_unmap: | 468 | failed_unmap: |
478 | nilfs_ifile_unmap_inode(sbi->s_ifile, ino, bh); | 469 | nilfs_ifile_unmap_inode(root->ifile, ino, bh); |
479 | brelse(bh); | 470 | brelse(bh); |
480 | 471 | ||
481 | bad_inode: | 472 | bad_inode: |
@@ -530,7 +521,7 @@ struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, | |||
530 | if (!(inode->i_state & I_NEW)) | 521 | if (!(inode->i_state & I_NEW)) |
531 | return inode; | 522 | return inode; |
532 | 523 | ||
533 | err = __nilfs_read_inode(sb, ino, inode); | 524 | err = __nilfs_read_inode(sb, root, ino, inode); |
534 | if (unlikely(err)) { | 525 | if (unlikely(err)) { |
535 | iget_failed(inode); | 526 | iget_failed(inode); |
536 | return ERR_PTR(err); | 527 | return ERR_PTR(err); |
@@ -595,21 +586,20 @@ void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh) | |||
595 | { | 586 | { |
596 | ino_t ino = inode->i_ino; | 587 | ino_t ino = inode->i_ino; |
597 | struct nilfs_inode_info *ii = NILFS_I(inode); | 588 | struct nilfs_inode_info *ii = NILFS_I(inode); |
598 | struct super_block *sb = inode->i_sb; | 589 | struct inode *ifile = ii->i_root->ifile; |
599 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | ||
600 | struct nilfs_inode *raw_inode; | 590 | struct nilfs_inode *raw_inode; |
601 | 591 | ||
602 | raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, ibh); | 592 | raw_inode = nilfs_ifile_map_inode(ifile, ino, ibh); |
603 | 593 | ||
604 | if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state)) | 594 | if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state)) |
605 | memset(raw_inode, 0, NILFS_MDT(sbi->s_ifile)->mi_entry_size); | 595 | memset(raw_inode, 0, NILFS_MDT(ifile)->mi_entry_size); |
606 | set_bit(NILFS_I_INODE_DIRTY, &ii->i_state); | 596 | set_bit(NILFS_I_INODE_DIRTY, &ii->i_state); |
607 | 597 | ||
608 | nilfs_write_inode_common(inode, raw_inode, 0); | 598 | nilfs_write_inode_common(inode, raw_inode, 0); |
609 | /* XXX: call with has_bmap = 0 is a workaround to avoid | 599 | /* XXX: call with has_bmap = 0 is a workaround to avoid |
610 | deadlock of bmap. This delays update of i_bmap to just | 600 | deadlock of bmap. This delays update of i_bmap to just |
611 | before writing */ | 601 | before writing */ |
612 | nilfs_ifile_unmap_inode(sbi->s_ifile, ino, ibh); | 602 | nilfs_ifile_unmap_inode(ifile, ino, ibh); |
613 | } | 603 | } |
614 | 604 | ||
615 | #define NILFS_MAX_TRUNCATE_BLOCKS 16384 /* 64MB for 4KB block */ | 605 | #define NILFS_MAX_TRUNCATE_BLOCKS 16384 /* 64MB for 4KB block */ |
@@ -719,12 +709,16 @@ void nilfs_evict_inode(struct inode *inode) | |||
719 | if (inode->i_data.nrpages) | 709 | if (inode->i_data.nrpages) |
720 | truncate_inode_pages(&inode->i_data, 0); | 710 | truncate_inode_pages(&inode->i_data, 0); |
721 | 711 | ||
712 | /* TODO: some of the following operations may fail. */ | ||
722 | nilfs_truncate_bmap(ii, 0); | 713 | nilfs_truncate_bmap(ii, 0); |
723 | nilfs_mark_inode_dirty(inode); | 714 | nilfs_mark_inode_dirty(inode); |
724 | end_writeback(inode); | 715 | end_writeback(inode); |
716 | |||
717 | nilfs_ifile_delete_inode(ii->i_root->ifile, inode->i_ino); | ||
718 | atomic_dec(&NILFS_SB(sb)->s_inodes_count); | ||
719 | |||
725 | nilfs_clear_inode(inode); | 720 | nilfs_clear_inode(inode); |
726 | nilfs_free_inode(inode); | 721 | |
727 | /* nilfs_free_inode() marks inode buffer dirty */ | ||
728 | if (IS_SYNC(inode)) | 722 | if (IS_SYNC(inode)) |
729 | nilfs_set_transaction_flag(NILFS_TI_SYNC); | 723 | nilfs_set_transaction_flag(NILFS_TI_SYNC); |
730 | nilfs_transaction_commit(sb); | 724 | nilfs_transaction_commit(sb); |
@@ -779,8 +773,8 @@ int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode, | |||
779 | spin_lock(&sbi->s_inode_lock); | 773 | spin_lock(&sbi->s_inode_lock); |
780 | if (ii->i_bh == NULL) { | 774 | if (ii->i_bh == NULL) { |
781 | spin_unlock(&sbi->s_inode_lock); | 775 | spin_unlock(&sbi->s_inode_lock); |
782 | err = nilfs_ifile_get_inode_block(sbi->s_ifile, inode->i_ino, | 776 | err = nilfs_ifile_get_inode_block(ii->i_root->ifile, |
783 | pbh); | 777 | inode->i_ino, pbh); |
784 | if (unlikely(err)) | 778 | if (unlikely(err)) |
785 | return err; | 779 | return err; |
786 | spin_lock(&sbi->s_inode_lock); | 780 | spin_lock(&sbi->s_inode_lock); |
@@ -860,7 +854,7 @@ int nilfs_mark_inode_dirty(struct inode *inode) | |||
860 | } | 854 | } |
861 | nilfs_update_inode(inode, ibh); | 855 | nilfs_update_inode(inode, ibh); |
862 | nilfs_mdt_mark_buffer_dirty(ibh); | 856 | nilfs_mdt_mark_buffer_dirty(ibh); |
863 | nilfs_mdt_mark_dirty(sbi->s_ifile); | 857 | nilfs_mdt_mark_dirty(NILFS_I(inode)->i_root->ifile); |
864 | brelse(ibh); | 858 | brelse(ibh); |
865 | return 0; | 859 | return 0; |
866 | } | 860 | } |
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index aa7940f7ecf1..3870c109aba3 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h | |||
@@ -286,7 +286,6 @@ extern int nilfs_commit_super(struct nilfs_sb_info *, int); | |||
286 | extern int nilfs_cleanup_super(struct nilfs_sb_info *); | 286 | extern int nilfs_cleanup_super(struct nilfs_sb_info *); |
287 | int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt, | 287 | int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt, |
288 | struct nilfs_root **root); | 288 | struct nilfs_root **root); |
289 | extern void nilfs_detach_checkpoint(struct nilfs_sb_info *); | ||
290 | 289 | ||
291 | /* gcinode.c */ | 290 | /* gcinode.c */ |
292 | int nilfs_gccache_submit_read_data(struct inode *, sector_t, sector_t, __u64, | 291 | int nilfs_gccache_submit_read_data(struct inode *, sector_t, sector_t, __u64, |
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c index a9a5ba8f57d5..dcb5a9812c6c 100644 --- a/fs/nilfs2/recovery.c +++ b/fs/nilfs2/recovery.c | |||
@@ -773,7 +773,7 @@ int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs, | |||
773 | goto failed; | 773 | goto failed; |
774 | } | 774 | } |
775 | 775 | ||
776 | err = nilfs_attach_segment_constructor(sbi); | 776 | err = nilfs_attach_segment_constructor(sbi, root); |
777 | if (unlikely(err)) | 777 | if (unlikely(err)) |
778 | goto failed; | 778 | goto failed; |
779 | 779 | ||
@@ -791,7 +791,6 @@ int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs, | |||
791 | } | 791 | } |
792 | 792 | ||
793 | failed: | 793 | failed: |
794 | nilfs_detach_checkpoint(sbi); | ||
795 | nilfs_put_root(root); | 794 | nilfs_put_root(root); |
796 | return err; | 795 | return err; |
797 | } | 796 | } |
diff --git a/fs/nilfs2/sb.h b/fs/nilfs2/sb.h index 0776ccc2504a..50c418e6438e 100644 --- a/fs/nilfs2/sb.h +++ b/fs/nilfs2/sb.h | |||
@@ -68,9 +68,6 @@ struct nilfs_sb_info { | |||
68 | spinlock_t s_inode_lock; /* Lock for the nilfs inode. | 68 | spinlock_t s_inode_lock; /* Lock for the nilfs inode. |
69 | It covers s_dirty_files list */ | 69 | It covers s_dirty_files list */ |
70 | 70 | ||
71 | /* Metadata files */ | ||
72 | struct inode *s_ifile; /* index file inode */ | ||
73 | |||
74 | /* Inode allocator */ | 71 | /* Inode allocator */ |
75 | spinlock_t s_next_gen_lock; | 72 | spinlock_t s_next_gen_lock; |
76 | u32 s_next_generation; | 73 | u32 s_next_generation; |
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 9cf71389f369..2a6b74e6699d 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -763,12 +763,12 @@ static void nilfs_dispose_list(struct nilfs_sb_info *sbi, | |||
763 | } | 763 | } |
764 | } | 764 | } |
765 | 765 | ||
766 | static int nilfs_test_metadata_dirty(struct nilfs_sb_info *sbi) | 766 | static int nilfs_test_metadata_dirty(struct the_nilfs *nilfs, |
767 | struct nilfs_root *root) | ||
767 | { | 768 | { |
768 | struct the_nilfs *nilfs = sbi->s_nilfs; | ||
769 | int ret = 0; | 769 | int ret = 0; |
770 | 770 | ||
771 | if (nilfs_mdt_fetch_dirty(sbi->s_ifile)) | 771 | if (nilfs_mdt_fetch_dirty(root->ifile)) |
772 | ret++; | 772 | ret++; |
773 | if (nilfs_mdt_fetch_dirty(nilfs->ns_cpfile)) | 773 | if (nilfs_mdt_fetch_dirty(nilfs->ns_cpfile)) |
774 | ret++; | 774 | ret++; |
@@ -793,7 +793,7 @@ static int nilfs_segctor_confirm(struct nilfs_sc_info *sci) | |||
793 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 793 | struct nilfs_sb_info *sbi = sci->sc_sbi; |
794 | int ret = 0; | 794 | int ret = 0; |
795 | 795 | ||
796 | if (nilfs_test_metadata_dirty(sbi)) | 796 | if (nilfs_test_metadata_dirty(sbi->s_nilfs, sci->sc_root)) |
797 | set_bit(NILFS_SC_DIRTY, &sci->sc_flags); | 797 | set_bit(NILFS_SC_DIRTY, &sci->sc_flags); |
798 | 798 | ||
799 | spin_lock(&sbi->s_inode_lock); | 799 | spin_lock(&sbi->s_inode_lock); |
@@ -809,7 +809,7 @@ static void nilfs_segctor_clear_metadata_dirty(struct nilfs_sc_info *sci) | |||
809 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 809 | struct nilfs_sb_info *sbi = sci->sc_sbi; |
810 | struct the_nilfs *nilfs = sbi->s_nilfs; | 810 | struct the_nilfs *nilfs = sbi->s_nilfs; |
811 | 811 | ||
812 | nilfs_mdt_clear_dirty(sbi->s_ifile); | 812 | nilfs_mdt_clear_dirty(sci->sc_root->ifile); |
813 | nilfs_mdt_clear_dirty(nilfs->ns_cpfile); | 813 | nilfs_mdt_clear_dirty(nilfs->ns_cpfile); |
814 | nilfs_mdt_clear_dirty(nilfs->ns_sufile); | 814 | nilfs_mdt_clear_dirty(nilfs->ns_sufile); |
815 | nilfs_mdt_clear_dirty(nilfs_dat_inode(nilfs)); | 815 | nilfs_mdt_clear_dirty(nilfs_dat_inode(nilfs)); |
@@ -869,7 +869,8 @@ static int nilfs_segctor_fill_in_checkpoint(struct nilfs_sc_info *sci) | |||
869 | else | 869 | else |
870 | nilfs_checkpoint_set_minor(raw_cp); | 870 | nilfs_checkpoint_set_minor(raw_cp); |
871 | 871 | ||
872 | nilfs_write_inode_common(sbi->s_ifile, &raw_cp->cp_ifile_inode, 1); | 872 | nilfs_write_inode_common(sci->sc_root->ifile, |
873 | &raw_cp->cp_ifile_inode, 1); | ||
873 | nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, bh_cp); | 874 | nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, bh_cp); |
874 | return 0; | 875 | return 0; |
875 | 876 | ||
@@ -894,13 +895,12 @@ static void nilfs_fill_in_file_bmap(struct inode *ifile, | |||
894 | } | 895 | } |
895 | } | 896 | } |
896 | 897 | ||
897 | static void nilfs_segctor_fill_in_file_bmap(struct nilfs_sc_info *sci, | 898 | static void nilfs_segctor_fill_in_file_bmap(struct nilfs_sc_info *sci) |
898 | struct inode *ifile) | ||
899 | { | 899 | { |
900 | struct nilfs_inode_info *ii; | 900 | struct nilfs_inode_info *ii; |
901 | 901 | ||
902 | list_for_each_entry(ii, &sci->sc_dirty_files, i_dirty) { | 902 | list_for_each_entry(ii, &sci->sc_dirty_files, i_dirty) { |
903 | nilfs_fill_in_file_bmap(ifile, ii); | 903 | nilfs_fill_in_file_bmap(sci->sc_root->ifile, ii); |
904 | set_bit(NILFS_I_COLLECTED, &ii->i_state); | 904 | set_bit(NILFS_I_COLLECTED, &ii->i_state); |
905 | } | 905 | } |
906 | } | 906 | } |
@@ -1143,7 +1143,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode) | |||
1143 | sci->sc_stage.flags |= NILFS_CF_IFILE_STARTED; | 1143 | sci->sc_stage.flags |= NILFS_CF_IFILE_STARTED; |
1144 | /* Fall through */ | 1144 | /* Fall through */ |
1145 | case NILFS_ST_IFILE: | 1145 | case NILFS_ST_IFILE: |
1146 | err = nilfs_segctor_scan_file(sci, sbi->s_ifile, | 1146 | err = nilfs_segctor_scan_file(sci, sci->sc_root->ifile, |
1147 | &nilfs_sc_file_ops); | 1147 | &nilfs_sc_file_ops); |
1148 | if (unlikely(err)) | 1148 | if (unlikely(err)) |
1149 | break; | 1149 | break; |
@@ -1984,6 +1984,7 @@ static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci, | |||
1984 | struct nilfs_sb_info *sbi) | 1984 | struct nilfs_sb_info *sbi) |
1985 | { | 1985 | { |
1986 | struct nilfs_inode_info *ii, *n; | 1986 | struct nilfs_inode_info *ii, *n; |
1987 | struct inode *ifile = sci->sc_root->ifile; | ||
1987 | 1988 | ||
1988 | spin_lock(&sbi->s_inode_lock); | 1989 | spin_lock(&sbi->s_inode_lock); |
1989 | retry: | 1990 | retry: |
@@ -1994,14 +1995,14 @@ static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci, | |||
1994 | 1995 | ||
1995 | spin_unlock(&sbi->s_inode_lock); | 1996 | spin_unlock(&sbi->s_inode_lock); |
1996 | err = nilfs_ifile_get_inode_block( | 1997 | err = nilfs_ifile_get_inode_block( |
1997 | sbi->s_ifile, ii->vfs_inode.i_ino, &ibh); | 1998 | ifile, ii->vfs_inode.i_ino, &ibh); |
1998 | if (unlikely(err)) { | 1999 | if (unlikely(err)) { |
1999 | nilfs_warning(sbi->s_super, __func__, | 2000 | nilfs_warning(sbi->s_super, __func__, |
2000 | "failed to get inode block.\n"); | 2001 | "failed to get inode block.\n"); |
2001 | return err; | 2002 | return err; |
2002 | } | 2003 | } |
2003 | nilfs_mdt_mark_buffer_dirty(ibh); | 2004 | nilfs_mdt_mark_buffer_dirty(ibh); |
2004 | nilfs_mdt_mark_dirty(sbi->s_ifile); | 2005 | nilfs_mdt_mark_dirty(ifile); |
2005 | spin_lock(&sbi->s_inode_lock); | 2006 | spin_lock(&sbi->s_inode_lock); |
2006 | if (likely(!ii->i_bh)) | 2007 | if (likely(!ii->i_bh)) |
2007 | ii->i_bh = ibh; | 2008 | ii->i_bh = ibh; |
@@ -2058,7 +2059,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | |||
2058 | if (unlikely(err)) | 2059 | if (unlikely(err)) |
2059 | goto out; | 2060 | goto out; |
2060 | 2061 | ||
2061 | if (nilfs_test_metadata_dirty(sbi)) | 2062 | if (nilfs_test_metadata_dirty(nilfs, sci->sc_root)) |
2062 | set_bit(NILFS_SC_DIRTY, &sci->sc_flags); | 2063 | set_bit(NILFS_SC_DIRTY, &sci->sc_flags); |
2063 | 2064 | ||
2064 | if (nilfs_segctor_clean(sci)) | 2065 | if (nilfs_segctor_clean(sci)) |
@@ -2090,7 +2091,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | |||
2090 | goto failed; | 2091 | goto failed; |
2091 | 2092 | ||
2092 | if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED) | 2093 | if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED) |
2093 | nilfs_segctor_fill_in_file_bmap(sci, sbi->s_ifile); | 2094 | nilfs_segctor_fill_in_file_bmap(sci); |
2094 | 2095 | ||
2095 | if (mode == SC_LSEG_SR && | 2096 | if (mode == SC_LSEG_SR && |
2096 | sci->sc_stage.scnt >= NILFS_ST_CPFILE) { | 2097 | sci->sc_stage.scnt >= NILFS_ST_CPFILE) { |
@@ -2684,7 +2685,8 @@ static void nilfs_segctor_kill_thread(struct nilfs_sc_info *sci) | |||
2684 | /* | 2685 | /* |
2685 | * Setup & clean-up functions | 2686 | * Setup & clean-up functions |
2686 | */ | 2687 | */ |
2687 | static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi) | 2688 | static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi, |
2689 | struct nilfs_root *root) | ||
2688 | { | 2690 | { |
2689 | struct nilfs_sc_info *sci; | 2691 | struct nilfs_sc_info *sci; |
2690 | 2692 | ||
@@ -2695,6 +2697,9 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi) | |||
2695 | sci->sc_sbi = sbi; | 2697 | sci->sc_sbi = sbi; |
2696 | sci->sc_super = sbi->s_super; | 2698 | sci->sc_super = sbi->s_super; |
2697 | 2699 | ||
2700 | nilfs_get_root(root); | ||
2701 | sci->sc_root = root; | ||
2702 | |||
2698 | init_waitqueue_head(&sci->sc_wait_request); | 2703 | init_waitqueue_head(&sci->sc_wait_request); |
2699 | init_waitqueue_head(&sci->sc_wait_daemon); | 2704 | init_waitqueue_head(&sci->sc_wait_daemon); |
2700 | init_waitqueue_head(&sci->sc_wait_task); | 2705 | init_waitqueue_head(&sci->sc_wait_task); |
@@ -2769,6 +2774,8 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | |||
2769 | WARN_ON(!list_empty(&sci->sc_segbufs)); | 2774 | WARN_ON(!list_empty(&sci->sc_segbufs)); |
2770 | WARN_ON(!list_empty(&sci->sc_write_logs)); | 2775 | WARN_ON(!list_empty(&sci->sc_write_logs)); |
2771 | 2776 | ||
2777 | nilfs_put_root(sci->sc_root); | ||
2778 | |||
2772 | down_write(&sbi->s_nilfs->ns_segctor_sem); | 2779 | down_write(&sbi->s_nilfs->ns_segctor_sem); |
2773 | 2780 | ||
2774 | del_timer_sync(&sci->sc_timer); | 2781 | del_timer_sync(&sci->sc_timer); |
@@ -2778,6 +2785,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | |||
2778 | /** | 2785 | /** |
2779 | * nilfs_attach_segment_constructor - attach a segment constructor | 2786 | * nilfs_attach_segment_constructor - attach a segment constructor |
2780 | * @sbi: nilfs_sb_info | 2787 | * @sbi: nilfs_sb_info |
2788 | * @root: root object of the current filesystem tree | ||
2781 | * | 2789 | * |
2782 | * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info, | 2790 | * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info, |
2783 | * initializes it, and starts the segment constructor. | 2791 | * initializes it, and starts the segment constructor. |
@@ -2787,7 +2795,8 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | |||
2787 | * | 2795 | * |
2788 | * %-ENOMEM - Insufficient memory available. | 2796 | * %-ENOMEM - Insufficient memory available. |
2789 | */ | 2797 | */ |
2790 | int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi) | 2798 | int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi, |
2799 | struct nilfs_root *root) | ||
2791 | { | 2800 | { |
2792 | struct the_nilfs *nilfs = sbi->s_nilfs; | 2801 | struct the_nilfs *nilfs = sbi->s_nilfs; |
2793 | int err; | 2802 | int err; |
@@ -2801,7 +2810,7 @@ int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi) | |||
2801 | nilfs_detach_segment_constructor(sbi); | 2810 | nilfs_detach_segment_constructor(sbi); |
2802 | } | 2811 | } |
2803 | 2812 | ||
2804 | sbi->s_sc_info = nilfs_segctor_new(sbi); | 2813 | sbi->s_sc_info = nilfs_segctor_new(sbi, root); |
2805 | if (!sbi->s_sc_info) | 2814 | if (!sbi->s_sc_info) |
2806 | return -ENOMEM; | 2815 | return -ENOMEM; |
2807 | 2816 | ||
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h index 675d932148a4..cd8056e7cbed 100644 --- a/fs/nilfs2/segment.h +++ b/fs/nilfs2/segment.h | |||
@@ -29,6 +29,8 @@ | |||
29 | #include <linux/nilfs2_fs.h> | 29 | #include <linux/nilfs2_fs.h> |
30 | #include "sb.h" | 30 | #include "sb.h" |
31 | 31 | ||
32 | struct nilfs_root; | ||
33 | |||
32 | /** | 34 | /** |
33 | * struct nilfs_recovery_info - Recovery information | 35 | * struct nilfs_recovery_info - Recovery information |
34 | * @ri_need_recovery: Recovery status | 36 | * @ri_need_recovery: Recovery status |
@@ -87,6 +89,7 @@ struct nilfs_segsum_pointer { | |||
87 | * struct nilfs_sc_info - Segment constructor information | 89 | * struct nilfs_sc_info - Segment constructor information |
88 | * @sc_super: Back pointer to super_block struct | 90 | * @sc_super: Back pointer to super_block struct |
89 | * @sc_sbi: Back pointer to nilfs_sb_info struct | 91 | * @sc_sbi: Back pointer to nilfs_sb_info struct |
92 | * @sc_root: root object of the current filesystem tree | ||
90 | * @sc_nblk_inc: Block count of current generation | 93 | * @sc_nblk_inc: Block count of current generation |
91 | * @sc_dirty_files: List of files to be written | 94 | * @sc_dirty_files: List of files to be written |
92 | * @sc_gc_inodes: List of GC inodes having blocks to be written | 95 | * @sc_gc_inodes: List of GC inodes having blocks to be written |
@@ -129,6 +132,7 @@ struct nilfs_segsum_pointer { | |||
129 | struct nilfs_sc_info { | 132 | struct nilfs_sc_info { |
130 | struct super_block *sc_super; | 133 | struct super_block *sc_super; |
131 | struct nilfs_sb_info *sc_sbi; | 134 | struct nilfs_sb_info *sc_sbi; |
135 | struct nilfs_root *sc_root; | ||
132 | 136 | ||
133 | unsigned long sc_nblk_inc; | 137 | unsigned long sc_nblk_inc; |
134 | 138 | ||
@@ -231,7 +235,8 @@ extern void nilfs_flush_segment(struct super_block *, ino_t); | |||
231 | extern int nilfs_clean_segments(struct super_block *, struct nilfs_argv *, | 235 | extern int nilfs_clean_segments(struct super_block *, struct nilfs_argv *, |
232 | void **); | 236 | void **); |
233 | 237 | ||
234 | extern int nilfs_attach_segment_constructor(struct nilfs_sb_info *); | 238 | int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi, |
239 | struct nilfs_root *root); | ||
235 | extern void nilfs_detach_segment_constructor(struct nilfs_sb_info *); | 240 | extern void nilfs_detach_segment_constructor(struct nilfs_sb_info *); |
236 | 241 | ||
237 | /* recovery.c */ | 242 | /* recovery.c */ |
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index adbf5826b837..87c57810ae88 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -358,9 +358,9 @@ static void nilfs_put_super(struct super_block *sb) | |||
358 | down_write(&nilfs->ns_super_sem); | 358 | down_write(&nilfs->ns_super_sem); |
359 | if (nilfs->ns_current == sbi) | 359 | if (nilfs->ns_current == sbi) |
360 | nilfs->ns_current = NULL; | 360 | nilfs->ns_current = NULL; |
361 | list_del_init(&sbi->s_list); | ||
361 | up_write(&nilfs->ns_super_sem); | 362 | up_write(&nilfs->ns_super_sem); |
362 | 363 | ||
363 | nilfs_detach_checkpoint(sbi); | ||
364 | put_nilfs(sbi->s_nilfs); | 364 | put_nilfs(sbi->s_nilfs); |
365 | sbi->s_super = NULL; | 365 | sbi->s_super = NULL; |
366 | sb->s_fs_info = NULL; | 366 | sb->s_fs_info = NULL; |
@@ -405,13 +405,12 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt, | |||
405 | if (!root) | 405 | if (!root) |
406 | return err; | 406 | return err; |
407 | 407 | ||
408 | down_write(&nilfs->ns_super_sem); | 408 | if (root->ifile) |
409 | list_add(&sbi->s_list, &nilfs->ns_supers); | 409 | goto reuse; /* already attached checkpoint */ |
410 | up_write(&nilfs->ns_super_sem); | ||
411 | 410 | ||
412 | sbi->s_ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size); | 411 | root->ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size); |
413 | if (!sbi->s_ifile) | 412 | if (!root->ifile) |
414 | goto delist; | 413 | goto failed; |
415 | 414 | ||
416 | down_read(&nilfs->ns_segctor_sem); | 415 | down_read(&nilfs->ns_segctor_sem); |
417 | err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp, | 416 | err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp, |
@@ -427,7 +426,7 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt, | |||
427 | } | 426 | } |
428 | goto failed; | 427 | goto failed; |
429 | } | 428 | } |
430 | err = nilfs_read_inode_common(sbi->s_ifile, &raw_cp->cp_ifile_inode); | 429 | err = nilfs_read_inode_common(root->ifile, &raw_cp->cp_ifile_inode); |
431 | if (unlikely(err)) | 430 | if (unlikely(err)) |
432 | goto failed_bh; | 431 | goto failed_bh; |
433 | atomic_set(&sbi->s_inodes_count, le64_to_cpu(raw_cp->cp_inodes_count)); | 432 | atomic_set(&sbi->s_inodes_count, le64_to_cpu(raw_cp->cp_inodes_count)); |
@@ -435,35 +434,18 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt, | |||
435 | 434 | ||
436 | nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, cno, bh_cp); | 435 | nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, cno, bh_cp); |
437 | 436 | ||
437 | reuse: | ||
438 | *rootp = root; | 438 | *rootp = root; |
439 | return 0; | 439 | return 0; |
440 | 440 | ||
441 | failed_bh: | 441 | failed_bh: |
442 | nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, cno, bh_cp); | 442 | nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, cno, bh_cp); |
443 | failed: | 443 | failed: |
444 | nilfs_mdt_destroy(sbi->s_ifile); | ||
445 | sbi->s_ifile = NULL; | ||
446 | |||
447 | delist: | ||
448 | down_write(&nilfs->ns_super_sem); | ||
449 | list_del_init(&sbi->s_list); | ||
450 | up_write(&nilfs->ns_super_sem); | ||
451 | nilfs_put_root(root); | 444 | nilfs_put_root(root); |
452 | 445 | ||
453 | return err; | 446 | return err; |
454 | } | 447 | } |
455 | 448 | ||
456 | void nilfs_detach_checkpoint(struct nilfs_sb_info *sbi) | ||
457 | { | ||
458 | struct the_nilfs *nilfs = sbi->s_nilfs; | ||
459 | |||
460 | nilfs_mdt_destroy(sbi->s_ifile); | ||
461 | sbi->s_ifile = NULL; | ||
462 | down_write(&nilfs->ns_super_sem); | ||
463 | list_del_init(&sbi->s_list); | ||
464 | up_write(&nilfs->ns_super_sem); | ||
465 | } | ||
466 | |||
467 | static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 449 | static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
468 | { | 450 | { |
469 | struct super_block *sb = dentry->d_sb; | 451 | struct super_block *sb = dentry->d_sb; |
@@ -862,7 +844,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
862 | } | 844 | } |
863 | 845 | ||
864 | if (!(sb->s_flags & MS_RDONLY)) { | 846 | if (!(sb->s_flags & MS_RDONLY)) { |
865 | err = nilfs_attach_segment_constructor(sbi); | 847 | err = nilfs_attach_segment_constructor(sbi, fsroot); |
866 | if (err) | 848 | if (err) |
867 | goto failed_checkpoint; | 849 | goto failed_checkpoint; |
868 | } | 850 | } |
@@ -896,6 +878,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
896 | } | 878 | } |
897 | 879 | ||
898 | down_write(&nilfs->ns_super_sem); | 880 | down_write(&nilfs->ns_super_sem); |
881 | list_add(&sbi->s_list, &nilfs->ns_supers); | ||
899 | if (!nilfs_test_opt(sbi, SNAPSHOT)) | 882 | if (!nilfs_test_opt(sbi, SNAPSHOT)) |
900 | nilfs->ns_current = sbi; | 883 | nilfs->ns_current = sbi; |
901 | up_write(&nilfs->ns_super_sem); | 884 | up_write(&nilfs->ns_super_sem); |
@@ -906,7 +889,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, | |||
906 | nilfs_detach_segment_constructor(sbi); | 889 | nilfs_detach_segment_constructor(sbi); |
907 | 890 | ||
908 | failed_checkpoint: | 891 | failed_checkpoint: |
909 | nilfs_detach_checkpoint(sbi); | ||
910 | nilfs_put_root(fsroot); | 892 | nilfs_put_root(fsroot); |
911 | 893 | ||
912 | failed_sbi: | 894 | failed_sbi: |
@@ -966,6 +948,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
966 | up_write(&nilfs->ns_sem); | 948 | up_write(&nilfs->ns_sem); |
967 | } else { | 949 | } else { |
968 | __u64 features; | 950 | __u64 features; |
951 | struct nilfs_root *root; | ||
969 | 952 | ||
970 | /* | 953 | /* |
971 | * Mounting a RDONLY partition read-write, so reread and | 954 | * Mounting a RDONLY partition read-write, so reread and |
@@ -987,7 +970,8 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) | |||
987 | 970 | ||
988 | sb->s_flags &= ~MS_RDONLY; | 971 | sb->s_flags &= ~MS_RDONLY; |
989 | 972 | ||
990 | err = nilfs_attach_segment_constructor(sbi); | 973 | root = NILFS_I(sb->s_root->d_inode)->i_root; |
974 | err = nilfs_attach_segment_constructor(sbi, root); | ||
991 | if (err) | 975 | if (err) |
992 | goto restore_opts; | 976 | goto restore_opts; |
993 | 977 | ||