diff options
Diffstat (limited to 'fs/ubifs/io.c')
-rw-r--r-- | fs/ubifs/io.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index e8e632a1dcd..bc5857199ec 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c | |||
@@ -293,13 +293,14 @@ void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last) | |||
293 | * | 293 | * |
294 | * This function is called when the write-buffer timer expires. | 294 | * This function is called when the write-buffer timer expires. |
295 | */ | 295 | */ |
296 | static void wbuf_timer_callback_nolock(unsigned long data) | 296 | static enum hrtimer_restart wbuf_timer_callback_nolock(struct hrtimer *timer) |
297 | { | 297 | { |
298 | struct ubifs_wbuf *wbuf = (struct ubifs_wbuf *)data; | 298 | struct ubifs_wbuf *wbuf = container_of(timer, struct ubifs_wbuf, timer); |
299 | 299 | ||
300 | wbuf->need_sync = 1; | 300 | wbuf->need_sync = 1; |
301 | wbuf->c->need_wbuf_sync = 1; | 301 | wbuf->c->need_wbuf_sync = 1; |
302 | ubifs_wake_up_bgt(wbuf->c); | 302 | ubifs_wake_up_bgt(wbuf->c); |
303 | return HRTIMER_NORESTART; | ||
303 | } | 304 | } |
304 | 305 | ||
305 | /** | 306 | /** |
@@ -308,13 +309,12 @@ static void wbuf_timer_callback_nolock(unsigned long data) | |||
308 | */ | 309 | */ |
309 | static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | 310 | static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) |
310 | { | 311 | { |
311 | ubifs_assert(!timer_pending(&wbuf->timer)); | 312 | ubifs_assert(!hrtimer_active(&wbuf->timer)); |
312 | 313 | ||
313 | if (!wbuf->timeout) | 314 | if (!ktime_to_ns(wbuf->softlimit)) |
314 | return; | 315 | return; |
315 | 316 | hrtimer_start_range_ns(&wbuf->timer, wbuf->softlimit, wbuf->delta, | |
316 | wbuf->timer.expires = jiffies + wbuf->timeout; | 317 | HRTIMER_MODE_REL); |
317 | add_timer(&wbuf->timer); | ||
318 | } | 318 | } |
319 | 319 | ||
320 | /** | 320 | /** |
@@ -329,7 +329,7 @@ static void cancel_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | |||
329 | * should be canceled. | 329 | * should be canceled. |
330 | */ | 330 | */ |
331 | wbuf->need_sync = 0; | 331 | wbuf->need_sync = 0; |
332 | del_timer(&wbuf->timer); | 332 | hrtimer_cancel(&wbuf->timer); |
333 | } | 333 | } |
334 | 334 | ||
335 | /** | 335 | /** |
@@ -825,6 +825,7 @@ out: | |||
825 | int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) | 825 | int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) |
826 | { | 826 | { |
827 | size_t size; | 827 | size_t size; |
828 | ktime_t hardlimit; | ||
828 | 829 | ||
829 | wbuf->buf = kmalloc(c->min_io_size, GFP_KERNEL); | 830 | wbuf->buf = kmalloc(c->min_io_size, GFP_KERNEL); |
830 | if (!wbuf->buf) | 831 | if (!wbuf->buf) |
@@ -845,14 +846,21 @@ int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) | |||
845 | wbuf->sync_callback = NULL; | 846 | wbuf->sync_callback = NULL; |
846 | mutex_init(&wbuf->io_mutex); | 847 | mutex_init(&wbuf->io_mutex); |
847 | spin_lock_init(&wbuf->lock); | 848 | spin_lock_init(&wbuf->lock); |
848 | |||
849 | wbuf->c = c; | 849 | wbuf->c = c; |
850 | init_timer(&wbuf->timer); | ||
851 | wbuf->timer.function = wbuf_timer_callback_nolock; | ||
852 | wbuf->timer.data = (unsigned long)wbuf; | ||
853 | wbuf->timeout = DEFAULT_WBUF_TIMEOUT; | ||
854 | wbuf->next_ino = 0; | 850 | wbuf->next_ino = 0; |
855 | 851 | ||
852 | hrtimer_init(&wbuf->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
853 | wbuf->timer.function = wbuf_timer_callback_nolock; | ||
854 | /* | ||
855 | * Make write-buffer soft limit to be 20% of the hard limit. The | ||
856 | * write-buffer timer is allowed to expire any time between the soft | ||
857 | * and hard limits. | ||
858 | */ | ||
859 | hardlimit = ktime_set(DEFAULT_WBUF_TIMEOUT_SECS, 0); | ||
860 | wbuf->delta = (DEFAULT_WBUF_TIMEOUT_SECS * NSEC_PER_SEC) * 2 / 10; | ||
861 | wbuf->softlimit = ktime_sub_ns(hardlimit, wbuf->delta); | ||
862 | hrtimer_set_expires_range_ns(&wbuf->timer, wbuf->softlimit, | ||
863 | wbuf->delta); | ||
856 | return 0; | 864 | return 0; |
857 | } | 865 | } |
858 | 866 | ||