aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nilfs2/segment.c79
-rw-r--r--fs/nilfs2/segment.h2
2 files changed, 40 insertions, 41 deletions
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index ab439a7ef2d8..fa4abfc22d33 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -2425,43 +2425,43 @@ int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode,
2425 return err; 2425 return err;
2426} 2426}
2427 2427
2428struct 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 */ 2428#define FLUSH_FILE_BIT (0x1) /* data file only */
2436#define FLUSH_DAT_BIT (1 << NILFS_DAT_INO) /* DAT only */ 2429#define FLUSH_DAT_BIT (1 << NILFS_DAT_INO) /* DAT only */
2437 2430
2438static void nilfs_segctor_accept(struct nilfs_sc_info *sci, 2431/**
2439 struct nilfs_segctor_req *req) 2432 * nilfs_segctor_accept - record accepted sequence count of log-write requests
2433 * @sci: segment constructor object
2434 */
2435static void nilfs_segctor_accept(struct nilfs_sc_info *sci)
2440{ 2436{
2441 req->sc_err = req->sb_err = 0;
2442 spin_lock(&sci->sc_state_lock); 2437 spin_lock(&sci->sc_state_lock);
2443 req->seq_accepted = sci->sc_seq_request; 2438 sci->sc_seq_accepted = sci->sc_seq_request;
2444 spin_unlock(&sci->sc_state_lock); 2439 spin_unlock(&sci->sc_state_lock);
2445 2440
2446 if (sci->sc_timer) 2441 if (sci->sc_timer)
2447 del_timer_sync(sci->sc_timer); 2442 del_timer_sync(sci->sc_timer);
2448} 2443}
2449 2444
2450static void nilfs_segctor_notify(struct nilfs_sc_info *sci, 2445/**
2451 struct nilfs_segctor_req *req) 2446 * nilfs_segctor_notify - notify the result of request to caller threads
2447 * @sci: segment constructor object
2448 * @mode: mode of log forming
2449 * @err: error code to be notified
2450 */
2451static void nilfs_segctor_notify(struct nilfs_sc_info *sci, int mode, int err)
2452{ 2452{
2453 /* Clear requests (even when the construction failed) */ 2453 /* Clear requests (even when the construction failed) */
2454 spin_lock(&sci->sc_state_lock); 2454 spin_lock(&sci->sc_state_lock);
2455 2455
2456 if (req->mode == SC_LSEG_SR) { 2456 if (mode == SC_LSEG_SR) {
2457 sci->sc_state &= ~NILFS_SEGCTOR_COMMIT; 2457 sci->sc_state &= ~NILFS_SEGCTOR_COMMIT;
2458 sci->sc_seq_done = req->seq_accepted; 2458 sci->sc_seq_done = sci->sc_seq_accepted;
2459 nilfs_segctor_wakeup(sci, req->sc_err ? : req->sb_err); 2459 nilfs_segctor_wakeup(sci, err);
2460 sci->sc_flush_request = 0; 2460 sci->sc_flush_request = 0;
2461 } else { 2461 } else {
2462 if (req->mode == SC_FLUSH_FILE) 2462 if (mode == SC_FLUSH_FILE)
2463 sci->sc_flush_request &= ~FLUSH_FILE_BIT; 2463 sci->sc_flush_request &= ~FLUSH_FILE_BIT;
2464 else if (req->mode == SC_FLUSH_DAT) 2464 else if (mode == SC_FLUSH_DAT)
2465 sci->sc_flush_request &= ~FLUSH_DAT_BIT; 2465 sci->sc_flush_request &= ~FLUSH_DAT_BIT;
2466 2466
2467 /* re-enable timer if checkpoint creation was not done */ 2467 /* re-enable timer if checkpoint creation was not done */
@@ -2472,30 +2472,37 @@ static void nilfs_segctor_notify(struct nilfs_sc_info *sci,
2472 spin_unlock(&sci->sc_state_lock); 2472 spin_unlock(&sci->sc_state_lock);
2473} 2473}
2474 2474
2475static int nilfs_segctor_construct(struct nilfs_sc_info *sci, 2475/**
2476 struct nilfs_segctor_req *req) 2476 * nilfs_segctor_construct - form logs and write them to disk
2477 * @sci: segment constructor object
2478 * @mode: mode of log forming
2479 */
2480static int nilfs_segctor_construct(struct nilfs_sc_info *sci, int mode)
2477{ 2481{
2478 struct nilfs_sb_info *sbi = sci->sc_sbi; 2482 struct nilfs_sb_info *sbi = sci->sc_sbi;
2479 struct the_nilfs *nilfs = sbi->s_nilfs; 2483 struct the_nilfs *nilfs = sbi->s_nilfs;
2480 int err = 0; 2484 int err = 0;
2481 2485
2486 nilfs_segctor_accept(sci);
2487
2482 if (nilfs_discontinued(nilfs)) 2488 if (nilfs_discontinued(nilfs))
2483 req->mode = SC_LSEG_SR; 2489 mode = SC_LSEG_SR;
2484 if (!nilfs_segctor_confirm(sci)) { 2490 if (!nilfs_segctor_confirm(sci))
2485 err = nilfs_segctor_do_construct(sci, req->mode); 2491 err = nilfs_segctor_do_construct(sci, mode);
2486 req->sc_err = err; 2492
2487 }
2488 if (likely(!err)) { 2493 if (likely(!err)) {
2489 if (req->mode != SC_FLUSH_DAT) 2494 if (mode != SC_FLUSH_DAT)
2490 atomic_set(&nilfs->ns_ndirtyblks, 0); 2495 atomic_set(&nilfs->ns_ndirtyblks, 0);
2491 if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) && 2496 if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) &&
2492 nilfs_discontinued(nilfs)) { 2497 nilfs_discontinued(nilfs)) {
2493 down_write(&nilfs->ns_sem); 2498 down_write(&nilfs->ns_sem);
2494 req->sb_err = nilfs_commit_super(sbi, 2499 err = nilfs_commit_super(
2495 nilfs_altsb_need_update(nilfs)); 2500 sbi, nilfs_altsb_need_update(nilfs));
2496 up_write(&nilfs->ns_sem); 2501 up_write(&nilfs->ns_sem);
2497 } 2502 }
2498 } 2503 }
2504
2505 nilfs_segctor_notify(sci, mode, err);
2499 return err; 2506 return err;
2500} 2507}
2501 2508
@@ -2526,7 +2533,6 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
2526 struct nilfs_sc_info *sci = NILFS_SC(sbi); 2533 struct nilfs_sc_info *sci = NILFS_SC(sbi);
2527 struct the_nilfs *nilfs = sbi->s_nilfs; 2534 struct the_nilfs *nilfs = sbi->s_nilfs;
2528 struct nilfs_transaction_info ti; 2535 struct nilfs_transaction_info ti;
2529 struct nilfs_segctor_req req = { .mode = SC_LSEG_SR };
2530 int err; 2536 int err;
2531 2537
2532 if (unlikely(!sci)) 2538 if (unlikely(!sci))
@@ -2547,10 +2553,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); 2553 list_splice_tail_init(&nilfs->ns_gc_inodes, &sci->sc_gc_inodes);
2548 2554
2549 for (;;) { 2555 for (;;) {
2550 nilfs_segctor_accept(sci, &req); 2556 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); 2557 nilfs_remove_written_gcinodes(nilfs, &sci->sc_gc_inodes);
2553 nilfs_segctor_notify(sci, &req);
2554 2558
2555 if (likely(!err)) 2559 if (likely(!err))
2556 break; 2560 break;
@@ -2583,13 +2587,9 @@ static void nilfs_segctor_thread_construct(struct nilfs_sc_info *sci, int mode)
2583{ 2587{
2584 struct nilfs_sb_info *sbi = sci->sc_sbi; 2588 struct nilfs_sb_info *sbi = sci->sc_sbi;
2585 struct nilfs_transaction_info ti; 2589 struct nilfs_transaction_info ti;
2586 struct nilfs_segctor_req req = { .mode = mode };
2587 2590
2588 nilfs_transaction_lock(sbi, &ti, 0); 2591 nilfs_transaction_lock(sbi, &ti, 0);
2589 2592 nilfs_segctor_construct(sci, mode);
2590 nilfs_segctor_accept(sci, &req);
2591 nilfs_segctor_construct(sci, &req);
2592 nilfs_segctor_notify(sci, &req);
2593 2593
2594 /* 2594 /*
2595 * Unclosed segment should be retried. We do this using sc_timer. 2595 * Unclosed segment should be retried. We do this using sc_timer.
@@ -2807,12 +2807,9 @@ static void nilfs_segctor_write_out(struct nilfs_sc_info *sci)
2807 do { 2807 do {
2808 struct nilfs_sb_info *sbi = sci->sc_sbi; 2808 struct nilfs_sb_info *sbi = sci->sc_sbi;
2809 struct nilfs_transaction_info ti; 2809 struct nilfs_transaction_info ti;
2810 struct nilfs_segctor_req req = { .mode = SC_LSEG_SR };
2811 2810
2812 nilfs_transaction_lock(sbi, &ti, 0); 2811 nilfs_transaction_lock(sbi, &ti, 0);
2813 nilfs_segctor_accept(sci, &req); 2812 ret = nilfs_segctor_construct(sci, SC_LSEG_SR);
2814 ret = nilfs_segctor_construct(sci, &req);
2815 nilfs_segctor_notify(sci, &req);
2816 nilfs_transaction_unlock(sbi); 2813 nilfs_transaction_unlock(sbi);
2817 2814
2818 } while (ret && retrycount-- > 0); 2815 } while (ret && retrycount-- > 0);
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h
index 3d3ab2f9864c..3155e0c7f415 100644
--- a/fs/nilfs2/segment.h
+++ b/fs/nilfs2/segment.h
@@ -116,6 +116,7 @@ struct nilfs_segsum_pointer {
116 * @sc_wait_daemon: Daemon wait queue 116 * @sc_wait_daemon: Daemon wait queue
117 * @sc_wait_task: Start/end wait queue to control segctord task 117 * @sc_wait_task: Start/end wait queue to control segctord task
118 * @sc_seq_request: Request counter 118 * @sc_seq_request: Request counter
119 * @sc_seq_accept: Accepted request count
119 * @sc_seq_done: Completion counter 120 * @sc_seq_done: Completion counter
120 * @sc_sync: Request of explicit sync operation 121 * @sc_sync: Request of explicit sync operation
121 * @sc_interval: Timeout value of background construction 122 * @sc_interval: Timeout value of background construction
@@ -169,6 +170,7 @@ struct nilfs_sc_info {
169 wait_queue_head_t sc_wait_task; 170 wait_queue_head_t sc_wait_task;
170 171
171 __u32 sc_seq_request; 172 __u32 sc_seq_request;
173 __u32 sc_seq_accepted;
172 __u32 sc_seq_done; 174 __u32 sc_seq_done;
173 175
174 int sc_sync; 176 int sc_sync;