aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nilfs2')
-rw-r--r--fs/nilfs2/segbuf.c2
-rw-r--r--fs/nilfs2/segbuf.h2
-rw-r--r--fs/nilfs2/segment.c45
-rw-r--r--fs/nilfs2/segment.h2
4 files changed, 25 insertions, 26 deletions
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c
index 17851f77f73..a24ca9cc6af 100644
--- a/fs/nilfs2/segbuf.c
+++ b/fs/nilfs2/segbuf.c
@@ -81,6 +81,7 @@ struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *sb)
81 INIT_LIST_HEAD(&segbuf->sb_list); 81 INIT_LIST_HEAD(&segbuf->sb_list);
82 INIT_LIST_HEAD(&segbuf->sb_segsum_buffers); 82 INIT_LIST_HEAD(&segbuf->sb_segsum_buffers);
83 INIT_LIST_HEAD(&segbuf->sb_payload_buffers); 83 INIT_LIST_HEAD(&segbuf->sb_payload_buffers);
84 segbuf->sb_super_root = NULL;
84 85
85 init_completion(&segbuf->sb_bio_event); 86 init_completion(&segbuf->sb_bio_event);
86 atomic_set(&segbuf->sb_err, 0); 87 atomic_set(&segbuf->sb_err, 0);
@@ -282,6 +283,7 @@ static void nilfs_segbuf_clear(struct nilfs_segment_buffer *segbuf)
282{ 283{
283 nilfs_release_buffers(&segbuf->sb_segsum_buffers); 284 nilfs_release_buffers(&segbuf->sb_segsum_buffers);
284 nilfs_release_buffers(&segbuf->sb_payload_buffers); 285 nilfs_release_buffers(&segbuf->sb_payload_buffers);
286 segbuf->sb_super_root = NULL;
285} 287}
286 288
287/* 289/*
diff --git a/fs/nilfs2/segbuf.h b/fs/nilfs2/segbuf.h
index 94dfd3517bc..a1a0af6119e 100644
--- a/fs/nilfs2/segbuf.h
+++ b/fs/nilfs2/segbuf.h
@@ -76,6 +76,7 @@ struct nilfs_segsum_info {
76 * @sb_rest_blocks: Number of residual blocks in the current segment 76 * @sb_rest_blocks: Number of residual blocks in the current segment
77 * @sb_segsum_buffers: List of buffers for segment summaries 77 * @sb_segsum_buffers: List of buffers for segment summaries
78 * @sb_payload_buffers: List of buffers for segment payload 78 * @sb_payload_buffers: List of buffers for segment payload
79 * @sb_super_root: Pointer to buffer storing a super root block (if exists)
79 * @sb_nbio: Number of flying bio requests 80 * @sb_nbio: Number of flying bio requests
80 * @sb_err: I/O error status 81 * @sb_err: I/O error status
81 * @sb_bio_event: Completion event of log writing 82 * @sb_bio_event: Completion event of log writing
@@ -95,6 +96,7 @@ struct nilfs_segment_buffer {
95 /* Buffers */ 96 /* Buffers */
96 struct list_head sb_segsum_buffers; 97 struct list_head sb_segsum_buffers;
97 struct list_head sb_payload_buffers; /* including super root */ 98 struct list_head sb_payload_buffers; /* including super root */
99 struct buffer_head *sb_super_root;
98 100
99 /* io status */ 101 /* io status */
100 int sb_nbio; 102 int sb_nbio;
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 6a7dbd8451d..7ab0270b262 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -435,7 +435,7 @@ static int nilfs_segctor_add_super_root(struct nilfs_sc_info *sci)
435 return err; 435 return err;
436 segbuf = sci->sc_curseg; 436 segbuf = sci->sc_curseg;
437 } 437 }
438 err = nilfs_segbuf_extend_payload(segbuf, &sci->sc_super_root); 438 err = nilfs_segbuf_extend_payload(segbuf, &segbuf->sb_super_root);
439 if (likely(!err)) 439 if (likely(!err))
440 segbuf->sb_sum.flags |= NILFS_SS_SR; 440 segbuf->sb_sum.flags |= NILFS_SS_SR;
441 return err; 441 return err;
@@ -952,10 +952,10 @@ static void nilfs_segctor_fill_in_checksums(struct nilfs_sc_info *sci,
952{ 952{
953 struct nilfs_segment_buffer *segbuf; 953 struct nilfs_segment_buffer *segbuf;
954 954
955 if (sci->sc_super_root)
956 nilfs_fill_in_super_root_crc(sci->sc_super_root, seed);
957
958 list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { 955 list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
956 if (segbuf->sb_super_root)
957 nilfs_fill_in_super_root_crc(segbuf->sb_super_root,
958 seed);
959 nilfs_segbuf_fill_in_segsum_crc(segbuf, seed); 959 nilfs_segbuf_fill_in_segsum_crc(segbuf, seed);
960 nilfs_segbuf_fill_in_data_crc(segbuf, seed); 960 nilfs_segbuf_fill_in_data_crc(segbuf, seed);
961 } 961 }
@@ -964,11 +964,13 @@ static void nilfs_segctor_fill_in_checksums(struct nilfs_sc_info *sci,
964static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci, 964static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci,
965 struct the_nilfs *nilfs) 965 struct the_nilfs *nilfs)
966{ 966{
967 struct buffer_head *bh_sr = sci->sc_super_root; 967 struct buffer_head *bh_sr;
968 struct nilfs_super_root *raw_sr = 968 struct nilfs_super_root *raw_sr;
969 (struct nilfs_super_root *)bh_sr->b_data;
970 unsigned isz = nilfs->ns_inode_size; 969 unsigned isz = nilfs->ns_inode_size;
971 970
971 bh_sr = NILFS_LAST_SEGBUF(&sci->sc_segbufs)->sb_super_root;
972 raw_sr = (struct nilfs_super_root *)bh_sr->b_data;
973
972 raw_sr->sr_bytes = cpu_to_le16(NILFS_SR_BYTES); 974 raw_sr->sr_bytes = cpu_to_le16(NILFS_SR_BYTES);
973 raw_sr->sr_nongc_ctime 975 raw_sr->sr_nongc_ctime
974 = cpu_to_le64(nilfs_doing_gc() ? 976 = cpu_to_le64(nilfs_doing_gc() ?
@@ -1491,7 +1493,6 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
1491 1493
1492 /* Collection retry loop */ 1494 /* Collection retry loop */
1493 for (;;) { 1495 for (;;) {
1494 sci->sc_super_root = NULL;
1495 sci->sc_nblk_this_inc = 0; 1496 sci->sc_nblk_this_inc = 0;
1496 sci->sc_curseg = NILFS_FIRST_SEGBUF(&sci->sc_segbufs); 1497 sci->sc_curseg = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
1497 1498
@@ -1568,7 +1569,7 @@ nilfs_segctor_update_payload_blocknr(struct nilfs_sc_info *sci,
1568 ssp.offset = sizeof(struct nilfs_segment_summary); 1569 ssp.offset = sizeof(struct nilfs_segment_summary);
1569 1570
1570 list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) { 1571 list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) {
1571 if (bh == sci->sc_super_root) 1572 if (bh == segbuf->sb_super_root)
1572 break; 1573 break;
1573 if (!finfo) { 1574 if (!finfo) {
1574 finfo = nilfs_segctor_map_segsum_entry( 1575 finfo = nilfs_segctor_map_segsum_entry(
@@ -1729,7 +1730,7 @@ static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci,
1729 1730
1730 list_for_each_entry(bh, &segbuf->sb_payload_buffers, 1731 list_for_each_entry(bh, &segbuf->sb_payload_buffers,
1731 b_assoc_buffers) { 1732 b_assoc_buffers) {
1732 if (bh == sci->sc_super_root) { 1733 if (bh == segbuf->sb_super_root) {
1733 if (bh->b_page != bd_page) { 1734 if (bh->b_page != bd_page) {
1734 lock_page(bd_page); 1735 lock_page(bd_page);
1735 clear_page_dirty_for_io(bd_page); 1736 clear_page_dirty_for_io(bd_page);
@@ -1848,7 +1849,7 @@ static void nilfs_clear_copied_buffers(struct list_head *list, int err)
1848} 1849}
1849 1850
1850static void nilfs_abort_logs(struct list_head *logs, struct page *failed_page, 1851static void nilfs_abort_logs(struct list_head *logs, struct page *failed_page,
1851 struct buffer_head *bh_sr, int err) 1852 int err)
1852{ 1853{
1853 struct nilfs_segment_buffer *segbuf; 1854 struct nilfs_segment_buffer *segbuf;
1854 struct page *bd_page = NULL, *fs_page = NULL; 1855 struct page *bd_page = NULL, *fs_page = NULL;
@@ -1869,7 +1870,7 @@ static void nilfs_abort_logs(struct list_head *logs, struct page *failed_page,
1869 1870
1870 list_for_each_entry(bh, &segbuf->sb_payload_buffers, 1871 list_for_each_entry(bh, &segbuf->sb_payload_buffers,
1871 b_assoc_buffers) { 1872 b_assoc_buffers) {
1872 if (bh == bh_sr) { 1873 if (bh == segbuf->sb_super_root) {
1873 if (bh->b_page != bd_page) { 1874 if (bh->b_page != bd_page) {
1874 end_page_writeback(bd_page); 1875 end_page_writeback(bd_page);
1875 bd_page = bh->b_page; 1876 bd_page = bh->b_page;
@@ -1898,7 +1899,7 @@ static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci,
1898 1899
1899 list_splice_tail_init(&sci->sc_write_logs, &logs); 1900 list_splice_tail_init(&sci->sc_write_logs, &logs);
1900 ret = nilfs_wait_on_logs(&logs); 1901 ret = nilfs_wait_on_logs(&logs);
1901 nilfs_abort_logs(&logs, NULL, sci->sc_super_root, ret ? : err); 1902 nilfs_abort_logs(&logs, NULL, ret ? : err);
1902 1903
1903 list_splice_tail_init(&sci->sc_segbufs, &logs); 1904 list_splice_tail_init(&sci->sc_segbufs, &logs);
1904 nilfs_cancel_segusage(&logs, nilfs->ns_sufile); 1905 nilfs_cancel_segusage(&logs, nilfs->ns_sufile);
@@ -1914,7 +1915,6 @@ static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci,
1914 } 1915 }
1915 1916
1916 nilfs_destroy_logs(&logs); 1917 nilfs_destroy_logs(&logs);
1917 sci->sc_super_root = NULL;
1918} 1918}
1919 1919
1920static void nilfs_set_next_segment(struct the_nilfs *nilfs, 1920static void nilfs_set_next_segment(struct the_nilfs *nilfs,
@@ -1933,7 +1933,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
1933 struct nilfs_segment_buffer *segbuf; 1933 struct nilfs_segment_buffer *segbuf;
1934 struct page *bd_page = NULL, *fs_page = NULL; 1934 struct page *bd_page = NULL, *fs_page = NULL;
1935 struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs; 1935 struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs;
1936 int update_sr = (sci->sc_super_root != NULL); 1936 int update_sr = false;
1937 1937
1938 list_for_each_entry(segbuf, &sci->sc_write_logs, sb_list) { 1938 list_for_each_entry(segbuf, &sci->sc_write_logs, sb_list) {
1939 struct buffer_head *bh; 1939 struct buffer_head *bh;
@@ -1964,11 +1964,12 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
1964 set_buffer_uptodate(bh); 1964 set_buffer_uptodate(bh);
1965 clear_buffer_dirty(bh); 1965 clear_buffer_dirty(bh);
1966 clear_buffer_nilfs_volatile(bh); 1966 clear_buffer_nilfs_volatile(bh);
1967 if (bh == sci->sc_super_root) { 1967 if (bh == segbuf->sb_super_root) {
1968 if (bh->b_page != bd_page) { 1968 if (bh->b_page != bd_page) {
1969 end_page_writeback(bd_page); 1969 end_page_writeback(bd_page);
1970 bd_page = bh->b_page; 1970 bd_page = bh->b_page;
1971 } 1971 }
1972 update_sr = true;
1972 break; 1973 break;
1973 } 1974 }
1974 if (bh->b_page != fs_page) { 1975 if (bh->b_page != fs_page) {
@@ -2115,7 +2116,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
2115 struct nilfs_sb_info *sbi = sci->sc_sbi; 2116 struct nilfs_sb_info *sbi = sci->sc_sbi;
2116 struct the_nilfs *nilfs = sbi->s_nilfs; 2117 struct the_nilfs *nilfs = sbi->s_nilfs;
2117 struct page *failed_page; 2118 struct page *failed_page;
2118 int err, has_sr = 0; 2119 int err;
2119 2120
2120 sci->sc_stage.scnt = NILFS_ST_INIT; 2121 sci->sc_stage.scnt = NILFS_ST_INIT;
2121 2122
@@ -2143,8 +2144,6 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
2143 if (unlikely(err)) 2144 if (unlikely(err))
2144 goto failed; 2145 goto failed;
2145 2146
2146 has_sr = (sci->sc_super_root != NULL);
2147
2148 /* Avoid empty segment */ 2147 /* Avoid empty segment */
2149 if (sci->sc_stage.scnt == NILFS_ST_DONE && 2148 if (sci->sc_stage.scnt == NILFS_ST_DONE &&
2150 NILFS_SEG_EMPTY(&sci->sc_curseg->sb_sum)) { 2149 NILFS_SEG_EMPTY(&sci->sc_curseg->sb_sum)) {
@@ -2159,7 +2158,8 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
2159 if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED) 2158 if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
2160 nilfs_segctor_fill_in_file_bmap(sci, sbi->s_ifile); 2159 nilfs_segctor_fill_in_file_bmap(sci, sbi->s_ifile);
2161 2160
2162 if (has_sr) { 2161 if (mode == SC_LSEG_SR &&
2162 sci->sc_stage.scnt >= NILFS_ST_CPFILE) {
2163 err = nilfs_segctor_fill_in_checkpoint(sci); 2163 err = nilfs_segctor_fill_in_checkpoint(sci);
2164 if (unlikely(err)) 2164 if (unlikely(err))
2165 goto failed_to_write; 2165 goto failed_to_write;
@@ -2171,8 +2171,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
2171 /* Write partial segments */ 2171 /* Write partial segments */
2172 err = nilfs_segctor_prepare_write(sci, &failed_page); 2172 err = nilfs_segctor_prepare_write(sci, &failed_page);
2173 if (err) { 2173 if (err) {
2174 nilfs_abort_logs(&sci->sc_segbufs, failed_page, 2174 nilfs_abort_logs(&sci->sc_segbufs, failed_page, err);
2175 sci->sc_super_root, err);
2176 goto failed_to_write; 2175 goto failed_to_write;
2177 } 2176 }
2178 nilfs_segctor_fill_in_checksums(sci, nilfs->ns_crc_seed); 2177 nilfs_segctor_fill_in_checksums(sci, nilfs->ns_crc_seed);
@@ -2196,8 +2195,6 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
2196 } 2195 }
2197 } while (sci->sc_stage.scnt != NILFS_ST_DONE); 2196 } while (sci->sc_stage.scnt != NILFS_ST_DONE);
2198 2197
2199 sci->sc_super_root = NULL;
2200
2201 out: 2198 out:
2202 nilfs_segctor_check_out_files(sci, sbi); 2199 nilfs_segctor_check_out_files(sci, sbi);
2203 return err; 2200 return err;
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h
index 82dfd6a686b..e61fc797383 100644
--- a/fs/nilfs2/segment.h
+++ b/fs/nilfs2/segment.h
@@ -100,7 +100,6 @@ struct nilfs_segsum_pointer {
100 * @sc_write_logs: List of segment buffers to hold logs under writing 100 * @sc_write_logs: List of segment buffers to hold logs under writing
101 * @sc_segbuf_nblocks: Number of available blocks in segment buffers. 101 * @sc_segbuf_nblocks: Number of available blocks in segment buffers.
102 * @sc_curseg: Current segment buffer 102 * @sc_curseg: Current segment buffer
103 * @sc_super_root: Pointer to the super root buffer
104 * @sc_stage: Collection stage 103 * @sc_stage: Collection stage
105 * @sc_finfo_ptr: pointer to the current finfo struct in the segment summary 104 * @sc_finfo_ptr: pointer to the current finfo struct in the segment summary
106 * @sc_binfo_ptr: pointer to the current binfo struct in the segment summary 105 * @sc_binfo_ptr: pointer to the current binfo struct in the segment summary
@@ -148,7 +147,6 @@ struct nilfs_sc_info {
148 struct list_head sc_write_logs; 147 struct list_head sc_write_logs;
149 unsigned long sc_segbuf_nblocks; 148 unsigned long sc_segbuf_nblocks;
150 struct nilfs_segment_buffer *sc_curseg; 149 struct nilfs_segment_buffer *sc_curseg;
151 struct buffer_head *sc_super_root;
152 150
153 struct nilfs_cstage sc_stage; 151 struct nilfs_cstage sc_stage;
154 152