diff options
Diffstat (limited to 'fs/nilfs2/segment.c')
-rw-r--r-- | fs/nilfs2/segment.c | 102 |
1 files changed, 55 insertions, 47 deletions
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 9fd051a33c4..d926af62617 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -191,6 +191,8 @@ int nilfs_transaction_begin(struct super_block *sb, | |||
191 | if (ret > 0) | 191 | if (ret > 0) |
192 | return 0; | 192 | return 0; |
193 | 193 | ||
194 | vfs_check_frozen(sb, SB_FREEZE_WRITE); | ||
195 | |||
194 | sbi = NILFS_SB(sb); | 196 | sbi = NILFS_SB(sb); |
195 | nilfs = sbi->s_nilfs; | 197 | nilfs = sbi->s_nilfs; |
196 | down_read(&nilfs->ns_segctor_sem); | 198 | down_read(&nilfs->ns_segctor_sem); |
@@ -366,8 +368,7 @@ static int nilfs_segctor_reset_segment_buffer(struct nilfs_sc_info *sci) | |||
366 | 368 | ||
367 | if (nilfs_doing_gc()) | 369 | if (nilfs_doing_gc()) |
368 | flags = NILFS_SS_GC; | 370 | flags = NILFS_SS_GC; |
369 | err = nilfs_segbuf_reset(segbuf, flags, sci->sc_seg_ctime, | 371 | err = nilfs_segbuf_reset(segbuf, flags, sci->sc_seg_ctime, sci->sc_cno); |
370 | sci->sc_sbi->s_nilfs->ns_cno); | ||
371 | if (unlikely(err)) | 372 | if (unlikely(err)) |
372 | return err; | 373 | return err; |
373 | 374 | ||
@@ -440,17 +441,26 @@ static void nilfs_segctor_end_finfo(struct nilfs_sc_info *sci, | |||
440 | struct nilfs_finfo *finfo; | 441 | struct nilfs_finfo *finfo; |
441 | struct nilfs_inode_info *ii; | 442 | struct nilfs_inode_info *ii; |
442 | struct nilfs_segment_buffer *segbuf; | 443 | struct nilfs_segment_buffer *segbuf; |
444 | __u64 cno; | ||
443 | 445 | ||
444 | if (sci->sc_blk_cnt == 0) | 446 | if (sci->sc_blk_cnt == 0) |
445 | return; | 447 | return; |
446 | 448 | ||
447 | ii = NILFS_I(inode); | 449 | ii = NILFS_I(inode); |
450 | |||
451 | if (test_bit(NILFS_I_GCINODE, &ii->i_state)) | ||
452 | cno = ii->i_cno; | ||
453 | else if (NILFS_ROOT_METADATA_FILE(inode->i_ino)) | ||
454 | cno = 0; | ||
455 | else | ||
456 | cno = sci->sc_cno; | ||
457 | |||
448 | finfo = nilfs_segctor_map_segsum_entry(sci, &sci->sc_finfo_ptr, | 458 | finfo = nilfs_segctor_map_segsum_entry(sci, &sci->sc_finfo_ptr, |
449 | sizeof(*finfo)); | 459 | sizeof(*finfo)); |
450 | finfo->fi_ino = cpu_to_le64(inode->i_ino); | 460 | finfo->fi_ino = cpu_to_le64(inode->i_ino); |
451 | finfo->fi_nblocks = cpu_to_le32(sci->sc_blk_cnt); | 461 | finfo->fi_nblocks = cpu_to_le32(sci->sc_blk_cnt); |
452 | finfo->fi_ndatablk = cpu_to_le32(sci->sc_datablk_cnt); | 462 | finfo->fi_ndatablk = cpu_to_le32(sci->sc_datablk_cnt); |
453 | finfo->fi_cno = cpu_to_le64(ii->i_cno); | 463 | finfo->fi_cno = cpu_to_le64(cno); |
454 | 464 | ||
455 | segbuf = sci->sc_curseg; | 465 | segbuf = sci->sc_curseg; |
456 | segbuf->sb_sum.sumbytes = sci->sc_binfo_ptr.offset + | 466 | segbuf->sb_sum.sumbytes = sci->sc_binfo_ptr.offset + |
@@ -755,12 +765,12 @@ static void nilfs_dispose_list(struct nilfs_sb_info *sbi, | |||
755 | } | 765 | } |
756 | } | 766 | } |
757 | 767 | ||
758 | static int nilfs_test_metadata_dirty(struct nilfs_sb_info *sbi) | 768 | static int nilfs_test_metadata_dirty(struct the_nilfs *nilfs, |
769 | struct nilfs_root *root) | ||
759 | { | 770 | { |
760 | struct the_nilfs *nilfs = sbi->s_nilfs; | ||
761 | int ret = 0; | 771 | int ret = 0; |
762 | 772 | ||
763 | if (nilfs_mdt_fetch_dirty(sbi->s_ifile)) | 773 | if (nilfs_mdt_fetch_dirty(root->ifile)) |
764 | ret++; | 774 | ret++; |
765 | if (nilfs_mdt_fetch_dirty(nilfs->ns_cpfile)) | 775 | if (nilfs_mdt_fetch_dirty(nilfs->ns_cpfile)) |
766 | ret++; | 776 | ret++; |
@@ -785,7 +795,7 @@ static int nilfs_segctor_confirm(struct nilfs_sc_info *sci) | |||
785 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 795 | struct nilfs_sb_info *sbi = sci->sc_sbi; |
786 | int ret = 0; | 796 | int ret = 0; |
787 | 797 | ||
788 | if (nilfs_test_metadata_dirty(sbi)) | 798 | if (nilfs_test_metadata_dirty(sbi->s_nilfs, sci->sc_root)) |
789 | set_bit(NILFS_SC_DIRTY, &sci->sc_flags); | 799 | set_bit(NILFS_SC_DIRTY, &sci->sc_flags); |
790 | 800 | ||
791 | spin_lock(&sbi->s_inode_lock); | 801 | spin_lock(&sbi->s_inode_lock); |
@@ -801,7 +811,7 @@ static void nilfs_segctor_clear_metadata_dirty(struct nilfs_sc_info *sci) | |||
801 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 811 | struct nilfs_sb_info *sbi = sci->sc_sbi; |
802 | struct the_nilfs *nilfs = sbi->s_nilfs; | 812 | struct the_nilfs *nilfs = sbi->s_nilfs; |
803 | 813 | ||
804 | nilfs_mdt_clear_dirty(sbi->s_ifile); | 814 | nilfs_mdt_clear_dirty(sci->sc_root->ifile); |
805 | nilfs_mdt_clear_dirty(nilfs->ns_cpfile); | 815 | nilfs_mdt_clear_dirty(nilfs->ns_cpfile); |
806 | nilfs_mdt_clear_dirty(nilfs->ns_sufile); | 816 | nilfs_mdt_clear_dirty(nilfs->ns_sufile); |
807 | nilfs_mdt_clear_dirty(nilfs_dat_inode(nilfs)); | 817 | nilfs_mdt_clear_dirty(nilfs_dat_inode(nilfs)); |
@@ -848,9 +858,9 @@ static int nilfs_segctor_fill_in_checkpoint(struct nilfs_sc_info *sci) | |||
848 | raw_cp->cp_snapshot_list.ssl_next = 0; | 858 | raw_cp->cp_snapshot_list.ssl_next = 0; |
849 | raw_cp->cp_snapshot_list.ssl_prev = 0; | 859 | raw_cp->cp_snapshot_list.ssl_prev = 0; |
850 | raw_cp->cp_inodes_count = | 860 | raw_cp->cp_inodes_count = |
851 | cpu_to_le64(atomic_read(&sbi->s_inodes_count)); | 861 | cpu_to_le64(atomic_read(&sci->sc_root->inodes_count)); |
852 | raw_cp->cp_blocks_count = | 862 | raw_cp->cp_blocks_count = |
853 | cpu_to_le64(atomic_read(&sbi->s_blocks_count)); | 863 | cpu_to_le64(atomic_read(&sci->sc_root->blocks_count)); |
854 | raw_cp->cp_nblk_inc = | 864 | raw_cp->cp_nblk_inc = |
855 | cpu_to_le64(sci->sc_nblk_inc + sci->sc_nblk_this_inc); | 865 | cpu_to_le64(sci->sc_nblk_inc + sci->sc_nblk_this_inc); |
856 | raw_cp->cp_create = cpu_to_le64(sci->sc_seg_ctime); | 866 | raw_cp->cp_create = cpu_to_le64(sci->sc_seg_ctime); |
@@ -861,7 +871,8 @@ static int nilfs_segctor_fill_in_checkpoint(struct nilfs_sc_info *sci) | |||
861 | else | 871 | else |
862 | nilfs_checkpoint_set_minor(raw_cp); | 872 | nilfs_checkpoint_set_minor(raw_cp); |
863 | 873 | ||
864 | nilfs_write_inode_common(sbi->s_ifile, &raw_cp->cp_ifile_inode, 1); | 874 | nilfs_write_inode_common(sci->sc_root->ifile, |
875 | &raw_cp->cp_ifile_inode, 1); | ||
865 | nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, bh_cp); | 876 | nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, bh_cp); |
866 | return 0; | 877 | return 0; |
867 | 878 | ||
@@ -886,13 +897,12 @@ static void nilfs_fill_in_file_bmap(struct inode *ifile, | |||
886 | } | 897 | } |
887 | } | 898 | } |
888 | 899 | ||
889 | static void nilfs_segctor_fill_in_file_bmap(struct nilfs_sc_info *sci, | 900 | static void nilfs_segctor_fill_in_file_bmap(struct nilfs_sc_info *sci) |
890 | struct inode *ifile) | ||
891 | { | 901 | { |
892 | struct nilfs_inode_info *ii; | 902 | struct nilfs_inode_info *ii; |
893 | 903 | ||
894 | list_for_each_entry(ii, &sci->sc_dirty_files, i_dirty) { | 904 | list_for_each_entry(ii, &sci->sc_dirty_files, i_dirty) { |
895 | nilfs_fill_in_file_bmap(ifile, ii); | 905 | nilfs_fill_in_file_bmap(sci->sc_root->ifile, ii); |
896 | set_bit(NILFS_I_COLLECTED, &ii->i_state); | 906 | set_bit(NILFS_I_COLLECTED, &ii->i_state); |
897 | } | 907 | } |
898 | } | 908 | } |
@@ -1135,7 +1145,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode) | |||
1135 | sci->sc_stage.flags |= NILFS_CF_IFILE_STARTED; | 1145 | sci->sc_stage.flags |= NILFS_CF_IFILE_STARTED; |
1136 | /* Fall through */ | 1146 | /* Fall through */ |
1137 | case NILFS_ST_IFILE: | 1147 | case NILFS_ST_IFILE: |
1138 | err = nilfs_segctor_scan_file(sci, sbi->s_ifile, | 1148 | err = nilfs_segctor_scan_file(sci, sci->sc_root->ifile, |
1139 | &nilfs_sc_file_ops); | 1149 | &nilfs_sc_file_ops); |
1140 | if (unlikely(err)) | 1150 | if (unlikely(err)) |
1141 | break; | 1151 | break; |
@@ -1900,6 +1910,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) | |||
1900 | set_buffer_uptodate(bh); | 1910 | set_buffer_uptodate(bh); |
1901 | clear_buffer_dirty(bh); | 1911 | clear_buffer_dirty(bh); |
1902 | clear_buffer_nilfs_volatile(bh); | 1912 | clear_buffer_nilfs_volatile(bh); |
1913 | clear_buffer_nilfs_redirected(bh); | ||
1903 | if (bh == segbuf->sb_super_root) { | 1914 | if (bh == segbuf->sb_super_root) { |
1904 | if (bh->b_page != bd_page) { | 1915 | if (bh->b_page != bd_page) { |
1905 | end_page_writeback(bd_page); | 1916 | end_page_writeback(bd_page); |
@@ -1936,11 +1947,9 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) | |||
1936 | 1947 | ||
1937 | nilfs_drop_collected_inodes(&sci->sc_dirty_files); | 1948 | nilfs_drop_collected_inodes(&sci->sc_dirty_files); |
1938 | 1949 | ||
1939 | if (nilfs_doing_gc()) { | 1950 | if (nilfs_doing_gc()) |
1940 | nilfs_drop_collected_inodes(&sci->sc_gc_inodes); | 1951 | nilfs_drop_collected_inodes(&sci->sc_gc_inodes); |
1941 | if (update_sr) | 1952 | else |
1942 | nilfs_commit_gcdat_inode(nilfs); | ||
1943 | } else | ||
1944 | nilfs->ns_nongc_ctime = sci->sc_seg_ctime; | 1953 | nilfs->ns_nongc_ctime = sci->sc_seg_ctime; |
1945 | 1954 | ||
1946 | sci->sc_nblk_inc += sci->sc_nblk_this_inc; | 1955 | sci->sc_nblk_inc += sci->sc_nblk_this_inc; |
@@ -1976,7 +1985,7 @@ static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci, | |||
1976 | struct nilfs_sb_info *sbi) | 1985 | struct nilfs_sb_info *sbi) |
1977 | { | 1986 | { |
1978 | struct nilfs_inode_info *ii, *n; | 1987 | struct nilfs_inode_info *ii, *n; |
1979 | __u64 cno = sbi->s_nilfs->ns_cno; | 1988 | struct inode *ifile = sci->sc_root->ifile; |
1980 | 1989 | ||
1981 | spin_lock(&sbi->s_inode_lock); | 1990 | spin_lock(&sbi->s_inode_lock); |
1982 | retry: | 1991 | retry: |
@@ -1987,14 +1996,14 @@ static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci, | |||
1987 | 1996 | ||
1988 | spin_unlock(&sbi->s_inode_lock); | 1997 | spin_unlock(&sbi->s_inode_lock); |
1989 | err = nilfs_ifile_get_inode_block( | 1998 | err = nilfs_ifile_get_inode_block( |
1990 | sbi->s_ifile, ii->vfs_inode.i_ino, &ibh); | 1999 | ifile, ii->vfs_inode.i_ino, &ibh); |
1991 | if (unlikely(err)) { | 2000 | if (unlikely(err)) { |
1992 | nilfs_warning(sbi->s_super, __func__, | 2001 | nilfs_warning(sbi->s_super, __func__, |
1993 | "failed to get inode block.\n"); | 2002 | "failed to get inode block.\n"); |
1994 | return err; | 2003 | return err; |
1995 | } | 2004 | } |
1996 | nilfs_mdt_mark_buffer_dirty(ibh); | 2005 | nilfs_mdt_mark_buffer_dirty(ibh); |
1997 | nilfs_mdt_mark_dirty(sbi->s_ifile); | 2006 | nilfs_mdt_mark_dirty(ifile); |
1998 | spin_lock(&sbi->s_inode_lock); | 2007 | spin_lock(&sbi->s_inode_lock); |
1999 | if (likely(!ii->i_bh)) | 2008 | if (likely(!ii->i_bh)) |
2000 | ii->i_bh = ibh; | 2009 | ii->i_bh = ibh; |
@@ -2002,7 +2011,6 @@ static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci, | |||
2002 | brelse(ibh); | 2011 | brelse(ibh); |
2003 | goto retry; | 2012 | goto retry; |
2004 | } | 2013 | } |
2005 | ii->i_cno = cno; | ||
2006 | 2014 | ||
2007 | clear_bit(NILFS_I_QUEUED, &ii->i_state); | 2015 | clear_bit(NILFS_I_QUEUED, &ii->i_state); |
2008 | set_bit(NILFS_I_BUSY, &ii->i_state); | 2016 | set_bit(NILFS_I_BUSY, &ii->i_state); |
@@ -2011,8 +2019,6 @@ static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci, | |||
2011 | } | 2019 | } |
2012 | spin_unlock(&sbi->s_inode_lock); | 2020 | spin_unlock(&sbi->s_inode_lock); |
2013 | 2021 | ||
2014 | NILFS_I(sbi->s_ifile)->i_cno = cno; | ||
2015 | |||
2016 | return 0; | 2022 | return 0; |
2017 | } | 2023 | } |
2018 | 2024 | ||
@@ -2021,19 +2027,13 @@ static void nilfs_segctor_check_out_files(struct nilfs_sc_info *sci, | |||
2021 | { | 2027 | { |
2022 | struct nilfs_transaction_info *ti = current->journal_info; | 2028 | struct nilfs_transaction_info *ti = current->journal_info; |
2023 | struct nilfs_inode_info *ii, *n; | 2029 | struct nilfs_inode_info *ii, *n; |
2024 | __u64 cno = sbi->s_nilfs->ns_cno; | ||
2025 | 2030 | ||
2026 | spin_lock(&sbi->s_inode_lock); | 2031 | spin_lock(&sbi->s_inode_lock); |
2027 | list_for_each_entry_safe(ii, n, &sci->sc_dirty_files, i_dirty) { | 2032 | list_for_each_entry_safe(ii, n, &sci->sc_dirty_files, i_dirty) { |
2028 | if (!test_and_clear_bit(NILFS_I_UPDATED, &ii->i_state) || | 2033 | if (!test_and_clear_bit(NILFS_I_UPDATED, &ii->i_state) || |
2029 | test_bit(NILFS_I_DIRTY, &ii->i_state)) { | 2034 | test_bit(NILFS_I_DIRTY, &ii->i_state)) |
2030 | /* The current checkpoint number (=nilfs->ns_cno) is | ||
2031 | changed between check-in and check-out only if the | ||
2032 | super root is written out. So, we can update i_cno | ||
2033 | for the inodes that remain in the dirty list. */ | ||
2034 | ii->i_cno = cno; | ||
2035 | continue; | 2035 | continue; |
2036 | } | 2036 | |
2037 | clear_bit(NILFS_I_BUSY, &ii->i_state); | 2037 | clear_bit(NILFS_I_BUSY, &ii->i_state); |
2038 | brelse(ii->i_bh); | 2038 | brelse(ii->i_bh); |
2039 | ii->i_bh = NULL; | 2039 | ii->i_bh = NULL; |
@@ -2054,12 +2054,13 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | |||
2054 | int err; | 2054 | int err; |
2055 | 2055 | ||
2056 | sci->sc_stage.scnt = NILFS_ST_INIT; | 2056 | sci->sc_stage.scnt = NILFS_ST_INIT; |
2057 | sci->sc_cno = nilfs->ns_cno; | ||
2057 | 2058 | ||
2058 | err = nilfs_segctor_check_in_files(sci, sbi); | 2059 | err = nilfs_segctor_check_in_files(sci, sbi); |
2059 | if (unlikely(err)) | 2060 | if (unlikely(err)) |
2060 | goto out; | 2061 | goto out; |
2061 | 2062 | ||
2062 | if (nilfs_test_metadata_dirty(sbi)) | 2063 | if (nilfs_test_metadata_dirty(nilfs, sci->sc_root)) |
2063 | set_bit(NILFS_SC_DIRTY, &sci->sc_flags); | 2064 | set_bit(NILFS_SC_DIRTY, &sci->sc_flags); |
2064 | 2065 | ||
2065 | if (nilfs_segctor_clean(sci)) | 2066 | if (nilfs_segctor_clean(sci)) |
@@ -2091,7 +2092,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | |||
2091 | goto failed; | 2092 | goto failed; |
2092 | 2093 | ||
2093 | if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED) | 2094 | if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED) |
2094 | nilfs_segctor_fill_in_file_bmap(sci, sbi->s_ifile); | 2095 | nilfs_segctor_fill_in_file_bmap(sci); |
2095 | 2096 | ||
2096 | if (mode == SC_LSEG_SR && | 2097 | if (mode == SC_LSEG_SR && |
2097 | sci->sc_stage.scnt >= NILFS_ST_CPFILE) { | 2098 | sci->sc_stage.scnt >= NILFS_ST_CPFILE) { |
@@ -2452,9 +2453,8 @@ nilfs_remove_written_gcinodes(struct the_nilfs *nilfs, struct list_head *head) | |||
2452 | list_for_each_entry_safe(ii, n, head, i_dirty) { | 2453 | list_for_each_entry_safe(ii, n, head, i_dirty) { |
2453 | if (!test_bit(NILFS_I_UPDATED, &ii->i_state)) | 2454 | if (!test_bit(NILFS_I_UPDATED, &ii->i_state)) |
2454 | continue; | 2455 | continue; |
2455 | hlist_del_init(&ii->vfs_inode.i_hash); | ||
2456 | list_del_init(&ii->i_dirty); | 2456 | list_del_init(&ii->i_dirty); |
2457 | nilfs_clear_gcinode(&ii->vfs_inode); | 2457 | iput(&ii->vfs_inode); |
2458 | } | 2458 | } |
2459 | } | 2459 | } |
2460 | 2460 | ||
@@ -2472,13 +2472,15 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv, | |||
2472 | 2472 | ||
2473 | nilfs_transaction_lock(sbi, &ti, 1); | 2473 | nilfs_transaction_lock(sbi, &ti, 1); |
2474 | 2474 | ||
2475 | err = nilfs_init_gcdat_inode(nilfs); | 2475 | err = nilfs_mdt_save_to_shadow_map(nilfs->ns_dat); |
2476 | if (unlikely(err)) | 2476 | if (unlikely(err)) |
2477 | goto out_unlock; | 2477 | goto out_unlock; |
2478 | 2478 | ||
2479 | err = nilfs_ioctl_prepare_clean_segments(nilfs, argv, kbufs); | 2479 | err = nilfs_ioctl_prepare_clean_segments(nilfs, argv, kbufs); |
2480 | if (unlikely(err)) | 2480 | if (unlikely(err)) { |
2481 | nilfs_mdt_restore_from_shadow_map(nilfs->ns_dat); | ||
2481 | goto out_unlock; | 2482 | goto out_unlock; |
2483 | } | ||
2482 | 2484 | ||
2483 | sci->sc_freesegs = kbufs[4]; | 2485 | sci->sc_freesegs = kbufs[4]; |
2484 | sci->sc_nfreesegs = argv[4].v_nmembs; | 2486 | sci->sc_nfreesegs = argv[4].v_nmembs; |
@@ -2510,7 +2512,7 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv, | |||
2510 | out_unlock: | 2512 | out_unlock: |
2511 | sci->sc_freesegs = NULL; | 2513 | sci->sc_freesegs = NULL; |
2512 | sci->sc_nfreesegs = 0; | 2514 | sci->sc_nfreesegs = 0; |
2513 | nilfs_clear_gcdat_inode(nilfs); | 2515 | nilfs_mdt_clear_shadow_map(nilfs->ns_dat); |
2514 | nilfs_transaction_unlock(sbi); | 2516 | nilfs_transaction_unlock(sbi); |
2515 | return err; | 2517 | return err; |
2516 | } | 2518 | } |
@@ -2672,6 +2674,8 @@ static int nilfs_segctor_start_thread(struct nilfs_sc_info *sci) | |||
2672 | } | 2674 | } |
2673 | 2675 | ||
2674 | static void nilfs_segctor_kill_thread(struct nilfs_sc_info *sci) | 2676 | static void nilfs_segctor_kill_thread(struct nilfs_sc_info *sci) |
2677 | __acquires(&sci->sc_state_lock) | ||
2678 | __releases(&sci->sc_state_lock) | ||
2675 | { | 2679 | { |
2676 | sci->sc_state |= NILFS_SEGCTOR_QUIT; | 2680 | sci->sc_state |= NILFS_SEGCTOR_QUIT; |
2677 | 2681 | ||
@@ -2686,7 +2690,8 @@ static void nilfs_segctor_kill_thread(struct nilfs_sc_info *sci) | |||
2686 | /* | 2690 | /* |
2687 | * Setup & clean-up functions | 2691 | * Setup & clean-up functions |
2688 | */ | 2692 | */ |
2689 | static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi) | 2693 | static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi, |
2694 | struct nilfs_root *root) | ||
2690 | { | 2695 | { |
2691 | struct nilfs_sc_info *sci; | 2696 | struct nilfs_sc_info *sci; |
2692 | 2697 | ||
@@ -2697,6 +2702,9 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi) | |||
2697 | sci->sc_sbi = sbi; | 2702 | sci->sc_sbi = sbi; |
2698 | sci->sc_super = sbi->s_super; | 2703 | sci->sc_super = sbi->s_super; |
2699 | 2704 | ||
2705 | nilfs_get_root(root); | ||
2706 | sci->sc_root = root; | ||
2707 | |||
2700 | init_waitqueue_head(&sci->sc_wait_request); | 2708 | init_waitqueue_head(&sci->sc_wait_request); |
2701 | init_waitqueue_head(&sci->sc_wait_daemon); | 2709 | init_waitqueue_head(&sci->sc_wait_daemon); |
2702 | init_waitqueue_head(&sci->sc_wait_task); | 2710 | init_waitqueue_head(&sci->sc_wait_task); |
@@ -2771,6 +2779,8 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | |||
2771 | WARN_ON(!list_empty(&sci->sc_segbufs)); | 2779 | WARN_ON(!list_empty(&sci->sc_segbufs)); |
2772 | WARN_ON(!list_empty(&sci->sc_write_logs)); | 2780 | WARN_ON(!list_empty(&sci->sc_write_logs)); |
2773 | 2781 | ||
2782 | nilfs_put_root(sci->sc_root); | ||
2783 | |||
2774 | down_write(&sbi->s_nilfs->ns_segctor_sem); | 2784 | down_write(&sbi->s_nilfs->ns_segctor_sem); |
2775 | 2785 | ||
2776 | del_timer_sync(&sci->sc_timer); | 2786 | del_timer_sync(&sci->sc_timer); |
@@ -2780,6 +2790,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | |||
2780 | /** | 2790 | /** |
2781 | * nilfs_attach_segment_constructor - attach a segment constructor | 2791 | * nilfs_attach_segment_constructor - attach a segment constructor |
2782 | * @sbi: nilfs_sb_info | 2792 | * @sbi: nilfs_sb_info |
2793 | * @root: root object of the current filesystem tree | ||
2783 | * | 2794 | * |
2784 | * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info, | 2795 | * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info, |
2785 | * initializes it, and starts the segment constructor. | 2796 | * initializes it, and starts the segment constructor. |
@@ -2789,9 +2800,9 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | |||
2789 | * | 2800 | * |
2790 | * %-ENOMEM - Insufficient memory available. | 2801 | * %-ENOMEM - Insufficient memory available. |
2791 | */ | 2802 | */ |
2792 | int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi) | 2803 | int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi, |
2804 | struct nilfs_root *root) | ||
2793 | { | 2805 | { |
2794 | struct the_nilfs *nilfs = sbi->s_nilfs; | ||
2795 | int err; | 2806 | int err; |
2796 | 2807 | ||
2797 | if (NILFS_SC(sbi)) { | 2808 | if (NILFS_SC(sbi)) { |
@@ -2803,14 +2814,12 @@ int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi) | |||
2803 | nilfs_detach_segment_constructor(sbi); | 2814 | nilfs_detach_segment_constructor(sbi); |
2804 | } | 2815 | } |
2805 | 2816 | ||
2806 | sbi->s_sc_info = nilfs_segctor_new(sbi); | 2817 | sbi->s_sc_info = nilfs_segctor_new(sbi, root); |
2807 | if (!sbi->s_sc_info) | 2818 | if (!sbi->s_sc_info) |
2808 | return -ENOMEM; | 2819 | return -ENOMEM; |
2809 | 2820 | ||
2810 | nilfs_attach_writer(nilfs, sbi); | ||
2811 | err = nilfs_segctor_start_thread(NILFS_SC(sbi)); | 2821 | err = nilfs_segctor_start_thread(NILFS_SC(sbi)); |
2812 | if (err) { | 2822 | if (err) { |
2813 | nilfs_detach_writer(nilfs, sbi); | ||
2814 | kfree(sbi->s_sc_info); | 2823 | kfree(sbi->s_sc_info); |
2815 | sbi->s_sc_info = NULL; | 2824 | sbi->s_sc_info = NULL; |
2816 | } | 2825 | } |
@@ -2847,5 +2856,4 @@ void nilfs_detach_segment_constructor(struct nilfs_sb_info *sbi) | |||
2847 | up_write(&nilfs->ns_segctor_sem); | 2856 | up_write(&nilfs->ns_segctor_sem); |
2848 | 2857 | ||
2849 | nilfs_dispose_list(sbi, &garbage_list, 1); | 2858 | nilfs_dispose_list(sbi, &garbage_list, 1); |
2850 | nilfs_detach_writer(nilfs, sbi); | ||
2851 | } | 2859 | } |