diff options
author | Li Hong <lihong.hi@gmail.com> | 2010-04-10 11:25:39 -0400 |
---|---|---|
committer | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-05-09 22:32:31 -0400 |
commit | fdce895ea5dd4e24edf1f4d693827349a4e5b3b4 (patch) | |
tree | 77a1a4cd496ed8459813eddf68efe8b777c3c058 | |
parent | 154ac5a83014cd6ea72e4ac5018bf8c10ee9a79e (diff) |
nilfs2: change sc_timer from a pointer to an embedded one in struct nilfs_sc_info
In nilfs_segctor_thread(), timer is a local variable allocated on stack. Its
address can't be set to sci->sc_timer and passed in several procedures.
It works now by chance, just because other procedures are called by
nilfs_segctor_thread() directly or indirectly and the stack hasn't been
deallocated yet.
Signed-off-by: Li Hong <lihong.hi@gmail.com>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
-rw-r--r-- | fs/nilfs2/segment.c | 31 | ||||
-rw-r--r-- | fs/nilfs2/segment.h | 2 |
2 files changed, 14 insertions, 19 deletions
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 89a15f4bfeb9..8b4e280b96b4 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -2159,9 +2159,9 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) | |||
2159 | static void nilfs_segctor_start_timer(struct nilfs_sc_info *sci) | 2159 | static void nilfs_segctor_start_timer(struct nilfs_sc_info *sci) |
2160 | { | 2160 | { |
2161 | spin_lock(&sci->sc_state_lock); | 2161 | spin_lock(&sci->sc_state_lock); |
2162 | if (sci->sc_timer && !(sci->sc_state & NILFS_SEGCTOR_COMMIT)) { | 2162 | if (!(sci->sc_state & NILFS_SEGCTOR_COMMIT)) { |
2163 | sci->sc_timer->expires = jiffies + sci->sc_interval; | 2163 | sci->sc_timer.expires = jiffies + sci->sc_interval; |
2164 | add_timer(sci->sc_timer); | 2164 | add_timer(&sci->sc_timer); |
2165 | sci->sc_state |= NILFS_SEGCTOR_COMMIT; | 2165 | sci->sc_state |= NILFS_SEGCTOR_COMMIT; |
2166 | } | 2166 | } |
2167 | spin_unlock(&sci->sc_state_lock); | 2167 | spin_unlock(&sci->sc_state_lock); |
@@ -2366,9 +2366,7 @@ static void nilfs_segctor_accept(struct nilfs_sc_info *sci) | |||
2366 | spin_lock(&sci->sc_state_lock); | 2366 | spin_lock(&sci->sc_state_lock); |
2367 | sci->sc_seq_accepted = sci->sc_seq_request; | 2367 | sci->sc_seq_accepted = sci->sc_seq_request; |
2368 | spin_unlock(&sci->sc_state_lock); | 2368 | spin_unlock(&sci->sc_state_lock); |
2369 | 2369 | del_timer_sync(&sci->sc_timer); | |
2370 | if (sci->sc_timer) | ||
2371 | del_timer_sync(sci->sc_timer); | ||
2372 | } | 2370 | } |
2373 | 2371 | ||
2374 | /** | 2372 | /** |
@@ -2394,9 +2392,9 @@ static void nilfs_segctor_notify(struct nilfs_sc_info *sci, int mode, int err) | |||
2394 | sci->sc_flush_request &= ~FLUSH_DAT_BIT; | 2392 | sci->sc_flush_request &= ~FLUSH_DAT_BIT; |
2395 | 2393 | ||
2396 | /* re-enable timer if checkpoint creation was not done */ | 2394 | /* re-enable timer if checkpoint creation was not done */ |
2397 | if (sci->sc_timer && (sci->sc_state & NILFS_SEGCTOR_COMMIT) && | 2395 | if ((sci->sc_state & NILFS_SEGCTOR_COMMIT) && |
2398 | time_before(jiffies, sci->sc_timer->expires)) | 2396 | time_before(jiffies, sci->sc_timer.expires)) |
2399 | add_timer(sci->sc_timer); | 2397 | add_timer(&sci->sc_timer); |
2400 | } | 2398 | } |
2401 | spin_unlock(&sci->sc_state_lock); | 2399 | spin_unlock(&sci->sc_state_lock); |
2402 | } | 2400 | } |
@@ -2575,13 +2573,10 @@ static int nilfs_segctor_thread(void *arg) | |||
2575 | { | 2573 | { |
2576 | struct nilfs_sc_info *sci = (struct nilfs_sc_info *)arg; | 2574 | struct nilfs_sc_info *sci = (struct nilfs_sc_info *)arg; |
2577 | struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs; | 2575 | struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs; |
2578 | struct timer_list timer; | ||
2579 | int timeout = 0; | 2576 | int timeout = 0; |
2580 | 2577 | ||
2581 | init_timer(&timer); | 2578 | sci->sc_timer.data = (unsigned long)current; |
2582 | timer.data = (unsigned long)current; | 2579 | sci->sc_timer.function = nilfs_construction_timeout; |
2583 | timer.function = nilfs_construction_timeout; | ||
2584 | sci->sc_timer = &timer; | ||
2585 | 2580 | ||
2586 | /* start sync. */ | 2581 | /* start sync. */ |
2587 | sci->sc_task = current; | 2582 | sci->sc_task = current; |
@@ -2630,7 +2625,7 @@ static int nilfs_segctor_thread(void *arg) | |||
2630 | should_sleep = 0; | 2625 | should_sleep = 0; |
2631 | else if (sci->sc_state & NILFS_SEGCTOR_COMMIT) | 2626 | else if (sci->sc_state & NILFS_SEGCTOR_COMMIT) |
2632 | should_sleep = time_before(jiffies, | 2627 | should_sleep = time_before(jiffies, |
2633 | sci->sc_timer->expires); | 2628 | sci->sc_timer.expires); |
2634 | 2629 | ||
2635 | if (should_sleep) { | 2630 | if (should_sleep) { |
2636 | spin_unlock(&sci->sc_state_lock); | 2631 | spin_unlock(&sci->sc_state_lock); |
@@ -2639,7 +2634,7 @@ static int nilfs_segctor_thread(void *arg) | |||
2639 | } | 2634 | } |
2640 | finish_wait(&sci->sc_wait_daemon, &wait); | 2635 | finish_wait(&sci->sc_wait_daemon, &wait); |
2641 | timeout = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) && | 2636 | timeout = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) && |
2642 | time_after_eq(jiffies, sci->sc_timer->expires)); | 2637 | time_after_eq(jiffies, sci->sc_timer.expires)); |
2643 | 2638 | ||
2644 | if (nilfs_sb_dirty(nilfs) && nilfs_sb_need_update(nilfs)) | 2639 | if (nilfs_sb_dirty(nilfs) && nilfs_sb_need_update(nilfs)) |
2645 | set_nilfs_discontinued(nilfs); | 2640 | set_nilfs_discontinued(nilfs); |
@@ -2648,8 +2643,6 @@ static int nilfs_segctor_thread(void *arg) | |||
2648 | 2643 | ||
2649 | end_thread: | 2644 | end_thread: |
2650 | spin_unlock(&sci->sc_state_lock); | 2645 | spin_unlock(&sci->sc_state_lock); |
2651 | del_timer_sync(sci->sc_timer); | ||
2652 | sci->sc_timer = NULL; | ||
2653 | 2646 | ||
2654 | /* end sync. */ | 2647 | /* end sync. */ |
2655 | sci->sc_task = NULL; | 2648 | sci->sc_task = NULL; |
@@ -2708,6 +2701,7 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi) | |||
2708 | INIT_LIST_HEAD(&sci->sc_write_logs); | 2701 | INIT_LIST_HEAD(&sci->sc_write_logs); |
2709 | INIT_LIST_HEAD(&sci->sc_gc_inodes); | 2702 | INIT_LIST_HEAD(&sci->sc_gc_inodes); |
2710 | INIT_LIST_HEAD(&sci->sc_copied_buffers); | 2703 | INIT_LIST_HEAD(&sci->sc_copied_buffers); |
2704 | init_timer(&sci->sc_timer); | ||
2711 | 2705 | ||
2712 | sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT; | 2706 | sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT; |
2713 | sci->sc_mjcp_freq = HZ * NILFS_SC_DEFAULT_SR_FREQ; | 2707 | sci->sc_mjcp_freq = HZ * NILFS_SC_DEFAULT_SR_FREQ; |
@@ -2774,6 +2768,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) | |||
2774 | 2768 | ||
2775 | down_write(&sbi->s_nilfs->ns_segctor_sem); | 2769 | down_write(&sbi->s_nilfs->ns_segctor_sem); |
2776 | 2770 | ||
2771 | del_timer_sync(&sci->sc_timer); | ||
2777 | kfree(sci); | 2772 | kfree(sci); |
2778 | } | 2773 | } |
2779 | 2774 | ||
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h index 7aca76532683..dca142361ccf 100644 --- a/fs/nilfs2/segment.h +++ b/fs/nilfs2/segment.h | |||
@@ -177,7 +177,7 @@ struct nilfs_sc_info { | |||
177 | unsigned long sc_lseg_stime; /* in 1/HZ seconds */ | 177 | unsigned long sc_lseg_stime; /* in 1/HZ seconds */ |
178 | unsigned long sc_watermark; | 178 | unsigned long sc_watermark; |
179 | 179 | ||
180 | struct timer_list *sc_timer; | 180 | struct timer_list sc_timer; |
181 | struct task_struct *sc_task; | 181 | struct task_struct *sc_task; |
182 | }; | 182 | }; |
183 | 183 | ||