diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-07-10 22:14:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-07-10 22:14:48 -0400 |
commit | 44c695b13bee558c73a89bc79f6253a4ba637386 (patch) | |
tree | 4ffcef19658771ca47c0068b79951fdd91012853 /fs | |
parent | eee33abe592da1763550e6e55b1cfb7fdc6a9b4c (diff) | |
parent | 061125476039a9a998878468a6abe235b1cee347 (diff) |
Merge branch 'linux-next' of git://git.infradead.org/ubifs-2.6
* 'linux-next' of git://git.infradead.org/ubifs-2.6:
UBIFS: fix corruption dump
UBIFS: clean up free space checking
UBIFS: small amendments in the LEB scanning code
UBIFS: dump a little more in case of corruptions
MAINTAINERS: update ahunter's e-mail address
UBIFS: allow more than one volume to be mounted
UBIFS: fix assertion warning
UBIFS: minor spelling and grammar fixes
UBIFS: fix 64-bit divisions in debug print
UBIFS: few spelling fixes
UBIFS: set write-buffer timout to 3-5 seconds
UBIFS: slightly optimize write-buffer timer usage
UBIFS: improve debugging messaged
UBIFS: fix integer overflow warning
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ubifs/io.c | 57 | ||||
-rw-r--r-- | fs/ubifs/recovery.c | 57 | ||||
-rw-r--r-- | fs/ubifs/replay.c | 9 | ||||
-rw-r--r-- | fs/ubifs/scan.c | 20 | ||||
-rw-r--r-- | fs/ubifs/super.c | 14 | ||||
-rw-r--r-- | fs/ubifs/ubifs.h | 11 |
6 files changed, 92 insertions, 76 deletions
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index bc5857199ec2..762a7d6cec73 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) | |||
297 | { | 297 | { |
298 | struct ubifs_wbuf *wbuf = container_of(timer, struct ubifs_wbuf, timer); | 298 | struct ubifs_wbuf *wbuf = container_of(timer, struct ubifs_wbuf, timer); |
299 | 299 | ||
300 | dbg_io("jhead %d", wbuf->jhead); | ||
300 | wbuf->need_sync = 1; | 301 | wbuf->need_sync = 1; |
301 | wbuf->c->need_wbuf_sync = 1; | 302 | wbuf->c->need_wbuf_sync = 1; |
302 | ubifs_wake_up_bgt(wbuf->c); | 303 | ubifs_wake_up_bgt(wbuf->c); |
@@ -311,8 +312,12 @@ static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | |||
311 | { | 312 | { |
312 | ubifs_assert(!hrtimer_active(&wbuf->timer)); | 313 | ubifs_assert(!hrtimer_active(&wbuf->timer)); |
313 | 314 | ||
314 | if (!ktime_to_ns(wbuf->softlimit)) | 315 | if (wbuf->no_timer) |
315 | return; | 316 | return; |
317 | dbg_io("set timer for jhead %d, %llu-%llu millisecs", wbuf->jhead, | ||
318 | div_u64(ktime_to_ns(wbuf->softlimit), USEC_PER_SEC), | ||
319 | div_u64(ktime_to_ns(wbuf->softlimit) + wbuf->delta, | ||
320 | USEC_PER_SEC)); | ||
316 | hrtimer_start_range_ns(&wbuf->timer, wbuf->softlimit, wbuf->delta, | 321 | hrtimer_start_range_ns(&wbuf->timer, wbuf->softlimit, wbuf->delta, |
317 | HRTIMER_MODE_REL); | 322 | HRTIMER_MODE_REL); |
318 | } | 323 | } |
@@ -323,11 +328,8 @@ static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | |||
323 | */ | 328 | */ |
324 | static void cancel_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | 329 | static void cancel_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) |
325 | { | 330 | { |
326 | /* | 331 | if (wbuf->no_timer) |
327 | * If the syncer is waiting for the lock (from the background thread's | 332 | return; |
328 | * context) and another task is changing write-buffer then the syncing | ||
329 | * should be canceled. | ||
330 | */ | ||
331 | wbuf->need_sync = 0; | 333 | wbuf->need_sync = 0; |
332 | hrtimer_cancel(&wbuf->timer); | 334 | hrtimer_cancel(&wbuf->timer); |
333 | } | 335 | } |
@@ -349,8 +351,8 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf) | |||
349 | /* Write-buffer is empty or not seeked */ | 351 | /* Write-buffer is empty or not seeked */ |
350 | return 0; | 352 | return 0; |
351 | 353 | ||
352 | dbg_io("LEB %d:%d, %d bytes", | 354 | dbg_io("LEB %d:%d, %d bytes, jhead %d", |
353 | wbuf->lnum, wbuf->offs, wbuf->used); | 355 | wbuf->lnum, wbuf->offs, wbuf->used, wbuf->jhead); |
354 | ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY)); | 356 | ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY)); |
355 | ubifs_assert(!(wbuf->avail & 7)); | 357 | ubifs_assert(!(wbuf->avail & 7)); |
356 | ubifs_assert(wbuf->offs + c->min_io_size <= c->leb_size); | 358 | ubifs_assert(wbuf->offs + c->min_io_size <= c->leb_size); |
@@ -390,7 +392,7 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf) | |||
390 | * @offs: logical eraseblock offset to seek to | 392 | * @offs: logical eraseblock offset to seek to |
391 | * @dtype: data type | 393 | * @dtype: data type |
392 | * | 394 | * |
393 | * This function targets the write buffer to logical eraseblock @lnum:@offs. | 395 | * This function targets the write-buffer to logical eraseblock @lnum:@offs. |
394 | * The write-buffer is synchronized if it is not empty. Returns zero in case of | 396 | * The write-buffer is synchronized if it is not empty. Returns zero in case of |
395 | * success and a negative error code in case of failure. | 397 | * success and a negative error code in case of failure. |
396 | */ | 398 | */ |
@@ -399,7 +401,7 @@ int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, | |||
399 | { | 401 | { |
400 | const struct ubifs_info *c = wbuf->c; | 402 | const struct ubifs_info *c = wbuf->c; |
401 | 403 | ||
402 | dbg_io("LEB %d:%d", lnum, offs); | 404 | dbg_io("LEB %d:%d, jhead %d", lnum, offs, wbuf->jhead); |
403 | ubifs_assert(lnum >= 0 && lnum < c->leb_cnt); | 405 | ubifs_assert(lnum >= 0 && lnum < c->leb_cnt); |
404 | ubifs_assert(offs >= 0 && offs <= c->leb_size); | 406 | ubifs_assert(offs >= 0 && offs <= c->leb_size); |
405 | ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7)); | 407 | ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7)); |
@@ -506,9 +508,9 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
506 | struct ubifs_info *c = wbuf->c; | 508 | struct ubifs_info *c = wbuf->c; |
507 | int err, written, n, aligned_len = ALIGN(len, 8), offs; | 509 | int err, written, n, aligned_len = ALIGN(len, 8), offs; |
508 | 510 | ||
509 | dbg_io("%d bytes (%s) to wbuf at LEB %d:%d", len, | 511 | dbg_io("%d bytes (%s) to jhead %d wbuf at LEB %d:%d", len, |
510 | dbg_ntype(((struct ubifs_ch *)buf)->node_type), wbuf->lnum, | 512 | dbg_ntype(((struct ubifs_ch *)buf)->node_type), wbuf->jhead, |
511 | wbuf->offs + wbuf->used); | 513 | wbuf->lnum, wbuf->offs + wbuf->used); |
512 | ubifs_assert(len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt); | 514 | ubifs_assert(len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt); |
513 | ubifs_assert(wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0); | 515 | ubifs_assert(wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0); |
514 | ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size); | 516 | ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size); |
@@ -533,8 +535,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
533 | memcpy(wbuf->buf + wbuf->used, buf, len); | 535 | memcpy(wbuf->buf + wbuf->used, buf, len); |
534 | 536 | ||
535 | if (aligned_len == wbuf->avail) { | 537 | if (aligned_len == wbuf->avail) { |
536 | dbg_io("flush wbuf to LEB %d:%d", wbuf->lnum, | 538 | dbg_io("flush jhead %d wbuf to LEB %d:%d", |
537 | wbuf->offs); | 539 | wbuf->jhead, wbuf->lnum, wbuf->offs); |
538 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, | 540 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, |
539 | wbuf->offs, c->min_io_size, | 541 | wbuf->offs, c->min_io_size, |
540 | wbuf->dtype); | 542 | wbuf->dtype); |
@@ -562,7 +564,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
562 | * minimal I/O unit. We have to fill and flush write-buffer and switch | 564 | * minimal I/O unit. We have to fill and flush write-buffer and switch |
563 | * to the next min. I/O unit. | 565 | * to the next min. I/O unit. |
564 | */ | 566 | */ |
565 | dbg_io("flush wbuf to LEB %d:%d", wbuf->lnum, wbuf->offs); | 567 | dbg_io("flush jhead %d wbuf to LEB %d:%d", |
568 | wbuf->jhead, wbuf->lnum, wbuf->offs); | ||
566 | memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail); | 569 | memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail); |
567 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, | 570 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, |
568 | c->min_io_size, wbuf->dtype); | 571 | c->min_io_size, wbuf->dtype); |
@@ -695,7 +698,8 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, | |||
695 | int err, rlen, overlap; | 698 | int err, rlen, overlap; |
696 | struct ubifs_ch *ch = buf; | 699 | struct ubifs_ch *ch = buf; |
697 | 700 | ||
698 | dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len); | 701 | dbg_io("LEB %d:%d, %s, length %d, jhead %d", lnum, offs, |
702 | dbg_ntype(type), len, wbuf->jhead); | ||
699 | ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0); | 703 | ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0); |
700 | ubifs_assert(!(offs & 7) && offs < c->leb_size); | 704 | ubifs_assert(!(offs & 7) && offs < c->leb_size); |
701 | ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT); | 705 | ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT); |
@@ -819,13 +823,12 @@ out: | |||
819 | * @c: UBIFS file-system description object | 823 | * @c: UBIFS file-system description object |
820 | * @wbuf: write-buffer to initialize | 824 | * @wbuf: write-buffer to initialize |
821 | * | 825 | * |
822 | * This function initializes write buffer. Returns zero in case of success | 826 | * This function initializes write-buffer. Returns zero in case of success |
823 | * %-ENOMEM in case of failure. | 827 | * %-ENOMEM in case of failure. |
824 | */ | 828 | */ |
825 | int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) | 829 | int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) |
826 | { | 830 | { |
827 | size_t size; | 831 | size_t size; |
828 | ktime_t hardlimit; | ||
829 | 832 | ||
830 | wbuf->buf = kmalloc(c->min_io_size, GFP_KERNEL); | 833 | wbuf->buf = kmalloc(c->min_io_size, GFP_KERNEL); |
831 | if (!wbuf->buf) | 834 | if (!wbuf->buf) |
@@ -851,22 +854,16 @@ int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) | |||
851 | 854 | ||
852 | hrtimer_init(&wbuf->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 855 | hrtimer_init(&wbuf->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
853 | wbuf->timer.function = wbuf_timer_callback_nolock; | 856 | wbuf->timer.function = wbuf_timer_callback_nolock; |
854 | /* | 857 | wbuf->softlimit = ktime_set(WBUF_TIMEOUT_SOFTLIMIT, 0); |
855 | * Make write-buffer soft limit to be 20% of the hard limit. The | 858 | wbuf->delta = WBUF_TIMEOUT_HARDLIMIT - WBUF_TIMEOUT_SOFTLIMIT; |
856 | * write-buffer timer is allowed to expire any time between the soft | 859 | wbuf->delta *= 1000000000ULL; |
857 | * and hard limits. | 860 | ubifs_assert(wbuf->delta <= ULONG_MAX); |
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); | ||
864 | return 0; | 861 | return 0; |
865 | } | 862 | } |
866 | 863 | ||
867 | /** | 864 | /** |
868 | * ubifs_wbuf_add_ino_nolock - add an inode number into the wbuf inode array. | 865 | * ubifs_wbuf_add_ino_nolock - add an inode number into the wbuf inode array. |
869 | * @wbuf: the write-buffer whereto add | 866 | * @wbuf: the write-buffer where to add |
870 | * @inum: the inode number | 867 | * @inum: the inode number |
871 | * | 868 | * |
872 | * This function adds an inode number to the inode array of the write-buffer. | 869 | * This function adds an inode number to the inode array of the write-buffer. |
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index 805605250f12..e5f6cf8a1155 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c | |||
@@ -53,6 +53,25 @@ static int is_empty(void *buf, int len) | |||
53 | } | 53 | } |
54 | 54 | ||
55 | /** | 55 | /** |
56 | * first_non_ff - find offset of the first non-0xff byte. | ||
57 | * @buf: buffer to search in | ||
58 | * @len: length of buffer | ||
59 | * | ||
60 | * This function returns offset of the first non-0xff byte in @buf or %-1 if | ||
61 | * the buffer contains only 0xff bytes. | ||
62 | */ | ||
63 | static int first_non_ff(void *buf, int len) | ||
64 | { | ||
65 | uint8_t *p = buf; | ||
66 | int i; | ||
67 | |||
68 | for (i = 0; i < len; i++) | ||
69 | if (*p++ != 0xff) | ||
70 | return i; | ||
71 | return -1; | ||
72 | } | ||
73 | |||
74 | /** | ||
56 | * get_master_node - get the last valid master node allowing for corruption. | 75 | * get_master_node - get the last valid master node allowing for corruption. |
57 | * @c: UBIFS file-system description object | 76 | * @c: UBIFS file-system description object |
58 | * @lnum: LEB number | 77 | * @lnum: LEB number |
@@ -357,11 +376,7 @@ static int is_last_write(const struct ubifs_info *c, void *buf, int offs) | |||
357 | empty_offs = ALIGN(offs + 1, c->min_io_size); | 376 | empty_offs = ALIGN(offs + 1, c->min_io_size); |
358 | check_len = c->leb_size - empty_offs; | 377 | check_len = c->leb_size - empty_offs; |
359 | p = buf + empty_offs - offs; | 378 | p = buf + empty_offs - offs; |
360 | 379 | return is_empty(p, check_len); | |
361 | for (; check_len > 0; check_len--) | ||
362 | if (*p++ != 0xff) | ||
363 | return 0; | ||
364 | return 1; | ||
365 | } | 380 | } |
366 | 381 | ||
367 | /** | 382 | /** |
@@ -543,8 +558,8 @@ static int drop_incomplete_group(struct ubifs_scan_leb *sleb, int *offs) | |||
543 | * | 558 | * |
544 | * This function does a scan of a LEB, but caters for errors that might have | 559 | * This function does a scan of a LEB, but caters for errors that might have |
545 | * been caused by the unclean unmount from which we are attempting to recover. | 560 | * been caused by the unclean unmount from which we are attempting to recover. |
546 | * | 561 | * Returns %0 in case of success, %-EUCLEAN if an unrecoverable corruption is |
547 | * This function returns %0 on success and a negative error code on failure. | 562 | * found, and a negative error code in case of failure. |
548 | */ | 563 | */ |
549 | struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | 564 | struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, |
550 | int offs, void *sbuf, int grouped) | 565 | int offs, void *sbuf, int grouped) |
@@ -643,7 +658,8 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | |||
643 | goto corrupted; | 658 | goto corrupted; |
644 | default: | 659 | default: |
645 | dbg_err("unknown"); | 660 | dbg_err("unknown"); |
646 | goto corrupted; | 661 | err = -EINVAL; |
662 | goto error; | ||
647 | } | 663 | } |
648 | } | 664 | } |
649 | 665 | ||
@@ -652,8 +668,13 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | |||
652 | clean_buf(c, &buf, lnum, &offs, &len); | 668 | clean_buf(c, &buf, lnum, &offs, &len); |
653 | need_clean = 1; | 669 | need_clean = 1; |
654 | } else { | 670 | } else { |
655 | ubifs_err("corrupt empty space at LEB %d:%d", | 671 | int corruption = first_non_ff(buf, len); |
656 | lnum, offs); | 672 | |
673 | ubifs_err("corrupt empty space LEB %d:%d, corruption " | ||
674 | "starts at %d", lnum, offs, corruption); | ||
675 | /* Make sure we dump interesting non-0xFF data */ | ||
676 | offs = corruption; | ||
677 | buf += corruption; | ||
657 | goto corrupted; | 678 | goto corrupted; |
658 | } | 679 | } |
659 | } | 680 | } |
@@ -813,7 +834,7 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, | |||
813 | static int recover_head(const struct ubifs_info *c, int lnum, int offs, | 834 | static int recover_head(const struct ubifs_info *c, int lnum, int offs, |
814 | void *sbuf) | 835 | void *sbuf) |
815 | { | 836 | { |
816 | int len, err, need_clean = 0; | 837 | int len, err; |
817 | 838 | ||
818 | if (c->min_io_size > 1) | 839 | if (c->min_io_size > 1) |
819 | len = c->min_io_size; | 840 | len = c->min_io_size; |
@@ -827,19 +848,7 @@ static int recover_head(const struct ubifs_info *c, int lnum, int offs, | |||
827 | 848 | ||
828 | /* Read at the head location and check it is empty flash */ | 849 | /* Read at the head location and check it is empty flash */ |
829 | err = ubi_read(c->ubi, lnum, sbuf, offs, len); | 850 | err = ubi_read(c->ubi, lnum, sbuf, offs, len); |
830 | if (err) | 851 | if (err || !is_empty(sbuf, len)) { |
831 | need_clean = 1; | ||
832 | else { | ||
833 | uint8_t *p = sbuf; | ||
834 | |||
835 | while (len--) | ||
836 | if (*p++ != 0xff) { | ||
837 | need_clean = 1; | ||
838 | break; | ||
839 | } | ||
840 | } | ||
841 | |||
842 | if (need_clean) { | ||
843 | dbg_rcvry("cleaning head at %d:%d", lnum, offs); | 852 | dbg_rcvry("cleaning head at %d:%d", lnum, offs); |
844 | if (offs == 0) | 853 | if (offs == 0) |
845 | return ubifs_leb_unmap(c, lnum); | 854 | return ubifs_leb_unmap(c, lnum); |
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index 11cc80125a49..2970500f32df 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c | |||
@@ -837,9 +837,10 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) | |||
837 | 837 | ||
838 | dbg_mnt("replay log LEB %d:%d", lnum, offs); | 838 | dbg_mnt("replay log LEB %d:%d", lnum, offs); |
839 | sleb = ubifs_scan(c, lnum, offs, sbuf); | 839 | sleb = ubifs_scan(c, lnum, offs, sbuf); |
840 | if (IS_ERR(sleb)) { | 840 | if (IS_ERR(sleb) ) { |
841 | if (c->need_recovery) | 841 | if (PTR_ERR(sleb) != -EUCLEAN || !c->need_recovery) |
842 | sleb = ubifs_recover_log_leb(c, lnum, offs, sbuf); | 842 | return PTR_ERR(sleb); |
843 | sleb = ubifs_recover_log_leb(c, lnum, offs, sbuf); | ||
843 | if (IS_ERR(sleb)) | 844 | if (IS_ERR(sleb)) |
844 | return PTR_ERR(sleb); | 845 | return PTR_ERR(sleb); |
845 | } | 846 | } |
@@ -957,7 +958,7 @@ out: | |||
957 | return err; | 958 | return err; |
958 | 959 | ||
959 | out_dump: | 960 | out_dump: |
960 | ubifs_err("log error detected while replying the log at LEB %d:%d", | 961 | ubifs_err("log error detected while replaying the log at LEB %d:%d", |
961 | lnum, offs + snod->offs); | 962 | lnum, offs + snod->offs); |
962 | dbg_dump_node(c, snod->node); | 963 | dbg_dump_node(c, snod->node); |
963 | ubifs_scan_destroy(sleb); | 964 | ubifs_scan_destroy(sleb); |
diff --git a/fs/ubifs/scan.c b/fs/ubifs/scan.c index 0ed82479b44b..892ebfee4fe5 100644 --- a/fs/ubifs/scan.c +++ b/fs/ubifs/scan.c | |||
@@ -238,12 +238,12 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs, | |||
238 | { | 238 | { |
239 | int len; | 239 | int len; |
240 | 240 | ||
241 | ubifs_err("corrupted data at LEB %d:%d", lnum, offs); | 241 | ubifs_err("corruption at LEB %d:%d", lnum, offs); |
242 | if (dbg_failure_mode) | 242 | if (dbg_failure_mode) |
243 | return; | 243 | return; |
244 | len = c->leb_size - offs; | 244 | len = c->leb_size - offs; |
245 | if (len > 4096) | 245 | if (len > 8192) |
246 | len = 4096; | 246 | len = 8192; |
247 | dbg_err("first %d bytes from LEB %d:%d", len, lnum, offs); | 247 | dbg_err("first %d bytes from LEB %d:%d", len, lnum, offs); |
248 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4, buf, len, 1); | 248 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4, buf, len, 1); |
249 | } | 249 | } |
@@ -256,7 +256,9 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs, | |||
256 | * @sbuf: scan buffer (must be c->leb_size) | 256 | * @sbuf: scan buffer (must be c->leb_size) |
257 | * | 257 | * |
258 | * This function scans LEB number @lnum and returns complete information about | 258 | * This function scans LEB number @lnum and returns complete information about |
259 | * its contents. Returns an error code in case of failure. | 259 | * its contents. Returns the scaned information in case of success and, |
260 | * %-EUCLEAN if the LEB neads recovery, and other negative error codes in case | ||
261 | * of failure. | ||
260 | */ | 262 | */ |
261 | struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | 263 | struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, |
262 | int offs, void *sbuf) | 264 | int offs, void *sbuf) |
@@ -279,7 +281,6 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | |||
279 | cond_resched(); | 281 | cond_resched(); |
280 | 282 | ||
281 | ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 0); | 283 | ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 0); |
282 | |||
283 | if (ret > 0) { | 284 | if (ret > 0) { |
284 | /* Padding bytes or a valid padding node */ | 285 | /* Padding bytes or a valid padding node */ |
285 | offs += ret; | 286 | offs += ret; |
@@ -304,7 +305,8 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | |||
304 | goto corrupted; | 305 | goto corrupted; |
305 | default: | 306 | default: |
306 | dbg_err("unknown"); | 307 | dbg_err("unknown"); |
307 | goto corrupted; | 308 | err = -EINVAL; |
309 | goto error; | ||
308 | } | 310 | } |
309 | 311 | ||
310 | err = ubifs_add_snod(c, sleb, buf, offs); | 312 | err = ubifs_add_snod(c, sleb, buf, offs); |
@@ -317,8 +319,10 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | |||
317 | len -= node_len; | 319 | len -= node_len; |
318 | } | 320 | } |
319 | 321 | ||
320 | if (offs % c->min_io_size) | 322 | if (offs % c->min_io_size) { |
321 | goto corrupted; | 323 | ubifs_err("empty space starts at non-aligned offset %d", offs); |
324 | goto corrupted;; | ||
325 | } | ||
322 | 326 | ||
323 | ubifs_end_scan(c, sleb, lnum, offs); | 327 | ubifs_end_scan(c, sleb, lnum, offs); |
324 | 328 | ||
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 79fad43f3c57..26d2e0d80465 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -797,7 +797,7 @@ static int alloc_wbufs(struct ubifs_info *c) | |||
797 | * does not need to be synchronized by timer. | 797 | * does not need to be synchronized by timer. |
798 | */ | 798 | */ |
799 | c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM; | 799 | c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM; |
800 | c->jheads[GCHD].wbuf.softlimit = ktime_set(0, 0); | 800 | c->jheads[GCHD].wbuf.no_timer = 1; |
801 | 801 | ||
802 | return 0; | 802 | return 0; |
803 | } | 803 | } |
@@ -986,7 +986,7 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options, | |||
986 | switch (token) { | 986 | switch (token) { |
987 | /* | 987 | /* |
988 | * %Opt_fast_unmount and %Opt_norm_unmount options are ignored. | 988 | * %Opt_fast_unmount and %Opt_norm_unmount options are ignored. |
989 | * We accepte them in order to be backware-compatible. But this | 989 | * We accept them in order to be backward-compatible. But this |
990 | * should be removed at some point. | 990 | * should be removed at some point. |
991 | */ | 991 | */ |
992 | case Opt_fast_unmount: | 992 | case Opt_fast_unmount: |
@@ -1287,6 +1287,9 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1287 | if (err) | 1287 | if (err) |
1288 | goto out_journal; | 1288 | goto out_journal; |
1289 | 1289 | ||
1290 | /* Calculate 'min_idx_lebs' after journal replay */ | ||
1291 | c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); | ||
1292 | |||
1290 | err = ubifs_mount_orphans(c, c->need_recovery, mounted_read_only); | 1293 | err = ubifs_mount_orphans(c, c->need_recovery, mounted_read_only); |
1291 | if (err) | 1294 | if (err) |
1292 | goto out_orphans; | 1295 | goto out_orphans; |
@@ -1754,10 +1757,8 @@ static void ubifs_put_super(struct super_block *sb) | |||
1754 | 1757 | ||
1755 | /* Synchronize write-buffers */ | 1758 | /* Synchronize write-buffers */ |
1756 | if (c->jheads) | 1759 | if (c->jheads) |
1757 | for (i = 0; i < c->jhead_cnt; i++) { | 1760 | for (i = 0; i < c->jhead_cnt; i++) |
1758 | ubifs_wbuf_sync(&c->jheads[i].wbuf); | 1761 | ubifs_wbuf_sync(&c->jheads[i].wbuf); |
1759 | hrtimer_cancel(&c->jheads[i].wbuf.timer); | ||
1760 | } | ||
1761 | 1762 | ||
1762 | /* | 1763 | /* |
1763 | * On fatal errors c->ro_media is set to 1, in which case we do | 1764 | * On fatal errors c->ro_media is set to 1, in which case we do |
@@ -1975,7 +1976,8 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | |||
1975 | err = bdi_init(&c->bdi); | 1976 | err = bdi_init(&c->bdi); |
1976 | if (err) | 1977 | if (err) |
1977 | goto out_close; | 1978 | goto out_close; |
1978 | err = bdi_register(&c->bdi, NULL, "ubifs"); | 1979 | err = bdi_register(&c->bdi, NULL, "ubifs_%d_%d", |
1980 | c->vi.ubi_num, c->vi.vol_id); | ||
1979 | if (err) | 1981 | if (err) |
1980 | goto out_bdi; | 1982 | goto out_bdi; |
1981 | 1983 | ||
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 1bf01d820066..a29349094422 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -95,8 +95,9 @@ | |||
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 in seconds */ | 98 | /* Write-buffer synchronization timeout interval in seconds */ |
99 | #define DEFAULT_WBUF_TIMEOUT_SECS 5 | 99 | #define WBUF_TIMEOUT_SOFTLIMIT 3 |
100 | #define WBUF_TIMEOUT_HARDLIMIT 5 | ||
100 | 101 | ||
101 | /* Maximum possible inode number (only 32-bit inodes are supported now) */ | 102 | /* Maximum possible inode number (only 32-bit inodes are supported now) */ |
102 | #define MAX_INUM 0xFFFFFFFF | 103 | #define MAX_INUM 0xFFFFFFFF |
@@ -654,7 +655,8 @@ typedef int (*ubifs_lpt_scan_callback)(struct ubifs_info *c, | |||
654 | * @delta: hard and soft timeouts delta (the timer expire inteval is @softlimit | 655 | * @delta: hard and soft timeouts delta (the timer expire inteval is @softlimit |
655 | * and @softlimit + @delta) | 656 | * and @softlimit + @delta) |
656 | * @timer: write-buffer timer | 657 | * @timer: write-buffer timer |
657 | * @need_sync: it is set if its timer expired and needs sync | 658 | * @no_timer: non-zero if this write-buffer does not have a timer |
659 | * @need_sync: non-zero if the timer expired and the wbuf needs sync'ing | ||
658 | * @next_ino: points to the next position of the following inode number | 660 | * @next_ino: points to the next position of the following inode number |
659 | * @inodes: stores the inode numbers of the nodes which are in wbuf | 661 | * @inodes: stores the inode numbers of the nodes which are in wbuf |
660 | * | 662 | * |
@@ -683,7 +685,8 @@ struct ubifs_wbuf { | |||
683 | ktime_t softlimit; | 685 | ktime_t softlimit; |
684 | unsigned long long delta; | 686 | unsigned long long delta; |
685 | struct hrtimer timer; | 687 | struct hrtimer timer; |
686 | int need_sync; | 688 | unsigned int no_timer:1; |
689 | unsigned int need_sync:1; | ||
687 | int next_ino; | 690 | int next_ino; |
688 | ino_t *inodes; | 691 | ino_t *inodes; |
689 | }; | 692 | }; |