diff options
| -rw-r--r-- | fs/ubifs/io.c | 34 | ||||
| -rw-r--r-- | fs/ubifs/super.c | 6 | ||||
| -rw-r--r-- | fs/ubifs/ubifs.h | 13 |
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 | */ |
| 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 | ||
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; |
