aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/ubifs/io.c34
-rw-r--r--fs/ubifs/super.c6
-rw-r--r--fs/ubifs/ubifs.h13
3 files changed, 32 insertions, 21 deletions
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index e8e632a1dcdf..bc5857199ec2 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 */
296static void wbuf_timer_callback_nolock(unsigned long data) 296static 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 */
309static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) 310static 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:
825int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) 825int 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
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index b9b051a4c01e..91c91cb7a599 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -799,7 +799,7 @@ static int alloc_wbufs(struct ubifs_info *c)
799 * does not need to be synchronized by timer. 799 * does not need to be synchronized by timer.
800 */ 800 */
801 c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM; 801 c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM;
802 c->jheads[GCHD].wbuf.timeout = 0; 802 c->jheads[GCHD].wbuf.softlimit = ktime_set(0, 0);
803 803
804 return 0; 804 return 0;
805} 805}
@@ -1695,7 +1695,7 @@ static void ubifs_remount_ro(struct ubifs_info *c)
1695 1695
1696 for (i = 0; i < c->jhead_cnt; i++) { 1696 for (i = 0; i < c->jhead_cnt; i++) {
1697 ubifs_wbuf_sync(&c->jheads[i].wbuf); 1697 ubifs_wbuf_sync(&c->jheads[i].wbuf);
1698 del_timer_sync(&c->jheads[i].wbuf.timer); 1698 hrtimer_cancel(&c->jheads[i].wbuf.timer);
1699 } 1699 }
1700 1700
1701 c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY); 1701 c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY);
@@ -1755,7 +1755,7 @@ static void ubifs_put_super(struct super_block *sb)
1755 if (c->jheads) 1755 if (c->jheads)
1756 for (i = 0; i < c->jhead_cnt; i++) { 1756 for (i = 0; i < c->jhead_cnt; i++) {
1757 ubifs_wbuf_sync(&c->jheads[i].wbuf); 1757 ubifs_wbuf_sync(&c->jheads[i].wbuf);
1758 del_timer_sync(&c->jheads[i].wbuf.timer); 1758 hrtimer_cancel(&c->jheads[i].wbuf.timer);
1759 } 1759 }
1760 1760
1761 /* 1761 /*
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 0a8341e14088..1bf01d820066 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -95,8 +95,8 @@
95 */ 95 */
96#define BGT_NAME_PATTERN "ubifs_bgt%d_%d" 96#define BGT_NAME_PATTERN "ubifs_bgt%d_%d"
97 97
98/* Default write-buffer synchronization timeout (5 secs) */ 98/* Default write-buffer synchronization timeout in seconds */
99#define DEFAULT_WBUF_TIMEOUT (5 * HZ) 99#define DEFAULT_WBUF_TIMEOUT_SECS 5
100 100
101/* Maximum possible inode number (only 32-bit inodes are supported now) */ 101/* Maximum possible inode number (only 32-bit inodes are supported now) */
102#define MAX_INUM 0xFFFFFFFF 102#define MAX_INUM 0xFFFFFFFF
@@ -650,8 +650,10 @@ typedef int (*ubifs_lpt_scan_callback)(struct ubifs_info *c,
650 * @io_mutex: serializes write-buffer I/O 650 * @io_mutex: serializes write-buffer I/O
651 * @lock: serializes @buf, @lnum, @offs, @avail, @used, @next_ino and @inodes 651 * @lock: serializes @buf, @lnum, @offs, @avail, @used, @next_ino and @inodes
652 * fields 652 * fields
653 * @softlimit: soft write-buffer timeout interval
654 * @delta: hard and soft timeouts delta (the timer expire inteval is @softlimit
655 * and @softlimit + @delta)
653 * @timer: write-buffer timer 656 * @timer: write-buffer timer
654 * @timeout: timer expire interval in jiffies
655 * @need_sync: it is set if its timer expired and needs sync 657 * @need_sync: it is set if its timer expired and needs sync
656 * @next_ino: points to the next position of the following inode number 658 * @next_ino: points to the next position of the following inode number
657 * @inodes: stores the inode numbers of the nodes which are in wbuf 659 * @inodes: stores the inode numbers of the nodes which are in wbuf
@@ -678,8 +680,9 @@ struct ubifs_wbuf {
678 int (*sync_callback)(struct ubifs_info *c, int lnum, int free, int pad); 680 int (*sync_callback)(struct ubifs_info *c, int lnum, int free, int pad);
679 struct mutex io_mutex; 681 struct mutex io_mutex;
680 spinlock_t lock; 682 spinlock_t lock;
681 struct timer_list timer; 683 ktime_t softlimit;
682 int timeout; 684 unsigned long long delta;
685 struct hrtimer timer;
683 int need_sync; 686 int need_sync;
684 int next_ino; 687 int next_ino;
685 ino_t *inodes; 688 ino_t *inodes;