From e3dc5a665d39112e98cfd5bbc7fda2963c00c12c Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 22 Jun 2009 17:31:09 +0300 Subject: UBIFS: fix integer overflow warning Fix the following warning: fs/ubifs/io.c: In function 'ubifs_wbuf_init': fs/ubifs/io.c:860: warning: integer overflow in expression And limit maximum hrtimer delta to ULONG_MAX because the argument is 'unsigned long'. Signed-off-by: Adrian Hunter Signed-off-by: Artem Bityutskiy --- fs/ubifs/io.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'fs/ubifs/io.c') diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index bc5857199ec..2d41ae1d660 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c @@ -857,7 +857,9 @@ int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) * and hard limits. */ hardlimit = ktime_set(DEFAULT_WBUF_TIMEOUT_SECS, 0); - wbuf->delta = (DEFAULT_WBUF_TIMEOUT_SECS * NSEC_PER_SEC) * 2 / 10; + wbuf->delta = DEFAULT_WBUF_TIMEOUT_SECS * 1000000000ULL * 2 / 10; + if (wbuf->delta > ULONG_MAX) + wbuf->delta = ULONG_MAX; wbuf->softlimit = ktime_sub_ns(hardlimit, wbuf->delta); hrtimer_set_expires_range_ns(&wbuf->timer, wbuf->softlimit, wbuf->delta); -- cgit v1.2.3-70-g09d2 From 70aee2f153972f70fad5f7025134fec063f9efbe Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 18 Jun 2009 13:37:15 +0300 Subject: UBIFS: improve debugging messaged 1. Make the I/O debugging message print the journal head number. 2. Add prints to timer functions. Signed-off-by: Artem Bityutskiy --- fs/ubifs/io.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'fs/ubifs/io.c') diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index 2d41ae1d660..2ef689a9a36 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c @@ -297,6 +297,7 @@ static enum hrtimer_restart wbuf_timer_callback_nolock(struct hrtimer *timer) { struct ubifs_wbuf *wbuf = container_of(timer, struct ubifs_wbuf, timer); + dbg_io("jhead %d", wbuf->jhead); wbuf->need_sync = 1; wbuf->c->need_wbuf_sync = 1; ubifs_wake_up_bgt(wbuf->c); @@ -313,6 +314,9 @@ static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) if (!ktime_to_ns(wbuf->softlimit)) return; + dbg_io("set timer for jhead %d, %llu-%llu millisecs", wbuf->jhead, + ktime_to_ns(wbuf->softlimit)/USEC_PER_SEC, + (ktime_to_ns(wbuf->softlimit) + wbuf->delta)/USEC_PER_SEC); hrtimer_start_range_ns(&wbuf->timer, wbuf->softlimit, wbuf->delta, HRTIMER_MODE_REL); } @@ -349,8 +353,8 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf) /* Write-buffer is empty or not seeked */ return 0; - dbg_io("LEB %d:%d, %d bytes", - wbuf->lnum, wbuf->offs, wbuf->used); + dbg_io("LEB %d:%d, %d bytes, jhead %d", + wbuf->lnum, wbuf->offs, wbuf->used, wbuf->jhead); ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY)); ubifs_assert(!(wbuf->avail & 7)); ubifs_assert(wbuf->offs + c->min_io_size <= c->leb_size); @@ -399,7 +403,7 @@ int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, { const struct ubifs_info *c = wbuf->c; - dbg_io("LEB %d:%d", lnum, offs); + dbg_io("LEB %d:%d, jhead %d", lnum, offs, wbuf->jhead); ubifs_assert(lnum >= 0 && lnum < c->leb_cnt); ubifs_assert(offs >= 0 && offs <= c->leb_size); ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7)); @@ -506,9 +510,9 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) struct ubifs_info *c = wbuf->c; int err, written, n, aligned_len = ALIGN(len, 8), offs; - dbg_io("%d bytes (%s) to wbuf at LEB %d:%d", len, - dbg_ntype(((struct ubifs_ch *)buf)->node_type), wbuf->lnum, - wbuf->offs + wbuf->used); + dbg_io("%d bytes (%s) to jhead %d wbuf at LEB %d:%d", len, + dbg_ntype(((struct ubifs_ch *)buf)->node_type), wbuf->jhead, + wbuf->lnum, wbuf->offs + wbuf->used); ubifs_assert(len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt); ubifs_assert(wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0); ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size); @@ -533,8 +537,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) memcpy(wbuf->buf + wbuf->used, buf, len); if (aligned_len == wbuf->avail) { - dbg_io("flush wbuf to LEB %d:%d", wbuf->lnum, - wbuf->offs); + dbg_io("flush jhead %d wbuf to LEB %d:%d", + wbuf->jhead, wbuf->lnum, wbuf->offs); err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, c->min_io_size, wbuf->dtype); @@ -562,7 +566,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) * minimal I/O unit. We have to fill and flush write-buffer and switch * to the next min. I/O unit. */ - dbg_io("flush wbuf to LEB %d:%d", wbuf->lnum, wbuf->offs); + dbg_io("flush jhead %d wbuf to LEB %d:%d", + wbuf->jhead, wbuf->lnum, wbuf->offs); memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail); err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, c->min_io_size, wbuf->dtype); @@ -695,7 +700,8 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, int err, rlen, overlap; struct ubifs_ch *ch = buf; - dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len); + dbg_io("LEB %d:%d, %s, length %d, jhead %d", lnum, offs, + dbg_ntype(type), len, wbuf->jhead); ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0); ubifs_assert(!(offs & 7) && offs < c->leb_size); ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT); -- cgit v1.2.3-70-g09d2 From 0b335b9d7d5f0b832e90ac469480789c07be80ad Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 23 Jun 2009 12:30:43 +0300 Subject: UBIFS: slightly optimize write-buffer timer usage This patch adds the following minor optimization: 1. If write-buffer does not use the timer, indicate it with the wbuf->no_timer variable, instead of using the wbuf->softlimit variable. This is better because wbuf->softlimit is of ktime_t type, and the ktime_to_ns function contains 64-bit multiplication. 2. Do not call the 'hrtimer_cancel()' function for write-buffers which do not use timers. 3. Do not cancel the timer in 'ubifs_put_super()' because the synchronization function does this. This patch also removes a confusing comment. Signed-off-by: Artem Bityutskiy --- fs/ubifs/io.c | 9 +++------ fs/ubifs/super.c | 6 ++---- fs/ubifs/ubifs.h | 6 ++++-- 3 files changed, 9 insertions(+), 12 deletions(-) (limited to 'fs/ubifs/io.c') diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index 2ef689a9a36..9fcf6c38c1b 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c @@ -312,7 +312,7 @@ static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) { ubifs_assert(!hrtimer_active(&wbuf->timer)); - if (!ktime_to_ns(wbuf->softlimit)) + if (wbuf->no_timer) return; dbg_io("set timer for jhead %d, %llu-%llu millisecs", wbuf->jhead, ktime_to_ns(wbuf->softlimit)/USEC_PER_SEC, @@ -327,11 +327,8 @@ static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) */ static void cancel_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) { - /* - * If the syncer is waiting for the lock (from the background thread's - * context) and another task is changing write-buffer then the syncing - * should be canceled. - */ + if (wbuf->no_timer) + return; wbuf->need_sync = 0; hrtimer_cancel(&wbuf->timer); } diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 79fad43f3c5..5bb272c56a9 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -797,7 +797,7 @@ static int alloc_wbufs(struct ubifs_info *c) * does not need to be synchronized by timer. */ c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM; - c->jheads[GCHD].wbuf.softlimit = ktime_set(0, 0); + c->jheads[GCHD].wbuf.no_timer = 1; return 0; } @@ -1754,10 +1754,8 @@ static void ubifs_put_super(struct super_block *sb) /* Synchronize write-buffers */ if (c->jheads) - for (i = 0; i < c->jhead_cnt; i++) { + for (i = 0; i < c->jhead_cnt; i++) ubifs_wbuf_sync(&c->jheads[i].wbuf); - hrtimer_cancel(&c->jheads[i].wbuf.timer); - } /* * On fatal errors c->ro_media is set to 1, in which case we do diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 1bf01d82006..97bc9d09d54 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -654,7 +654,8 @@ typedef int (*ubifs_lpt_scan_callback)(struct ubifs_info *c, * @delta: hard and soft timeouts delta (the timer expire inteval is @softlimit * and @softlimit + @delta) * @timer: write-buffer timer - * @need_sync: it is set if its timer expired and needs sync + * @no_timer: non-zero if this write-buffer does not timer + * @need_sync: non-zero if its timer expired and needs sync * @next_ino: points to the next position of the following inode number * @inodes: stores the inode numbers of the nodes which are in wbuf * @@ -683,7 +684,8 @@ struct ubifs_wbuf { ktime_t softlimit; unsigned long long delta; struct hrtimer timer; - int need_sync; + unsigned int no_timer:1; + unsigned int need_sync:1; int next_ino; ino_t *inodes; }; -- cgit v1.2.3-70-g09d2 From 2a35a3a8ab3e94afd631ed4b45878ceb98f7ab28 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 23 Jun 2009 20:26:33 +0300 Subject: UBIFS: set write-buffer timout to 3-5 seconds This patch cleans up write-buffer timeout initialization and sets it to 3-5 interval. Signed-off-by: Artem Bityutskiy --- fs/ubifs/io.c | 17 ++++------------- fs/ubifs/ubifs.h | 5 +++-- 2 files changed, 7 insertions(+), 15 deletions(-) (limited to 'fs/ubifs/io.c') diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index 9fcf6c38c1b..48d0af94b26 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c @@ -828,7 +828,6 @@ out: int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) { size_t size; - ktime_t hardlimit; wbuf->buf = kmalloc(c->min_io_size, GFP_KERNEL); if (!wbuf->buf) @@ -854,18 +853,10 @@ int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) hrtimer_init(&wbuf->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); wbuf->timer.function = wbuf_timer_callback_nolock; - /* - * Make write-buffer soft limit to be 20% of the hard limit. The - * write-buffer timer is allowed to expire any time between the soft - * and hard limits. - */ - hardlimit = ktime_set(DEFAULT_WBUF_TIMEOUT_SECS, 0); - wbuf->delta = DEFAULT_WBUF_TIMEOUT_SECS * 1000000000ULL * 2 / 10; - if (wbuf->delta > ULONG_MAX) - wbuf->delta = ULONG_MAX; - wbuf->softlimit = ktime_sub_ns(hardlimit, wbuf->delta); - hrtimer_set_expires_range_ns(&wbuf->timer, wbuf->softlimit, - wbuf->delta); + wbuf->softlimit = ktime_set(WBUF_TIMEOUT_SOFTLIMIT, 0); + wbuf->delta = WBUF_TIMEOUT_HARDLIMIT - WBUF_TIMEOUT_SOFTLIMIT; + wbuf->delta *= 1000000000ULL; + ubifs_assert(wbuf->delta <= ULONG_MAX); return 0; } diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 97bc9d09d54..c3a707d458a 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -95,8 +95,9 @@ */ #define BGT_NAME_PATTERN "ubifs_bgt%d_%d" -/* Default write-buffer synchronization timeout in seconds */ -#define DEFAULT_WBUF_TIMEOUT_SECS 5 +/* Write-buffer synchronization timeout interval in seconds */ +#define WBUF_TIMEOUT_SOFTLIMIT 3 +#define WBUF_TIMEOUT_HARDLIMIT 5 /* Maximum possible inode number (only 32-bit inodes are supported now) */ #define MAX_INUM 0xFFFFFFFF -- cgit v1.2.3-70-g09d2 From cb54ef8b1304fe25f3d57031e0f85558a043239f Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 23 Jun 2009 20:30:32 +0300 Subject: UBIFS: few spelling fixes Signed-off-by: Artem Bityutskiy --- fs/ubifs/io.c | 6 +++--- fs/ubifs/super.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'fs/ubifs/io.c') diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index 48d0af94b26..7e4267ecfa5 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c @@ -391,7 +391,7 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf) * @offs: logical eraseblock offset to seek to * @dtype: data type * - * This function targets the write buffer to logical eraseblock @lnum:@offs. + * This function targets the write-buffer to logical eraseblock @lnum:@offs. * The write-buffer is synchronized if it is not empty. Returns zero in case of * success and a negative error code in case of failure. */ @@ -822,7 +822,7 @@ out: * @c: UBIFS file-system description object * @wbuf: write-buffer to initialize * - * This function initializes write buffer. Returns zero in case of success + * This function initializes write-buffer. Returns zero in case of success * %-ENOMEM in case of failure. */ int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) @@ -862,7 +862,7 @@ int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) /** * ubifs_wbuf_add_ino_nolock - add an inode number into the wbuf inode array. - * @wbuf: the write-buffer whereto add + * @wbuf: the write-buffer where to add * @inum: the inode number * * This function adds an inode number to the inode array of the write-buffer. diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 5bb272c56a9..76405c457a3 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -986,7 +986,7 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options, switch (token) { /* * %Opt_fast_unmount and %Opt_norm_unmount options are ignored. - * We accepte them in order to be backware-compatible. But this + * We accept them in order to be backward-compatible. But this * should be removed at some point. */ case Opt_fast_unmount: -- cgit v1.2.3-70-g09d2 From 44737589442bf69d811e003d9d0064b8fc1541d6 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 24 Jun 2009 10:15:12 +0300 Subject: UBIFS: fix 64-bit divisions in debug print Signed-off-by: Adrian Hunter --- fs/ubifs/io.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'fs/ubifs/io.c') diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index 7e4267ecfa5..762a7d6cec7 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c @@ -315,8 +315,9 @@ static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) if (wbuf->no_timer) return; dbg_io("set timer for jhead %d, %llu-%llu millisecs", wbuf->jhead, - ktime_to_ns(wbuf->softlimit)/USEC_PER_SEC, - (ktime_to_ns(wbuf->softlimit) + wbuf->delta)/USEC_PER_SEC); + div_u64(ktime_to_ns(wbuf->softlimit), USEC_PER_SEC), + div_u64(ktime_to_ns(wbuf->softlimit) + wbuf->delta, + USEC_PER_SEC)); hrtimer_start_range_ns(&wbuf->timer, wbuf->softlimit, wbuf->delta, HRTIMER_MODE_REL); } -- cgit v1.2.3-70-g09d2