diff options
Diffstat (limited to 'fs/nilfs2/segment.c')
| -rw-r--r-- | fs/nilfs2/segment.c | 143 |
1 files changed, 75 insertions, 68 deletions
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 105b508b47a8..c161d89061b5 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
| @@ -141,7 +141,7 @@ int nilfs_init_transaction_cache(void) | |||
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | /** | 143 | /** |
| 144 | * nilfs_detroy_transaction_cache - destroy the cache for transaction info | 144 | * nilfs_destroy_transaction_cache - destroy the cache for transaction info |
| 145 | * | 145 | * |
| 146 | * nilfs_destroy_transaction_cache() frees the slab cache for the struct | 146 | * nilfs_destroy_transaction_cache() frees the slab cache for the struct |
| 147 | * nilfs_transaction_info. | 147 | * nilfs_transaction_info. |
| @@ -201,7 +201,7 @@ static int nilfs_prepare_segment_lock(struct nilfs_transaction_info *ti) | |||
| 201 | * This function allocates a nilfs_transaction_info struct to keep context | 201 | * This function allocates a nilfs_transaction_info struct to keep context |
| 202 | * information on it. It is initialized and hooked onto the current task in | 202 | * information on it. It is initialized and hooked onto the current task in |
| 203 | * the outermost call. If a pre-allocated struct is given to @ti, it is used | 203 | * the outermost call. If a pre-allocated struct is given to @ti, it is used |
| 204 | * instead; othewise a new struct is assigned from a slab. | 204 | * instead; otherwise a new struct is assigned from a slab. |
| 205 | * | 205 | * |
| 206 | * When @vacancy_check flag is set, this function will check the amount of | 206 | * When @vacancy_check flag is set, this function will check the amount of |
| 207 | * free space, and will wait for the GC to reclaim disk space if low capacity. | 207 | * free space, and will wait for the GC to reclaim disk space if low capacity. |
| @@ -1510,6 +1510,12 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci, | |||
| 1510 | if (mode != SC_LSEG_SR || sci->sc_stage.scnt < NILFS_ST_CPFILE) | 1510 | if (mode != SC_LSEG_SR || sci->sc_stage.scnt < NILFS_ST_CPFILE) |
| 1511 | break; | 1511 | break; |
| 1512 | 1512 | ||
| 1513 | nilfs_clear_logs(&sci->sc_segbufs); | ||
| 1514 | |||
| 1515 | err = nilfs_segctor_extend_segments(sci, nilfs, nadd); | ||
| 1516 | if (unlikely(err)) | ||
| 1517 | return err; | ||
| 1518 | |||
| 1513 | if (sci->sc_stage.flags & NILFS_CF_SUFREED) { | 1519 | if (sci->sc_stage.flags & NILFS_CF_SUFREED) { |
| 1514 | err = nilfs_sufile_cancel_freev(nilfs->ns_sufile, | 1520 | err = nilfs_sufile_cancel_freev(nilfs->ns_sufile, |
| 1515 | sci->sc_freesegs, | 1521 | sci->sc_freesegs, |
| @@ -1517,12 +1523,6 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci, | |||
| 1517 | NULL); | 1523 | NULL); |
| 1518 | WARN_ON(err); /* do not happen */ | 1524 | WARN_ON(err); /* do not happen */ |
| 1519 | } | 1525 | } |
| 1520 | nilfs_clear_logs(&sci->sc_segbufs); | ||
| 1521 | |||
| 1522 | err = nilfs_segctor_extend_segments(sci, nilfs, nadd); | ||
| 1523 | if (unlikely(err)) | ||
| 1524 | return err; | ||
| 1525 | |||
| 1526 | nadd = min_t(int, nadd << 1, SC_MAX_SEGDELTA); | 1526 | nadd = min_t(int, nadd << 1, SC_MAX_SEGDELTA); |
| 1527 | sci->sc_stage = prev_stage; | 1527 | sci->sc_stage = prev_stage; |
| 1528 | } | 1528 | } |
| @@ -1764,14 +1764,9 @@ static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci, | |||
| 1764 | static int nilfs_segctor_write(struct nilfs_sc_info *sci, | 1764 | static int nilfs_segctor_write(struct nilfs_sc_info *sci, |
| 1765 | struct the_nilfs *nilfs) | 1765 | struct the_nilfs *nilfs) |
| 1766 | { | 1766 | { |
| 1767 | struct nilfs_segment_buffer *segbuf; | 1767 | int ret; |
| 1768 | int ret = 0; | ||
| 1769 | 1768 | ||
| 1770 | list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) { | 1769 | ret = nilfs_write_logs(&sci->sc_segbufs, nilfs); |
| 1771 | ret = nilfs_segbuf_write(segbuf, nilfs); | ||
| 1772 | if (ret) | ||
| 1773 | break; | ||
| 1774 | } | ||
| 1775 | list_splice_tail_init(&sci->sc_segbufs, &sci->sc_write_logs); | 1770 | list_splice_tail_init(&sci->sc_segbufs, &sci->sc_write_logs); |
| 1776 | return ret; | 1771 | return ret; |
| 1777 | } | 1772 | } |
| @@ -1902,8 +1897,7 @@ static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci, | |||
| 1902 | 1897 | ||
| 1903 | list_splice_tail_init(&sci->sc_write_logs, &logs); | 1898 | list_splice_tail_init(&sci->sc_write_logs, &logs); |
| 1904 | ret = nilfs_wait_on_logs(&logs); | 1899 | ret = nilfs_wait_on_logs(&logs); |
| 1905 | if (ret) | 1900 | nilfs_abort_logs(&logs, NULL, sci->sc_super_root, ret ? : err); |
| 1906 | nilfs_abort_logs(&logs, NULL, sci->sc_super_root, ret); | ||
| 1907 | 1901 | ||
| 1908 | list_splice_tail_init(&sci->sc_segbufs, &logs); | 1902 | list_splice_tail_init(&sci->sc_segbufs, &logs); |
| 1909 | nilfs_cancel_segusage(&logs, nilfs->ns_sufile); | 1903 | nilfs_cancel_segusage(&logs, nilfs->ns_sufile); |
| @@ -1937,8 +1931,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) | |||
| 1937 | { | 1931 | { |
| 1938 | struct nilfs_segment_buffer *segbuf; | 1932 | struct nilfs_segment_buffer *segbuf; |
| 1939 | struct page *bd_page = NULL, *fs_page = NULL; | 1933 | struct page *bd_page = NULL, *fs_page = NULL; |
| 1940 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 1934 | struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs; |
| 1941 | struct the_nilfs *nilfs = sbi->s_nilfs; | ||
| 1942 | int update_sr = (sci->sc_super_root != NULL); | 1935 | int update_sr = (sci->sc_super_root != NULL); |
| 1943 | 1936 | ||
| 1944 | list_for_each_entry(segbuf, &sci->sc_write_logs, sb_list) { | 1937 | list_for_each_entry(segbuf, &sci->sc_write_logs, sb_list) { |
| @@ -2020,7 +2013,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) | |||
| 2020 | if (update_sr) { | 2013 | if (update_sr) { |
| 2021 | nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start, | 2014 | nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start, |
| 2022 | segbuf->sb_sum.seg_seq, nilfs->ns_cno++); | 2015 | segbuf->sb_sum.seg_seq, nilfs->ns_cno++); |
| 2023 | sbi->s_super->s_dirt = 1; | 2016 | set_nilfs_sb_dirty(nilfs); |
| 2024 | 2017 | ||
| 2025 | clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags); | 2018 | clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags); |
| 2026 | clear_bit(NILFS_SC_DIRTY, &sci->sc_flags); | 2019 | clear_bit(NILFS_SC_DIRTY, &sci->sc_flags); |
| @@ -2220,7 +2213,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | |||
| 2220 | } | 2213 | } |
| 2221 | 2214 | ||
| 2222 | /** | 2215 | /** |
| 2223 | * nilfs_secgtor_start_timer - set timer of background write | 2216 | * nilfs_segctor_start_timer - set timer of background write |
| 2224 | * @sci: nilfs_sc_info | 2217 | * @sci: nilfs_sc_info |
| 2225 | * | 2218 | * |
| 2226 | * If the timer has already been set, it ignores the new request. | 2219 | * If the timer has already been set, it ignores the new request. |
| @@ -2425,43 +2418,43 @@ int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode, | |||
| 2425 | return err; | 2418 | return err; |
| 2426 | } | 2419 | } |
| 2427 | 2420 | ||
| 2428 | struct nilfs_segctor_req { | ||
| 2429 | int mode; | ||
| 2430 | __u32 seq_accepted; | ||
| 2431 | int sc_err; /* construction failure */ | ||
| 2432 | int sb_err; /* super block writeback failure */ | ||
| 2433 | }; | ||
| 2434 | |||
| 2435 | #define FLUSH_FILE_BIT (0x1) /* data file only */ | 2421 | #define FLUSH_FILE_BIT (0x1) /* data file only */ |
| 2436 | #define FLUSH_DAT_BIT (1 << NILFS_DAT_INO) /* DAT only */ | 2422 | #define FLUSH_DAT_BIT (1 << NILFS_DAT_INO) /* DAT only */ |
| 2437 | 2423 | ||
| 2438 | static void nilfs_segctor_accept(struct nilfs_sc_info *sci, | 2424 | /** |
| 2439 | struct nilfs_segctor_req *req) | 2425 | * nilfs_segctor_accept - record accepted sequence count of log-write requests |
| 2426 | * @sci: segment constructor object | ||
| 2427 | */ | ||
| 2428 | static void nilfs_segctor_accept(struct nilfs_sc_info *sci) | ||
| 2440 | { | 2429 | { |
| 2441 | req->sc_err = req->sb_err = 0; | ||
| 2442 | spin_lock(&sci->sc_state_lock); | 2430 | spin_lock(&sci->sc_state_lock); |
| 2443 | req->seq_accepted = sci->sc_seq_request; | 2431 | sci->sc_seq_accepted = sci->sc_seq_request; |
| 2444 | spin_unlock(&sci->sc_state_lock); | 2432 | spin_unlock(&sci->sc_state_lock); |
| 2445 | 2433 | ||
| 2446 | if (sci->sc_timer) | 2434 | if (sci->sc_timer) |
| 2447 | del_timer_sync(sci->sc_timer); | 2435 | del_timer_sync(sci->sc_timer); |
| 2448 | } | 2436 | } |
| 2449 | 2437 | ||
| 2450 | static void nilfs_segctor_notify(struct nilfs_sc_info *sci, | 2438 | /** |
| 2451 | struct nilfs_segctor_req *req) | 2439 | * nilfs_segctor_notify - notify the result of request to caller threads |
| 2440 | * @sci: segment constructor object | ||
| 2441 | * @mode: mode of log forming | ||
| 2442 | * @err: error code to be notified | ||
| 2443 | */ | ||
| 2444 | static void nilfs_segctor_notify(struct nilfs_sc_info *sci, int mode, int err) | ||
| 2452 | { | 2445 | { |
| 2453 | /* Clear requests (even when the construction failed) */ | 2446 | /* Clear requests (even when the construction failed) */ |
| 2454 | spin_lock(&sci->sc_state_lock); | 2447 | spin_lock(&sci->sc_state_lock); |
| 2455 | 2448 | ||
| 2456 | if (req->mode == SC_LSEG_SR) { | 2449 | if (mode == SC_LSEG_SR) { |
| 2457 | sci->sc_state &= ~NILFS_SEGCTOR_COMMIT; | 2450 | sci->sc_state &= ~NILFS_SEGCTOR_COMMIT; |
| 2458 | sci->sc_seq_done = req->seq_accepted; | 2451 | sci->sc_seq_done = sci->sc_seq_accepted; |
| 2459 | nilfs_segctor_wakeup(sci, req->sc_err ? : req->sb_err); | 2452 | nilfs_segctor_wakeup(sci, err); |
| 2460 | sci->sc_flush_request = 0; | 2453 | sci->sc_flush_request = 0; |
| 2461 | } else { | 2454 | } else { |
| 2462 | if (req->mode == SC_FLUSH_FILE) | 2455 | if (mode == SC_FLUSH_FILE) |
| 2463 | sci->sc_flush_request &= ~FLUSH_FILE_BIT; | 2456 | sci->sc_flush_request &= ~FLUSH_FILE_BIT; |
| 2464 | else if (req->mode == SC_FLUSH_DAT) | 2457 | else if (mode == SC_FLUSH_DAT) |
| 2465 | sci->sc_flush_request &= ~FLUSH_DAT_BIT; | 2458 | sci->sc_flush_request &= ~FLUSH_DAT_BIT; |
| 2466 | 2459 | ||
| 2467 | /* re-enable timer if checkpoint creation was not done */ | 2460 | /* re-enable timer if checkpoint creation was not done */ |
| @@ -2472,30 +2465,37 @@ static void nilfs_segctor_notify(struct nilfs_sc_info *sci, | |||
| 2472 | spin_unlock(&sci->sc_state_lock); | 2465 | spin_unlock(&sci->sc_state_lock); |
| 2473 | } | 2466 | } |
| 2474 | 2467 | ||
| 2475 | static int nilfs_segctor_construct(struct nilfs_sc_info *sci, | 2468 | /** |
| 2476 | struct nilfs_segctor_req *req) | 2469 | * nilfs_segctor_construct - form logs and write them to disk |
| 2470 | * @sci: segment constructor object | ||
| 2471 | * @mode: mode of log forming | ||
| 2472 | */ | ||
| 2473 | static int nilfs_segctor_construct(struct nilfs_sc_info *sci, int mode) | ||
| 2477 | { | 2474 | { |
| 2478 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 2475 | struct nilfs_sb_info *sbi = sci->sc_sbi; |
| 2479 | struct the_nilfs *nilfs = sbi->s_nilfs; | 2476 | struct the_nilfs *nilfs = sbi->s_nilfs; |
| 2480 | int err = 0; | 2477 | int err = 0; |
| 2481 | 2478 | ||
| 2479 | nilfs_segctor_accept(sci); | ||
| 2480 | |||
| 2482 | if (nilfs_discontinued(nilfs)) | 2481 | if (nilfs_discontinued(nilfs)) |
| 2483 | req->mode = SC_LSEG_SR; | 2482 | mode = SC_LSEG_SR; |
| 2484 | if (!nilfs_segctor_confirm(sci)) { | 2483 | if (!nilfs_segctor_confirm(sci)) |
| 2485 | err = nilfs_segctor_do_construct(sci, req->mode); | 2484 | err = nilfs_segctor_do_construct(sci, mode); |
| 2486 | req->sc_err = err; | 2485 | |
| 2487 | } | ||
| 2488 | if (likely(!err)) { | 2486 | if (likely(!err)) { |
| 2489 | if (req->mode != SC_FLUSH_DAT) | 2487 | if (mode != SC_FLUSH_DAT) |
| 2490 | atomic_set(&nilfs->ns_ndirtyblks, 0); | 2488 | atomic_set(&nilfs->ns_ndirtyblks, 0); |
| 2491 | if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) && | 2489 | if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) && |
| 2492 | nilfs_discontinued(nilfs)) { | 2490 | nilfs_discontinued(nilfs)) { |
| 2493 | down_write(&nilfs->ns_sem); | 2491 | down_write(&nilfs->ns_sem); |
| 2494 | req->sb_err = nilfs_commit_super(sbi, | 2492 | err = nilfs_commit_super( |
| 2495 | nilfs_altsb_need_update(nilfs)); | 2493 | sbi, nilfs_altsb_need_update(nilfs)); |
| 2496 | up_write(&nilfs->ns_sem); | 2494 | up_write(&nilfs->ns_sem); |
| 2497 | } | 2495 | } |
| 2498 | } | 2496 | } |
| 2497 | |||
| 2498 | nilfs_segctor_notify(sci, mode, err); | ||
| 2499 | return err; | 2499 | return err; |
| 2500 | } | 2500 | } |
| 2501 | 2501 | ||
| @@ -2526,7 +2526,6 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv, | |||
| 2526 | struct nilfs_sc_info *sci = NILFS_SC(sbi); | 2526 | struct nilfs_sc_info *sci = NILFS_SC(sbi); |
| 2527 | struct the_nilfs *nilfs = sbi->s_nilfs; | 2527 | struct the_nilfs *nilfs = sbi->s_nilfs; |
| 2528 | struct nilfs_transaction_info ti; | 2528 | struct nilfs_transaction_info ti; |
| 2529 | struct nilfs_segctor_req req = { .mode = SC_LSEG_SR }; | ||
| 2530 | int err; | 2529 | int err; |
| 2531 | 2530 | ||
| 2532 | if (unlikely(!sci)) | 2531 | if (unlikely(!sci)) |
| @@ -2547,10 +2546,8 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv, | |||
| 2547 | list_splice_tail_init(&nilfs->ns_gc_inodes, &sci->sc_gc_inodes); | 2546 | list_splice_tail_init(&nilfs->ns_gc_inodes, &sci->sc_gc_inodes); |
| 2548 | 2547 | ||
| 2549 | for (;;) { | 2548 | for (;;) { |
| 2550 | nilfs_segctor_accept(sci, &req); | 2549 | err = nilfs_segctor_construct(sci, SC_LSEG_SR); |
| 2551 | err = nilfs_segctor_construct(sci, &req); | ||
| 2552 | nilfs_remove_written_gcinodes(nilfs, &sci->sc_gc_inodes); | 2550 | nilfs_remove_written_gcinodes(nilfs, &sci->sc_gc_inodes); |
| 2553 | nilfs_segctor_notify(sci, &req); | ||
| 2554 | 2551 | ||
| 2555 | if (likely(!err)) | 2552 | if (likely(!err)) |
| 2556 | break; | 2553 | break; |
| @@ -2560,6 +2557,16 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv, | |||
| 2560 | set_current_state(TASK_INTERRUPTIBLE); | 2557 | set_current_state(TASK_INTERRUPTIBLE); |
| 2561 | schedule_timeout(sci->sc_interval); | 2558 | schedule_timeout(sci->sc_interval); |
| 2562 | } | 2559 | } |
| 2560 | if (nilfs_test_opt(sbi, DISCARD)) { | ||
| 2561 | int ret = nilfs_discard_segments(nilfs, sci->sc_freesegs, | ||
| 2562 | sci->sc_nfreesegs); | ||
| 2563 | if (ret) { | ||
| 2564 | printk(KERN_WARNING | ||
| 2565 | "NILFS warning: error %d on discard request, " | ||
| 2566 | "turning discards off for the device\n", ret); | ||
| 2567 | nilfs_clear_opt(sbi, DISCARD); | ||
| 2568 | } | ||
| 2569 | } | ||
| 2563 | 2570 | ||
| 2564 | out_unlock: | 2571 | out_unlock: |
| 2565 | sci->sc_freesegs = NULL; | 2572 | sci->sc_freesegs = NULL; |
| @@ -2573,13 +2580,9 @@ static void nilfs_segctor_thread_construct(struct nilfs_sc_info *sci, int mode) | |||
| 2573 | { | 2580 | { |
| 2574 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 2581 | struct nilfs_sb_info *sbi = sci->sc_sbi; |
| 2575 | struct nilfs_transaction_info ti; | 2582 | struct nilfs_transaction_info ti; |
| 2576 | struct nilfs_segctor_req req = { .mode = mode }; | ||
| 2577 | 2583 | ||
| 2578 | nilfs_transaction_lock(sbi, &ti, 0); | 2584 | nilfs_transaction_lock(sbi, &ti, 0); |
| 2579 | 2585 | nilfs_segctor_construct(sci, mode); | |
| 2580 | nilfs_segctor_accept(sci, &req); | ||
| 2581 | nilfs_segctor_construct(sci, &req); | ||
| 2582 | nilfs_segctor_notify(sci, &req); | ||
| 2583 | 2586 | ||
| 2584 | /* | 2587 | /* |
| 2585 | * Unclosed segment should be retried. We do this using sc_timer. | 2588 | * Unclosed segment should be retried. We do this using sc_timer. |
| @@ -2635,6 +2638,7 @@ static int nilfs_segctor_flush_mode(struct nilfs_sc_info *sci) | |||
| 2635 | static int nilfs_segctor_thread(void *arg) | 2638 | static int nilfs_segctor_thread(void *arg) |
| 2636 | { | 2639 | { |
| 2637 | struct nilfs_sc_info *sci = (struct nilfs_sc_info *)arg; | 2640 | struct nilfs_sc_info *sci = (struct nilfs_sc_info *)arg; |
| 2641 | struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs; | ||
| 2638 | struct timer_list timer; | 2642 | struct timer_list timer; |
| 2639 | int timeout = 0; | 2643 | int timeout = 0; |
| 2640 | 2644 | ||
| @@ -2680,7 +2684,6 @@ static int nilfs_segctor_thread(void *arg) | |||
| 2680 | } else { | 2684 | } else { |
| 2681 | DEFINE_WAIT(wait); | 2685 | DEFINE_WAIT(wait); |
| 2682 | int should_sleep = 1; | 2686 | int should_sleep = 1; |
| 2683 | struct the_nilfs *nilfs; | ||
| 2684 | 2687 | ||
| 2685 | prepare_to_wait(&sci->sc_wait_daemon, &wait, | 2688 | prepare_to_wait(&sci->sc_wait_daemon, &wait, |
| 2686 | TASK_INTERRUPTIBLE); | 2689 | TASK_INTERRUPTIBLE); |
| @@ -2701,8 +2704,8 @@ static int nilfs_segctor_thread(void *arg) | |||
| 2701 | finish_wait(&sci->sc_wait_daemon, &wait); | 2704 | finish_wait(&sci->sc_wait_daemon, &wait); |
| 2702 | timeout = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) && | 2705 | timeout = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) && |
| 2703 | time_after_eq(jiffies, sci->sc_timer->expires)); | 2706 | time_after_eq(jiffies, sci->sc_timer->expires)); |
| 2704 | nilfs = sci->sc_sbi->s_nilfs; | 2707 | |
| 2705 | if (sci->sc_super->s_dirt && nilfs_sb_need_update(nilfs)) | 2708 | if (nilfs_sb_dirty(nilfs) && nilfs_sb_need_update(nilfs)) |
| 2706 | set_nilfs_discontinued(nilfs); | 2709 | set_nilfs_discontinued(nilfs); |
| 2707 | } | 2710 | } |
| 2708 | goto loop; | 2711 | goto loop; |
| @@ -2797,12 +2800,9 @@ static void nilfs_segctor_write_out(struct nilfs_sc_info *sci) | |||
| 2797 | do { | 2800 | do { |
| 2798 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 2801 | struct nilfs_sb_info *sbi = sci->sc_sbi; |
| 2799 | struct nilfs_transaction_info ti; | 2802 | struct nilfs_transaction_info ti; |
| 2800 | struct nilfs_segctor_req req = { .mode = SC_LSEG_SR }; | ||
| 2801 | 2803 | ||
| 2802 | nilfs_transaction_lock(sbi, &ti, 0); | 2804 | nilfs_transaction_lock(sbi, &ti, 0); |
| 2803 | nilfs_segctor_accept(sci, &req); | 2805 | ret = nilfs_segctor_construct(sci, SC_LSEG_SR); |
| 2804 | ret = nilfs_segctor_construct(sci, &req); | ||
| 2805 | nilfs_segctor_notify(sci, &req); | ||
| 2806 | nilfs_transaction_unlock(sbi); | 2806 | nilfs_transaction_unlock(sbi); |
| 2807 | 2807 | ||
| 2808 | } while (ret && retrycount-- > 0); | 2808 | } while (ret && retrycount-- > 0); |
| @@ -2853,7 +2853,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | |||
| 2853 | * @sbi: nilfs_sb_info | 2853 | * @sbi: nilfs_sb_info |
| 2854 | * | 2854 | * |
| 2855 | * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info, | 2855 | * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info, |
| 2856 | * initilizes it, and starts the segment constructor. | 2856 | * initializes it, and starts the segment constructor. |
| 2857 | * | 2857 | * |
| 2858 | * Return Value: On success, 0 is returned. On error, one of the following | 2858 | * Return Value: On success, 0 is returned. On error, one of the following |
| 2859 | * negative error code is returned. | 2859 | * negative error code is returned. |
| @@ -2865,8 +2865,15 @@ int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi) | |||
| 2865 | struct the_nilfs *nilfs = sbi->s_nilfs; | 2865 | struct the_nilfs *nilfs = sbi->s_nilfs; |
| 2866 | int err; | 2866 | int err; |
| 2867 | 2867 | ||
| 2868 | /* Each field of nilfs_segctor is cleared through the initialization | 2868 | if (NILFS_SC(sbi)) { |
| 2869 | of super-block info */ | 2869 | /* |
| 2870 | * This happens if the filesystem was remounted | ||
| 2871 | * read/write after nilfs_error degenerated it into a | ||
| 2872 | * read-only mount. | ||
| 2873 | */ | ||
| 2874 | nilfs_detach_segment_constructor(sbi); | ||
| 2875 | } | ||
| 2876 | |||
| 2870 | sbi->s_sc_info = nilfs_segctor_new(sbi); | 2877 | sbi->s_sc_info = nilfs_segctor_new(sbi); |
| 2871 | if (!sbi->s_sc_info) | 2878 | if (!sbi->s_sc_info) |
| 2872 | return -ENOMEM; | 2879 | return -ENOMEM; |
