]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - fs/nilfs2/segment.c
nilfs2: move pointer to super root block into logs
[net-next-2.6.git] / fs / nilfs2 / segment.c
index 6a7dbd8451db73d40080156ff325c82183437f51..7ab0270b262933c49024476375cfa6028b545e6f 100644 (file)
@@ -435,7 +435,7 @@ static int nilfs_segctor_add_super_root(struct nilfs_sc_info *sci)
                        return err;
                segbuf = sci->sc_curseg;
        }
-       err = nilfs_segbuf_extend_payload(segbuf, &sci->sc_super_root);
+       err = nilfs_segbuf_extend_payload(segbuf, &segbuf->sb_super_root);
        if (likely(!err))
                segbuf->sb_sum.flags |= NILFS_SS_SR;
        return err;
@@ -952,10 +952,10 @@ static void nilfs_segctor_fill_in_checksums(struct nilfs_sc_info *sci,
 {
        struct nilfs_segment_buffer *segbuf;
 
-       if (sci->sc_super_root)
-               nilfs_fill_in_super_root_crc(sci->sc_super_root, seed);
-
        list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
+               if (segbuf->sb_super_root)
+                       nilfs_fill_in_super_root_crc(segbuf->sb_super_root,
+                                                    seed);
                nilfs_segbuf_fill_in_segsum_crc(segbuf, seed);
                nilfs_segbuf_fill_in_data_crc(segbuf, seed);
        }
@@ -964,11 +964,13 @@ static void nilfs_segctor_fill_in_checksums(struct nilfs_sc_info *sci,
 static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci,
                                             struct the_nilfs *nilfs)
 {
-       struct buffer_head *bh_sr = sci->sc_super_root;
-       struct nilfs_super_root *raw_sr =
-               (struct nilfs_super_root *)bh_sr->b_data;
+       struct buffer_head *bh_sr;
+       struct nilfs_super_root *raw_sr;
        unsigned isz = nilfs->ns_inode_size;
 
+       bh_sr = NILFS_LAST_SEGBUF(&sci->sc_segbufs)->sb_super_root;
+       raw_sr = (struct nilfs_super_root *)bh_sr->b_data;
+
        raw_sr->sr_bytes = cpu_to_le16(NILFS_SR_BYTES);
        raw_sr->sr_nongc_ctime
                = cpu_to_le64(nilfs_doing_gc() ?
@@ -1491,7 +1493,6 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
 
        /* Collection retry loop */
        for (;;) {
-               sci->sc_super_root = NULL;
                sci->sc_nblk_this_inc = 0;
                sci->sc_curseg = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
 
@@ -1568,7 +1569,7 @@ nilfs_segctor_update_payload_blocknr(struct nilfs_sc_info *sci,
        ssp.offset = sizeof(struct nilfs_segment_summary);
 
        list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) {
-               if (bh == sci->sc_super_root)
+               if (bh == segbuf->sb_super_root)
                        break;
                if (!finfo) {
                        finfo = nilfs_segctor_map_segsum_entry(
@@ -1729,7 +1730,7 @@ static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci,
 
                list_for_each_entry(bh, &segbuf->sb_payload_buffers,
                                    b_assoc_buffers) {
-                       if (bh == sci->sc_super_root) {
+                       if (bh == segbuf->sb_super_root) {
                                if (bh->b_page != bd_page) {
                                        lock_page(bd_page);
                                        clear_page_dirty_for_io(bd_page);
@@ -1848,7 +1849,7 @@ static void nilfs_clear_copied_buffers(struct list_head *list, int err)
 }
 
 static void nilfs_abort_logs(struct list_head *logs, struct page *failed_page,
-                            struct buffer_head *bh_sr, int err)
+                            int err)
 {
        struct nilfs_segment_buffer *segbuf;
        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,
 
                list_for_each_entry(bh, &segbuf->sb_payload_buffers,
                                    b_assoc_buffers) {
-                       if (bh == bh_sr) {
+                       if (bh == segbuf->sb_super_root) {
                                if (bh->b_page != bd_page) {
                                        end_page_writeback(bd_page);
                                        bd_page = bh->b_page;
@@ -1898,7 +1899,7 @@ static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci,
 
        list_splice_tail_init(&sci->sc_write_logs, &logs);
        ret = nilfs_wait_on_logs(&logs);
-       nilfs_abort_logs(&logs, NULL, sci->sc_super_root, ret ? : err);
+       nilfs_abort_logs(&logs, NULL, ret ? : err);
 
        list_splice_tail_init(&sci->sc_segbufs, &logs);
        nilfs_cancel_segusage(&logs, nilfs->ns_sufile);
@@ -1914,7 +1915,6 @@ static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci,
        }
 
        nilfs_destroy_logs(&logs);
-       sci->sc_super_root = NULL;
 }
 
 static void nilfs_set_next_segment(struct the_nilfs *nilfs,
@@ -1933,7 +1933,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
        struct nilfs_segment_buffer *segbuf;
        struct page *bd_page = NULL, *fs_page = NULL;
        struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs;
-       int update_sr = (sci->sc_super_root != NULL);
+       int update_sr = false;
 
        list_for_each_entry(segbuf, &sci->sc_write_logs, sb_list) {
                struct buffer_head *bh;
@@ -1964,11 +1964,12 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
                        set_buffer_uptodate(bh);
                        clear_buffer_dirty(bh);
                        clear_buffer_nilfs_volatile(bh);
-                       if (bh == sci->sc_super_root) {
+                       if (bh == segbuf->sb_super_root) {
                                if (bh->b_page != bd_page) {
                                        end_page_writeback(bd_page);
                                        bd_page = bh->b_page;
                                }
+                               update_sr = true;
                                break;
                        }
                        if (bh->b_page != fs_page) {
@@ -2115,7 +2116,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
        struct nilfs_sb_info *sbi = sci->sc_sbi;
        struct the_nilfs *nilfs = sbi->s_nilfs;
        struct page *failed_page;
-       int err, has_sr = 0;
+       int err;
 
        sci->sc_stage.scnt = NILFS_ST_INIT;
 
@@ -2143,8 +2144,6 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
                if (unlikely(err))
                        goto failed;
 
-               has_sr = (sci->sc_super_root != NULL);
-
                /* Avoid empty segment */
                if (sci->sc_stage.scnt == NILFS_ST_DONE &&
                    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)
                if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
                        nilfs_segctor_fill_in_file_bmap(sci, sbi->s_ifile);
 
-               if (has_sr) {
+               if (mode == SC_LSEG_SR &&
+                   sci->sc_stage.scnt >= NILFS_ST_CPFILE) {
                        err = nilfs_segctor_fill_in_checkpoint(sci);
                        if (unlikely(err))
                                goto failed_to_write;
@@ -2171,8 +2171,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
                /* Write partial segments */
                err = nilfs_segctor_prepare_write(sci, &failed_page);
                if (err) {
-                       nilfs_abort_logs(&sci->sc_segbufs, failed_page,
-                                        sci->sc_super_root, err);
+                       nilfs_abort_logs(&sci->sc_segbufs, failed_page, err);
                        goto failed_to_write;
                }
                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)
                }
        } while (sci->sc_stage.scnt != NILFS_ST_DONE);
 
-       sci->sc_super_root = NULL;
-
  out:
        nilfs_segctor_check_out_files(sci, sbi);
        return err;