diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ubifs/budget.c | 2 | ||||
-rw-r--r-- | fs/ubifs/commit.c | 2 | ||||
-rw-r--r-- | fs/ubifs/debug.c | 112 | ||||
-rw-r--r-- | fs/ubifs/debug.h | 5 | ||||
-rw-r--r-- | fs/ubifs/file.c | 62 | ||||
-rw-r--r-- | fs/ubifs/gc.c | 2 | ||||
-rw-r--r-- | fs/ubifs/io.c | 29 | ||||
-rw-r--r-- | fs/ubifs/journal.c | 13 | ||||
-rw-r--r-- | fs/ubifs/key.h | 35 | ||||
-rw-r--r-- | fs/ubifs/log.c | 17 | ||||
-rw-r--r-- | fs/ubifs/lprops.c | 43 | ||||
-rw-r--r-- | fs/ubifs/master.c | 20 | ||||
-rw-r--r-- | fs/ubifs/orphan.c | 7 | ||||
-rw-r--r-- | fs/ubifs/recovery.c | 4 | ||||
-rw-r--r-- | fs/ubifs/replay.c | 6 | ||||
-rw-r--r-- | fs/ubifs/scan.c | 32 | ||||
-rw-r--r-- | fs/ubifs/super.c | 33 | ||||
-rw-r--r-- | fs/ubifs/tnc.c | 76 | ||||
-rw-r--r-- | fs/ubifs/tnc_commit.c | 2 | ||||
-rw-r--r-- | fs/ubifs/ubifs-media.h | 7 | ||||
-rw-r--r-- | fs/ubifs/ubifs.h | 13 | ||||
-rw-r--r-- | fs/ubifs/xattr.c | 4 |
22 files changed, 345 insertions, 181 deletions
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c index ee1ce68fd98b..076ca50e9933 100644 --- a/fs/ubifs/budget.c +++ b/fs/ubifs/budget.c | |||
@@ -715,7 +715,7 @@ long long ubifs_get_free_space_nolock(struct ubifs_info *c) | |||
715 | * ubifs_get_free_space - return amount of free space. | 715 | * ubifs_get_free_space - return amount of free space. |
716 | * @c: UBIFS file-system description object | 716 | * @c: UBIFS file-system description object |
717 | * | 717 | * |
718 | * This function calculates and retuns amount of free space to report to | 718 | * This function calculates and returns amount of free space to report to |
719 | * user-space. | 719 | * user-space. |
720 | */ | 720 | */ |
721 | long long ubifs_get_free_space(struct ubifs_info *c) | 721 | long long ubifs_get_free_space(struct ubifs_info *c) |
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c index f3a7945527fb..4775af401167 100644 --- a/fs/ubifs/commit.c +++ b/fs/ubifs/commit.c | |||
@@ -510,7 +510,7 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot) | |||
510 | int lnum, offs, len, err = 0, uninitialized_var(last_level), child_cnt; | 510 | int lnum, offs, len, err = 0, uninitialized_var(last_level), child_cnt; |
511 | int first = 1, iip; | 511 | int first = 1, iip; |
512 | struct ubifs_debug_info *d = c->dbg; | 512 | struct ubifs_debug_info *d = c->dbg; |
513 | union ubifs_key lower_key, upper_key, l_key, u_key; | 513 | union ubifs_key uninitialized_var(lower_key), upper_key, l_key, u_key; |
514 | unsigned long long uninitialized_var(last_sqnum); | 514 | unsigned long long uninitialized_var(last_sqnum); |
515 | struct ubifs_idx_node *idx; | 515 | struct ubifs_idx_node *idx; |
516 | struct list_head list; | 516 | struct list_head list; |
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index ce2cd8343618..dbc093afd946 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c | |||
@@ -210,6 +210,20 @@ const char *dbg_cstate(int cmt_state) | |||
210 | } | 210 | } |
211 | } | 211 | } |
212 | 212 | ||
213 | const char *dbg_jhead(int jhead) | ||
214 | { | ||
215 | switch (jhead) { | ||
216 | case GCHD: | ||
217 | return "0 (GC)"; | ||
218 | case BASEHD: | ||
219 | return "1 (base)"; | ||
220 | case DATAHD: | ||
221 | return "2 (data)"; | ||
222 | default: | ||
223 | return "unknown journal head"; | ||
224 | } | ||
225 | } | ||
226 | |||
213 | static void dump_ch(const struct ubifs_ch *ch) | 227 | static void dump_ch(const struct ubifs_ch *ch) |
214 | { | 228 | { |
215 | printk(KERN_DEBUG "\tmagic %#x\n", le32_to_cpu(ch->magic)); | 229 | printk(KERN_DEBUG "\tmagic %#x\n", le32_to_cpu(ch->magic)); |
@@ -623,8 +637,9 @@ void dbg_dump_budg(struct ubifs_info *c) | |||
623 | /* If we are in R/O mode, journal heads do not exist */ | 637 | /* If we are in R/O mode, journal heads do not exist */ |
624 | if (c->jheads) | 638 | if (c->jheads) |
625 | for (i = 0; i < c->jhead_cnt; i++) | 639 | for (i = 0; i < c->jhead_cnt; i++) |
626 | printk(KERN_DEBUG "\tjhead %d\t LEB %d\n", | 640 | printk(KERN_DEBUG "\tjhead %s\t LEB %d\n", |
627 | c->jheads[i].wbuf.jhead, c->jheads[i].wbuf.lnum); | 641 | dbg_jhead(c->jheads[i].wbuf.jhead), |
642 | c->jheads[i].wbuf.lnum); | ||
628 | for (rb = rb_first(&c->buds); rb; rb = rb_next(rb)) { | 643 | for (rb = rb_first(&c->buds); rb; rb = rb_next(rb)) { |
629 | bud = rb_entry(rb, struct ubifs_bud, rb); | 644 | bud = rb_entry(rb, struct ubifs_bud, rb); |
630 | printk(KERN_DEBUG "\tbud LEB %d\n", bud->lnum); | 645 | printk(KERN_DEBUG "\tbud LEB %d\n", bud->lnum); |
@@ -648,9 +663,90 @@ void dbg_dump_budg(struct ubifs_info *c) | |||
648 | 663 | ||
649 | void dbg_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp) | 664 | void dbg_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp) |
650 | { | 665 | { |
651 | printk(KERN_DEBUG "LEB %d lprops: free %d, dirty %d (used %d), " | 666 | int i, spc, dark = 0, dead = 0; |
652 | "flags %#x\n", lp->lnum, lp->free, lp->dirty, | 667 | struct rb_node *rb; |
653 | c->leb_size - lp->free - lp->dirty, lp->flags); | 668 | struct ubifs_bud *bud; |
669 | |||
670 | spc = lp->free + lp->dirty; | ||
671 | if (spc < c->dead_wm) | ||
672 | dead = spc; | ||
673 | else | ||
674 | dark = ubifs_calc_dark(c, spc); | ||
675 | |||
676 | if (lp->flags & LPROPS_INDEX) | ||
677 | printk(KERN_DEBUG "LEB %-7d free %-8d dirty %-8d used %-8d " | ||
678 | "free + dirty %-8d flags %#x (", lp->lnum, lp->free, | ||
679 | lp->dirty, c->leb_size - spc, spc, lp->flags); | ||
680 | else | ||
681 | printk(KERN_DEBUG "LEB %-7d free %-8d dirty %-8d used %-8d " | ||
682 | "free + dirty %-8d dark %-4d dead %-4d nodes fit %-3d " | ||
683 | "flags %#-4x (", lp->lnum, lp->free, lp->dirty, | ||
684 | c->leb_size - spc, spc, dark, dead, | ||
685 | (int)(spc / UBIFS_MAX_NODE_SZ), lp->flags); | ||
686 | |||
687 | if (lp->flags & LPROPS_TAKEN) { | ||
688 | if (lp->flags & LPROPS_INDEX) | ||
689 | printk(KERN_CONT "index, taken"); | ||
690 | else | ||
691 | printk(KERN_CONT "taken"); | ||
692 | } else { | ||
693 | const char *s; | ||
694 | |||
695 | if (lp->flags & LPROPS_INDEX) { | ||
696 | switch (lp->flags & LPROPS_CAT_MASK) { | ||
697 | case LPROPS_DIRTY_IDX: | ||
698 | s = "dirty index"; | ||
699 | break; | ||
700 | case LPROPS_FRDI_IDX: | ||
701 | s = "freeable index"; | ||
702 | break; | ||
703 | default: | ||
704 | s = "index"; | ||
705 | } | ||
706 | } else { | ||
707 | switch (lp->flags & LPROPS_CAT_MASK) { | ||
708 | case LPROPS_UNCAT: | ||
709 | s = "not categorized"; | ||
710 | break; | ||
711 | case LPROPS_DIRTY: | ||
712 | s = "dirty"; | ||
713 | break; | ||
714 | case LPROPS_FREE: | ||
715 | s = "free"; | ||
716 | break; | ||
717 | case LPROPS_EMPTY: | ||
718 | s = "empty"; | ||
719 | break; | ||
720 | case LPROPS_FREEABLE: | ||
721 | s = "freeable"; | ||
722 | break; | ||
723 | default: | ||
724 | s = NULL; | ||
725 | break; | ||
726 | } | ||
727 | } | ||
728 | printk(KERN_CONT "%s", s); | ||
729 | } | ||
730 | |||
731 | for (rb = rb_first((struct rb_root *)&c->buds); rb; rb = rb_next(rb)) { | ||
732 | bud = rb_entry(rb, struct ubifs_bud, rb); | ||
733 | if (bud->lnum == lp->lnum) { | ||
734 | int head = 0; | ||
735 | for (i = 0; i < c->jhead_cnt; i++) { | ||
736 | if (lp->lnum == c->jheads[i].wbuf.lnum) { | ||
737 | printk(KERN_CONT ", jhead %s", | ||
738 | dbg_jhead(i)); | ||
739 | head = 1; | ||
740 | } | ||
741 | } | ||
742 | if (!head) | ||
743 | printk(KERN_CONT ", bud of jhead %s", | ||
744 | dbg_jhead(bud->jhead)); | ||
745 | } | ||
746 | } | ||
747 | if (lp->lnum == c->gc_lnum) | ||
748 | printk(KERN_CONT ", GC LEB"); | ||
749 | printk(KERN_CONT ")\n"); | ||
654 | } | 750 | } |
655 | 751 | ||
656 | void dbg_dump_lprops(struct ubifs_info *c) | 752 | void dbg_dump_lprops(struct ubifs_info *c) |
@@ -724,7 +820,7 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum) | |||
724 | 820 | ||
725 | printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n", | 821 | printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n", |
726 | current->pid, lnum); | 822 | current->pid, lnum); |
727 | sleb = ubifs_scan(c, lnum, 0, c->dbg->buf); | 823 | sleb = ubifs_scan(c, lnum, 0, c->dbg->buf, 0); |
728 | if (IS_ERR(sleb)) { | 824 | if (IS_ERR(sleb)) { |
729 | ubifs_err("scan error %d", (int)PTR_ERR(sleb)); | 825 | ubifs_err("scan error %d", (int)PTR_ERR(sleb)); |
730 | return; | 826 | return; |
@@ -909,8 +1005,10 @@ out: | |||
909 | ubifs_msg("saved lprops statistics dump"); | 1005 | ubifs_msg("saved lprops statistics dump"); |
910 | dbg_dump_lstats(&d->saved_lst); | 1006 | dbg_dump_lstats(&d->saved_lst); |
911 | ubifs_get_lp_stats(c, &lst); | 1007 | ubifs_get_lp_stats(c, &lst); |
1008 | |||
912 | ubifs_msg("current lprops statistics dump"); | 1009 | ubifs_msg("current lprops statistics dump"); |
913 | dbg_dump_lstats(&d->saved_lst); | 1010 | dbg_dump_lstats(&lst); |
1011 | |||
914 | spin_lock(&c->space_lock); | 1012 | spin_lock(&c->space_lock); |
915 | dbg_dump_budg(c); | 1013 | dbg_dump_budg(c); |
916 | spin_unlock(&c->space_lock); | 1014 | spin_unlock(&c->space_lock); |
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h index c1cd73b2e06e..29d960101ea6 100644 --- a/fs/ubifs/debug.h +++ b/fs/ubifs/debug.h | |||
@@ -271,6 +271,7 @@ void ubifs_debugging_exit(struct ubifs_info *c); | |||
271 | /* Dump functions */ | 271 | /* Dump functions */ |
272 | const char *dbg_ntype(int type); | 272 | const char *dbg_ntype(int type); |
273 | const char *dbg_cstate(int cmt_state); | 273 | const char *dbg_cstate(int cmt_state); |
274 | const char *dbg_jhead(int jhead); | ||
274 | const char *dbg_get_key_dump(const struct ubifs_info *c, | 275 | const char *dbg_get_key_dump(const struct ubifs_info *c, |
275 | const union ubifs_key *key); | 276 | const union ubifs_key *key); |
276 | void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode); | 277 | void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode); |
@@ -321,6 +322,8 @@ void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat, | |||
321 | int dbg_check_lprops(struct ubifs_info *c); | 322 | int dbg_check_lprops(struct ubifs_info *c); |
322 | int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode, | 323 | int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode, |
323 | int row, int col); | 324 | int row, int col); |
325 | int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode, | ||
326 | loff_t size); | ||
324 | 327 | ||
325 | /* Force the use of in-the-gaps method for testing */ | 328 | /* Force the use of in-the-gaps method for testing */ |
326 | 329 | ||
@@ -425,6 +428,7 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c); | |||
425 | 428 | ||
426 | #define dbg_ntype(type) "" | 429 | #define dbg_ntype(type) "" |
427 | #define dbg_cstate(cmt_state) "" | 430 | #define dbg_cstate(cmt_state) "" |
431 | #define dbg_jhead(jhead) "" | ||
428 | #define dbg_get_key_dump(c, key) ({}) | 432 | #define dbg_get_key_dump(c, key) ({}) |
429 | #define dbg_dump_inode(c, inode) ({}) | 433 | #define dbg_dump_inode(c, inode) ({}) |
430 | #define dbg_dump_node(c, node) ({}) | 434 | #define dbg_dump_node(c, node) ({}) |
@@ -460,6 +464,7 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c); | |||
460 | #define dbg_check_heap(c, heap, cat, add_pos) ({}) | 464 | #define dbg_check_heap(c, heap, cat, add_pos) ({}) |
461 | #define dbg_check_lprops(c) 0 | 465 | #define dbg_check_lprops(c) 0 |
462 | #define dbg_check_lpt_nodes(c, cnode, row, col) 0 | 466 | #define dbg_check_lpt_nodes(c, cnode, row, col) 0 |
467 | #define dbg_check_inode_size(c, inode, size) 0 | ||
463 | #define dbg_force_in_the_gaps_enabled 0 | 468 | #define dbg_force_in_the_gaps_enabled 0 |
464 | #define dbg_force_in_the_gaps() 0 | 469 | #define dbg_force_in_the_gaps() 0 |
465 | #define dbg_failure_mode 0 | 470 | #define dbg_failure_mode 0 |
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 6d34dc7e33e1..2e6481a7701c 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c | |||
@@ -21,34 +21,32 @@ | |||
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * This file implements VFS file and inode operations of regular files, device | 24 | * This file implements VFS file and inode operations for regular files, device |
25 | * nodes and symlinks as well as address space operations. | 25 | * nodes and symlinks as well as address space operations. |
26 | * | 26 | * |
27 | * UBIFS uses 2 page flags: PG_private and PG_checked. PG_private is set if the | 27 | * UBIFS uses 2 page flags: @PG_private and @PG_checked. @PG_private is set if |
28 | * page is dirty and is used for budgeting purposes - dirty pages should not be | 28 | * the page is dirty and is used for optimization purposes - dirty pages are |
29 | * budgeted. The PG_checked flag is set if full budgeting is required for the | 29 | * not budgeted so the flag shows that 'ubifs_write_end()' should not release |
30 | * page e.g., when it corresponds to a file hole or it is just beyond the file | 30 | * the budget for this page. The @PG_checked flag is set if full budgeting is |
31 | * size. The budgeting is done in 'ubifs_write_begin()', because it is OK to | 31 | * required for the page e.g., when it corresponds to a file hole or it is |
32 | * fail in this function, and the budget is released in 'ubifs_write_end()'. So | 32 | * beyond the file size. The budgeting is done in 'ubifs_write_begin()', because |
33 | * the PG_private and PG_checked flags carry the information about how the page | 33 | * it is OK to fail in this function, and the budget is released in |
34 | * was budgeted, to make it possible to release the budget properly. | 34 | * 'ubifs_write_end()'. So the @PG_private and @PG_checked flags carry |
35 | * information about how the page was budgeted, to make it possible to release | ||
36 | * the budget properly. | ||
35 | * | 37 | * |
36 | * A thing to keep in mind: inode's 'i_mutex' is locked in most VFS operations | 38 | * A thing to keep in mind: inode @i_mutex is locked in most VFS operations we |
37 | * we implement. However, this is not true for '->writepage()', which might be | 39 | * implement. However, this is not true for 'ubifs_writepage()', which may be |
38 | * called with 'i_mutex' unlocked. For example, when pdflush is performing | 40 | * called with @i_mutex unlocked. For example, when pdflush is doing background |
39 | * write-back, it calls 'writepage()' with unlocked 'i_mutex', although the | 41 | * write-back, it calls 'ubifs_writepage()' with unlocked @i_mutex. At "normal" |
40 | * inode has 'I_LOCK' flag in this case. At "normal" work-paths 'i_mutex' is | 42 | * work-paths the @i_mutex is locked in 'ubifs_writepage()', e.g. in the |
41 | * locked in '->writepage', e.g. in "sys_write -> alloc_pages -> direct reclaim | 43 | * "sys_write -> alloc_pages -> direct reclaim path". So, in 'ubifs_writepage()' |
42 | * path'. So, in '->writepage()' we are only guaranteed that the page is | 44 | * we are only guaranteed that the page is locked. |
43 | * locked. | ||
44 | * | 45 | * |
45 | * Similarly, 'i_mutex' does not have to be locked in readpage(), e.g., | 46 | * Similarly, @i_mutex is not always locked in 'ubifs_readpage()', e.g., the |
46 | * readahead path does not have it locked ("sys_read -> generic_file_aio_read | 47 | * read-ahead path does not lock it ("sys_read -> generic_file_aio_read -> |
47 | * -> ondemand_readahead -> readpage"). In case of readahead, 'I_LOCK' flag is | 48 | * ondemand_readahead -> readpage"). In case of readahead, @I_LOCK flag is not |
48 | * not set as well. However, UBIFS disables readahead. | 49 | * set as well. However, UBIFS disables readahead. |
49 | * | ||
50 | * This, for example means that there might be 2 concurrent '->writepage()' | ||
51 | * calls for the same inode, but different inode dirty pages. | ||
52 | */ | 50 | */ |
53 | 51 | ||
54 | #include "ubifs.h" | 52 | #include "ubifs.h" |
@@ -449,9 +447,9 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, | |||
449 | /* | 447 | /* |
450 | * We change whole page so no need to load it. But we | 448 | * We change whole page so no need to load it. But we |
451 | * have to set the @PG_checked flag to make the further | 449 | * have to set the @PG_checked flag to make the further |
452 | * code the page is new. This might be not true, but it | 450 | * code know that the page is new. This might be not |
453 | * is better to budget more that to read the page from | 451 | * true, but it is better to budget more than to read |
454 | * the media. | 452 | * the page from the media. |
455 | */ | 453 | */ |
456 | SetPageChecked(page); | 454 | SetPageChecked(page); |
457 | skipped_read = 1; | 455 | skipped_read = 1; |
@@ -497,8 +495,8 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, | |||
497 | } | 495 | } |
498 | 496 | ||
499 | /* | 497 | /* |
500 | * Whee, we aquired budgeting quickly - without involving | 498 | * Whee, we acquired budgeting quickly - without involving |
501 | * garbage-collection, committing or forceing write-back. We return | 499 | * garbage-collection, committing or forcing write-back. We return |
502 | * with @ui->ui_mutex locked if we are appending pages, and unlocked | 500 | * with @ui->ui_mutex locked if we are appending pages, and unlocked |
503 | * otherwise. This is an optimization (slightly hacky though). | 501 | * otherwise. This is an optimization (slightly hacky though). |
504 | */ | 502 | */ |
@@ -562,7 +560,7 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping, | |||
562 | 560 | ||
563 | /* | 561 | /* |
564 | * Return 0 to force VFS to repeat the whole operation, or the | 562 | * Return 0 to force VFS to repeat the whole operation, or the |
565 | * error code if 'do_readpage()' failes. | 563 | * error code if 'do_readpage()' fails. |
566 | */ | 564 | */ |
567 | copied = do_readpage(page); | 565 | copied = do_readpage(page); |
568 | goto out; | 566 | goto out; |
@@ -1175,11 +1173,11 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode, | |||
1175 | ui->ui_size = inode->i_size; | 1173 | ui->ui_size = inode->i_size; |
1176 | /* Truncation changes inode [mc]time */ | 1174 | /* Truncation changes inode [mc]time */ |
1177 | inode->i_mtime = inode->i_ctime = ubifs_current_time(inode); | 1175 | inode->i_mtime = inode->i_ctime = ubifs_current_time(inode); |
1178 | /* The other attributes may be changed at the same time as well */ | 1176 | /* Other attributes may be changed at the same time as well */ |
1179 | do_attr_changes(inode, attr); | 1177 | do_attr_changes(inode, attr); |
1180 | |||
1181 | err = ubifs_jnl_truncate(c, inode, old_size, new_size); | 1178 | err = ubifs_jnl_truncate(c, inode, old_size, new_size); |
1182 | mutex_unlock(&ui->ui_mutex); | 1179 | mutex_unlock(&ui->ui_mutex); |
1180 | |||
1183 | out_budg: | 1181 | out_budg: |
1184 | if (budgeted) | 1182 | if (budgeted) |
1185 | ubifs_release_budget(c, &req); | 1183 | ubifs_release_budget(c, &req); |
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c index f0f5f15d384e..618c2701d3a7 100644 --- a/fs/ubifs/gc.c +++ b/fs/ubifs/gc.c | |||
@@ -529,7 +529,7 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp) | |||
529 | * We scan the entire LEB even though we only really need to scan up to | 529 | * We scan the entire LEB even though we only really need to scan up to |
530 | * (c->leb_size - lp->free). | 530 | * (c->leb_size - lp->free). |
531 | */ | 531 | */ |
532 | sleb = ubifs_scan(c, lnum, 0, c->sbuf); | 532 | sleb = ubifs_scan(c, lnum, 0, c->sbuf, 0); |
533 | if (IS_ERR(sleb)) | 533 | if (IS_ERR(sleb)) |
534 | return PTR_ERR(sleb); | 534 | return PTR_ERR(sleb); |
535 | 535 | ||
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index 762a7d6cec73..e589fedaf1ef 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c | |||
@@ -297,7 +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 | dbg_io("jhead %s", dbg_jhead(wbuf->jhead)); |
301 | wbuf->need_sync = 1; | 301 | wbuf->need_sync = 1; |
302 | wbuf->c->need_wbuf_sync = 1; | 302 | wbuf->c->need_wbuf_sync = 1; |
303 | ubifs_wake_up_bgt(wbuf->c); | 303 | ubifs_wake_up_bgt(wbuf->c); |
@@ -314,7 +314,8 @@ static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | |||
314 | 314 | ||
315 | if (wbuf->no_timer) | 315 | if (wbuf->no_timer) |
316 | return; | 316 | return; |
317 | dbg_io("set timer for jhead %d, %llu-%llu millisecs", wbuf->jhead, | 317 | dbg_io("set timer for jhead %s, %llu-%llu millisecs", |
318 | dbg_jhead(wbuf->jhead), | ||
318 | div_u64(ktime_to_ns(wbuf->softlimit), USEC_PER_SEC), | 319 | div_u64(ktime_to_ns(wbuf->softlimit), USEC_PER_SEC), |
319 | div_u64(ktime_to_ns(wbuf->softlimit) + wbuf->delta, | 320 | div_u64(ktime_to_ns(wbuf->softlimit) + wbuf->delta, |
320 | USEC_PER_SEC)); | 321 | USEC_PER_SEC)); |
@@ -351,8 +352,8 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf) | |||
351 | /* Write-buffer is empty or not seeked */ | 352 | /* Write-buffer is empty or not seeked */ |
352 | return 0; | 353 | return 0; |
353 | 354 | ||
354 | dbg_io("LEB %d:%d, %d bytes, jhead %d", | 355 | dbg_io("LEB %d:%d, %d bytes, jhead %s", |
355 | wbuf->lnum, wbuf->offs, wbuf->used, wbuf->jhead); | 356 | wbuf->lnum, wbuf->offs, wbuf->used, dbg_jhead(wbuf->jhead)); |
356 | ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY)); | 357 | ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY)); |
357 | ubifs_assert(!(wbuf->avail & 7)); | 358 | ubifs_assert(!(wbuf->avail & 7)); |
358 | ubifs_assert(wbuf->offs + c->min_io_size <= c->leb_size); | 359 | ubifs_assert(wbuf->offs + c->min_io_size <= c->leb_size); |
@@ -401,7 +402,7 @@ int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, | |||
401 | { | 402 | { |
402 | const struct ubifs_info *c = wbuf->c; | 403 | const struct ubifs_info *c = wbuf->c; |
403 | 404 | ||
404 | dbg_io("LEB %d:%d, jhead %d", lnum, offs, wbuf->jhead); | 405 | dbg_io("LEB %d:%d, jhead %s", lnum, offs, dbg_jhead(wbuf->jhead)); |
405 | ubifs_assert(lnum >= 0 && lnum < c->leb_cnt); | 406 | ubifs_assert(lnum >= 0 && lnum < c->leb_cnt); |
406 | ubifs_assert(offs >= 0 && offs <= c->leb_size); | 407 | ubifs_assert(offs >= 0 && offs <= c->leb_size); |
407 | ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7)); | 408 | ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7)); |
@@ -508,9 +509,9 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
508 | struct ubifs_info *c = wbuf->c; | 509 | struct ubifs_info *c = wbuf->c; |
509 | int err, written, n, aligned_len = ALIGN(len, 8), offs; | 510 | int err, written, n, aligned_len = ALIGN(len, 8), offs; |
510 | 511 | ||
511 | dbg_io("%d bytes (%s) to jhead %d wbuf at LEB %d:%d", len, | 512 | dbg_io("%d bytes (%s) to jhead %s wbuf at LEB %d:%d", len, |
512 | dbg_ntype(((struct ubifs_ch *)buf)->node_type), wbuf->jhead, | 513 | dbg_ntype(((struct ubifs_ch *)buf)->node_type), |
513 | wbuf->lnum, wbuf->offs + wbuf->used); | 514 | dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs + wbuf->used); |
514 | ubifs_assert(len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt); | 515 | ubifs_assert(len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt); |
515 | ubifs_assert(wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0); | 516 | ubifs_assert(wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0); |
516 | ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size); | 517 | ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size); |
@@ -535,8 +536,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
535 | memcpy(wbuf->buf + wbuf->used, buf, len); | 536 | memcpy(wbuf->buf + wbuf->used, buf, len); |
536 | 537 | ||
537 | if (aligned_len == wbuf->avail) { | 538 | if (aligned_len == wbuf->avail) { |
538 | dbg_io("flush jhead %d wbuf to LEB %d:%d", | 539 | dbg_io("flush jhead %s wbuf to LEB %d:%d", |
539 | wbuf->jhead, wbuf->lnum, wbuf->offs); | 540 | dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs); |
540 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, | 541 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, |
541 | wbuf->offs, c->min_io_size, | 542 | wbuf->offs, c->min_io_size, |
542 | wbuf->dtype); | 543 | wbuf->dtype); |
@@ -564,8 +565,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
564 | * minimal I/O unit. We have to fill and flush write-buffer and switch | 565 | * minimal I/O unit. We have to fill and flush write-buffer and switch |
565 | * to the next min. I/O unit. | 566 | * to the next min. I/O unit. |
566 | */ | 567 | */ |
567 | dbg_io("flush jhead %d wbuf to LEB %d:%d", | 568 | dbg_io("flush jhead %s wbuf to LEB %d:%d", |
568 | wbuf->jhead, wbuf->lnum, wbuf->offs); | 569 | dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs); |
569 | memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail); | 570 | memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail); |
570 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, | 571 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, |
571 | c->min_io_size, wbuf->dtype); | 572 | c->min_io_size, wbuf->dtype); |
@@ -698,8 +699,8 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, | |||
698 | int err, rlen, overlap; | 699 | int err, rlen, overlap; |
699 | struct ubifs_ch *ch = buf; | 700 | struct ubifs_ch *ch = buf; |
700 | 701 | ||
701 | dbg_io("LEB %d:%d, %s, length %d, jhead %d", lnum, offs, | 702 | dbg_io("LEB %d:%d, %s, length %d, jhead %s", lnum, offs, |
702 | dbg_ntype(type), len, wbuf->jhead); | 703 | dbg_ntype(type), len, dbg_jhead(wbuf->jhead)); |
703 | ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0); | 704 | ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0); |
704 | ubifs_assert(!(offs & 7) && offs < c->leb_size); | 705 | ubifs_assert(!(offs & 7) && offs < c->leb_size); |
705 | ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT); | 706 | ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT); |
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index 64b5f3a309f5..d321baeca68d 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c | |||
@@ -158,7 +158,7 @@ again: | |||
158 | * some. But the write-buffer mutex has to be unlocked because | 158 | * some. But the write-buffer mutex has to be unlocked because |
159 | * GC also takes it. | 159 | * GC also takes it. |
160 | */ | 160 | */ |
161 | dbg_jnl("no free space jhead %d, run GC", jhead); | 161 | dbg_jnl("no free space in jhead %s, run GC", dbg_jhead(jhead)); |
162 | mutex_unlock(&wbuf->io_mutex); | 162 | mutex_unlock(&wbuf->io_mutex); |
163 | 163 | ||
164 | lnum = ubifs_garbage_collect(c, 0); | 164 | lnum = ubifs_garbage_collect(c, 0); |
@@ -173,7 +173,8 @@ again: | |||
173 | * because we dropped @wbuf->io_mutex, so try once | 173 | * because we dropped @wbuf->io_mutex, so try once |
174 | * again. | 174 | * again. |
175 | */ | 175 | */ |
176 | dbg_jnl("GC couldn't make a free LEB for jhead %d", jhead); | 176 | dbg_jnl("GC couldn't make a free LEB for jhead %s", |
177 | dbg_jhead(jhead)); | ||
177 | if (retries++ < 2) { | 178 | if (retries++ < 2) { |
178 | dbg_jnl("retry (%d)", retries); | 179 | dbg_jnl("retry (%d)", retries); |
179 | goto again; | 180 | goto again; |
@@ -184,7 +185,7 @@ again: | |||
184 | } | 185 | } |
185 | 186 | ||
186 | mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); | 187 | mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); |
187 | dbg_jnl("got LEB %d for jhead %d", lnum, jhead); | 188 | dbg_jnl("got LEB %d for jhead %s", lnum, dbg_jhead(jhead)); |
188 | avail = c->leb_size - wbuf->offs - wbuf->used; | 189 | avail = c->leb_size - wbuf->offs - wbuf->used; |
189 | 190 | ||
190 | if (wbuf->lnum != -1 && avail >= len) { | 191 | if (wbuf->lnum != -1 && avail >= len) { |
@@ -255,7 +256,8 @@ static int write_node(struct ubifs_info *c, int jhead, void *node, int len, | |||
255 | *lnum = c->jheads[jhead].wbuf.lnum; | 256 | *lnum = c->jheads[jhead].wbuf.lnum; |
256 | *offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used; | 257 | *offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used; |
257 | 258 | ||
258 | dbg_jnl("jhead %d, LEB %d:%d, len %d", jhead, *lnum, *offs, len); | 259 | dbg_jnl("jhead %s, LEB %d:%d, len %d", |
260 | dbg_jhead(jhead), *lnum, *offs, len); | ||
259 | ubifs_prepare_node(c, node, len, 0); | 261 | ubifs_prepare_node(c, node, len, 0); |
260 | 262 | ||
261 | return ubifs_wbuf_write_nolock(wbuf, node, len); | 263 | return ubifs_wbuf_write_nolock(wbuf, node, len); |
@@ -285,7 +287,8 @@ static int write_head(struct ubifs_info *c, int jhead, void *buf, int len, | |||
285 | 287 | ||
286 | *lnum = c->jheads[jhead].wbuf.lnum; | 288 | *lnum = c->jheads[jhead].wbuf.lnum; |
287 | *offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used; | 289 | *offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used; |
288 | dbg_jnl("jhead %d, LEB %d:%d, len %d", jhead, *lnum, *offs, len); | 290 | dbg_jnl("jhead %s, LEB %d:%d, len %d", |
291 | dbg_jhead(jhead), *lnum, *offs, len); | ||
289 | 292 | ||
290 | err = ubifs_wbuf_write_nolock(wbuf, buf, len); | 293 | err = ubifs_wbuf_write_nolock(wbuf, buf, len); |
291 | if (err) | 294 | if (err) |
diff --git a/fs/ubifs/key.h b/fs/ubifs/key.h index 5fa27ea031ba..0f530c684f0b 100644 --- a/fs/ubifs/key.h +++ b/fs/ubifs/key.h | |||
@@ -229,23 +229,6 @@ static inline void xent_key_init(const struct ubifs_info *c, | |||
229 | } | 229 | } |
230 | 230 | ||
231 | /** | 231 | /** |
232 | * xent_key_init_hash - initialize extended attribute entry key without | ||
233 | * re-calculating hash function. | ||
234 | * @c: UBIFS file-system description object | ||
235 | * @key: key to initialize | ||
236 | * @inum: host inode number | ||
237 | * @hash: extended attribute entry name hash | ||
238 | */ | ||
239 | static inline void xent_key_init_hash(const struct ubifs_info *c, | ||
240 | union ubifs_key *key, ino_t inum, | ||
241 | uint32_t hash) | ||
242 | { | ||
243 | ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); | ||
244 | key->u32[0] = inum; | ||
245 | key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS); | ||
246 | } | ||
247 | |||
248 | /** | ||
249 | * xent_key_init_flash - initialize on-flash extended attribute entry key. | 232 | * xent_key_init_flash - initialize on-flash extended attribute entry key. |
250 | * @c: UBIFS file-system description object | 233 | * @c: UBIFS file-system description object |
251 | * @k: key to initialize | 234 | * @k: key to initialize |
@@ -295,22 +278,15 @@ static inline void data_key_init(const struct ubifs_info *c, | |||
295 | } | 278 | } |
296 | 279 | ||
297 | /** | 280 | /** |
298 | * data_key_init_flash - initialize on-flash data key. | 281 | * highest_data_key - get the highest possible data key for an inode. |
299 | * @c: UBIFS file-system description object | 282 | * @c: UBIFS file-system description object |
300 | * @k: key to initialize | 283 | * @key: key to initialize |
301 | * @inum: inode number | 284 | * @inum: inode number |
302 | * @block: block number | ||
303 | */ | 285 | */ |
304 | static inline void data_key_init_flash(const struct ubifs_info *c, void *k, | 286 | static inline void highest_data_key(const struct ubifs_info *c, |
305 | ino_t inum, unsigned int block) | 287 | union ubifs_key *key, ino_t inum) |
306 | { | 288 | { |
307 | union ubifs_key *key = k; | 289 | data_key_init(c, key, inum, UBIFS_S_KEY_BLOCK_MASK); |
308 | |||
309 | ubifs_assert(!(block & ~UBIFS_S_KEY_BLOCK_MASK)); | ||
310 | key->j32[0] = cpu_to_le32(inum); | ||
311 | key->j32[1] = cpu_to_le32(block | | ||
312 | (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS)); | ||
313 | memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8); | ||
314 | } | 290 | } |
315 | 291 | ||
316 | /** | 292 | /** |
@@ -554,4 +530,5 @@ static inline unsigned long long key_max_inode_size(const struct ubifs_info *c) | |||
554 | return 0; | 530 | return 0; |
555 | } | 531 | } |
556 | } | 532 | } |
533 | |||
557 | #endif /* !__UBIFS_KEY_H__ */ | 534 | #endif /* !__UBIFS_KEY_H__ */ |
diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c index 56e33772a1ee..c345e125f42c 100644 --- a/fs/ubifs/log.c +++ b/fs/ubifs/log.c | |||
@@ -169,8 +169,8 @@ void ubifs_add_bud(struct ubifs_info *c, struct ubifs_bud *bud) | |||
169 | */ | 169 | */ |
170 | c->bud_bytes += c->leb_size - bud->start; | 170 | c->bud_bytes += c->leb_size - bud->start; |
171 | 171 | ||
172 | dbg_log("LEB %d:%d, jhead %d, bud_bytes %lld", bud->lnum, | 172 | dbg_log("LEB %d:%d, jhead %s, bud_bytes %lld", bud->lnum, |
173 | bud->start, bud->jhead, c->bud_bytes); | 173 | bud->start, dbg_jhead(bud->jhead), c->bud_bytes); |
174 | spin_unlock(&c->buds_lock); | 174 | spin_unlock(&c->buds_lock); |
175 | } | 175 | } |
176 | 176 | ||
@@ -355,16 +355,16 @@ static void remove_buds(struct ubifs_info *c) | |||
355 | * heads (non-closed buds). | 355 | * heads (non-closed buds). |
356 | */ | 356 | */ |
357 | c->cmt_bud_bytes += wbuf->offs - bud->start; | 357 | c->cmt_bud_bytes += wbuf->offs - bud->start; |
358 | dbg_log("preserve %d:%d, jhead %d, bud bytes %d, " | 358 | dbg_log("preserve %d:%d, jhead %s, bud bytes %d, " |
359 | "cmt_bud_bytes %lld", bud->lnum, bud->start, | 359 | "cmt_bud_bytes %lld", bud->lnum, bud->start, |
360 | bud->jhead, wbuf->offs - bud->start, | 360 | dbg_jhead(bud->jhead), wbuf->offs - bud->start, |
361 | c->cmt_bud_bytes); | 361 | c->cmt_bud_bytes); |
362 | bud->start = wbuf->offs; | 362 | bud->start = wbuf->offs; |
363 | } else { | 363 | } else { |
364 | c->cmt_bud_bytes += c->leb_size - bud->start; | 364 | c->cmt_bud_bytes += c->leb_size - bud->start; |
365 | dbg_log("remove %d:%d, jhead %d, bud bytes %d, " | 365 | dbg_log("remove %d:%d, jhead %s, bud bytes %d, " |
366 | "cmt_bud_bytes %lld", bud->lnum, bud->start, | 366 | "cmt_bud_bytes %lld", bud->lnum, bud->start, |
367 | bud->jhead, c->leb_size - bud->start, | 367 | dbg_jhead(bud->jhead), c->leb_size - bud->start, |
368 | c->cmt_bud_bytes); | 368 | c->cmt_bud_bytes); |
369 | rb_erase(p1, &c->buds); | 369 | rb_erase(p1, &c->buds); |
370 | /* | 370 | /* |
@@ -429,7 +429,8 @@ int ubifs_log_start_commit(struct ubifs_info *c, int *ltail_lnum) | |||
429 | if (lnum == -1 || offs == c->leb_size) | 429 | if (lnum == -1 || offs == c->leb_size) |
430 | continue; | 430 | continue; |
431 | 431 | ||
432 | dbg_log("add ref to LEB %d:%d for jhead %d", lnum, offs, i); | 432 | dbg_log("add ref to LEB %d:%d for jhead %s", |
433 | lnum, offs, dbg_jhead(i)); | ||
433 | ref = buf + len; | 434 | ref = buf + len; |
434 | ref->ch.node_type = UBIFS_REF_NODE; | 435 | ref->ch.node_type = UBIFS_REF_NODE; |
435 | ref->lnum = cpu_to_le32(lnum); | 436 | ref->lnum = cpu_to_le32(lnum); |
@@ -695,7 +696,7 @@ int ubifs_consolidate_log(struct ubifs_info *c) | |||
695 | lnum = c->ltail_lnum; | 696 | lnum = c->ltail_lnum; |
696 | write_lnum = lnum; | 697 | write_lnum = lnum; |
697 | while (1) { | 698 | while (1) { |
698 | sleb = ubifs_scan(c, lnum, 0, c->sbuf); | 699 | sleb = ubifs_scan(c, lnum, 0, c->sbuf, 0); |
699 | if (IS_ERR(sleb)) { | 700 | if (IS_ERR(sleb)) { |
700 | err = PTR_ERR(sleb); | 701 | err = PTR_ERR(sleb); |
701 | goto out_free; | 702 | goto out_free; |
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c index 4cdd284dea56..4d4ca388889b 100644 --- a/fs/ubifs/lprops.c +++ b/fs/ubifs/lprops.c | |||
@@ -281,7 +281,7 @@ void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops, | |||
281 | case LPROPS_FREE: | 281 | case LPROPS_FREE: |
282 | if (add_to_lpt_heap(c, lprops, cat)) | 282 | if (add_to_lpt_heap(c, lprops, cat)) |
283 | break; | 283 | break; |
284 | /* No more room on heap so make it uncategorized */ | 284 | /* No more room on heap so make it un-categorized */ |
285 | cat = LPROPS_UNCAT; | 285 | cat = LPROPS_UNCAT; |
286 | /* Fall through */ | 286 | /* Fall through */ |
287 | case LPROPS_UNCAT: | 287 | case LPROPS_UNCAT: |
@@ -375,8 +375,8 @@ void ubifs_replace_cat(struct ubifs_info *c, struct ubifs_lprops *old_lprops, | |||
375 | * @lprops: LEB properties | 375 | * @lprops: LEB properties |
376 | * | 376 | * |
377 | * A LEB may have fallen off of the bottom of a heap, and ended up as | 377 | * A LEB may have fallen off of the bottom of a heap, and ended up as |
378 | * uncategorized even though it has enough space for us now. If that is the case | 378 | * un-categorized even though it has enough space for us now. If that is the |
379 | * this function will put the LEB back onto a heap. | 379 | * case this function will put the LEB back onto a heap. |
380 | */ | 380 | */ |
381 | void ubifs_ensure_cat(struct ubifs_info *c, struct ubifs_lprops *lprops) | 381 | void ubifs_ensure_cat(struct ubifs_info *c, struct ubifs_lprops *lprops) |
382 | { | 382 | { |
@@ -436,10 +436,10 @@ int ubifs_categorize_lprops(const struct ubifs_info *c, | |||
436 | /** | 436 | /** |
437 | * change_category - change LEB properties category. | 437 | * change_category - change LEB properties category. |
438 | * @c: UBIFS file-system description object | 438 | * @c: UBIFS file-system description object |
439 | * @lprops: LEB properties to recategorize | 439 | * @lprops: LEB properties to re-categorize |
440 | * | 440 | * |
441 | * LEB properties are categorized to enable fast find operations. When the LEB | 441 | * LEB properties are categorized to enable fast find operations. When the LEB |
442 | * properties change they must be recategorized. | 442 | * properties change they must be re-categorized. |
443 | */ | 443 | */ |
444 | static void change_category(struct ubifs_info *c, struct ubifs_lprops *lprops) | 444 | static void change_category(struct ubifs_info *c, struct ubifs_lprops *lprops) |
445 | { | 445 | { |
@@ -461,21 +461,18 @@ static void change_category(struct ubifs_info *c, struct ubifs_lprops *lprops) | |||
461 | } | 461 | } |
462 | 462 | ||
463 | /** | 463 | /** |
464 | * calc_dark - calculate LEB dark space size. | 464 | * ubifs_calc_dark - calculate LEB dark space size. |
465 | * @c: the UBIFS file-system description object | 465 | * @c: the UBIFS file-system description object |
466 | * @spc: amount of free and dirty space in the LEB | 466 | * @spc: amount of free and dirty space in the LEB |
467 | * | 467 | * |
468 | * This function calculates amount of dark space in an LEB which has @spc bytes | 468 | * This function calculates and returns amount of dark space in an LEB which |
469 | * of free and dirty space. Returns the calculations result. | 469 | * has @spc bytes of free and dirty space. |
470 | * | 470 | * |
471 | * Dark space is the space which is not always usable - it depends on which | 471 | * UBIFS is trying to account the space which might not be usable, and this |
472 | * nodes are written in which order. E.g., if an LEB has only 512 free bytes, | 472 | * space is called "dark space". For example, if an LEB has only %512 free |
473 | * it is dark space, because it cannot fit a large data node. So UBIFS cannot | 473 | * bytes, it is dark space, because it cannot fit a large data node. |
474 | * count on this LEB and treat these 512 bytes as usable because it is not true | ||
475 | * if, for example, only big chunks of uncompressible data will be written to | ||
476 | * the FS. | ||
477 | */ | 474 | */ |
478 | static int calc_dark(struct ubifs_info *c, int spc) | 475 | int ubifs_calc_dark(const struct ubifs_info *c, int spc) |
479 | { | 476 | { |
480 | ubifs_assert(!(spc & 7)); | 477 | ubifs_assert(!(spc & 7)); |
481 | 478 | ||
@@ -518,7 +515,7 @@ static int is_lprops_dirty(struct ubifs_info *c, struct ubifs_lprops *lprops) | |||
518 | * @free: new free space amount | 515 | * @free: new free space amount |
519 | * @dirty: new dirty space amount | 516 | * @dirty: new dirty space amount |
520 | * @flags: new flags | 517 | * @flags: new flags |
521 | * @idx_gc_cnt: change to the count of idx_gc list | 518 | * @idx_gc_cnt: change to the count of @idx_gc list |
522 | * | 519 | * |
523 | * This function changes LEB properties (@free, @dirty or @flag). However, the | 520 | * This function changes LEB properties (@free, @dirty or @flag). However, the |
524 | * property which has the %LPROPS_NC value is not changed. Returns a pointer to | 521 | * property which has the %LPROPS_NC value is not changed. Returns a pointer to |
@@ -535,7 +532,7 @@ const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c, | |||
535 | { | 532 | { |
536 | /* | 533 | /* |
537 | * This is the only function that is allowed to change lprops, so we | 534 | * This is the only function that is allowed to change lprops, so we |
538 | * discard the const qualifier. | 535 | * discard the "const" qualifier. |
539 | */ | 536 | */ |
540 | struct ubifs_lprops *lprops = (struct ubifs_lprops *)lp; | 537 | struct ubifs_lprops *lprops = (struct ubifs_lprops *)lp; |
541 | 538 | ||
@@ -575,7 +572,7 @@ const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c, | |||
575 | if (old_spc < c->dead_wm) | 572 | if (old_spc < c->dead_wm) |
576 | c->lst.total_dead -= old_spc; | 573 | c->lst.total_dead -= old_spc; |
577 | else | 574 | else |
578 | c->lst.total_dark -= calc_dark(c, old_spc); | 575 | c->lst.total_dark -= ubifs_calc_dark(c, old_spc); |
579 | 576 | ||
580 | c->lst.total_used -= c->leb_size - old_spc; | 577 | c->lst.total_used -= c->leb_size - old_spc; |
581 | } | 578 | } |
@@ -616,7 +613,7 @@ const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c, | |||
616 | if (new_spc < c->dead_wm) | 613 | if (new_spc < c->dead_wm) |
617 | c->lst.total_dead += new_spc; | 614 | c->lst.total_dead += new_spc; |
618 | else | 615 | else |
619 | c->lst.total_dark += calc_dark(c, new_spc); | 616 | c->lst.total_dark += ubifs_calc_dark(c, new_spc); |
620 | 617 | ||
621 | c->lst.total_used += c->leb_size - new_spc; | 618 | c->lst.total_used += c->leb_size - new_spc; |
622 | } | 619 | } |
@@ -1096,7 +1093,7 @@ static int scan_check_cb(struct ubifs_info *c, | |||
1096 | } | 1093 | } |
1097 | } | 1094 | } |
1098 | 1095 | ||
1099 | sleb = ubifs_scan(c, lnum, 0, c->dbg->buf); | 1096 | sleb = ubifs_scan(c, lnum, 0, c->dbg->buf, 0); |
1100 | if (IS_ERR(sleb)) { | 1097 | if (IS_ERR(sleb)) { |
1101 | /* | 1098 | /* |
1102 | * After an unclean unmount, empty and freeable LEBs | 1099 | * After an unclean unmount, empty and freeable LEBs |
@@ -1107,7 +1104,7 @@ static int scan_check_cb(struct ubifs_info *c, | |||
1107 | "- continuing checking"); | 1104 | "- continuing checking"); |
1108 | lst->empty_lebs += 1; | 1105 | lst->empty_lebs += 1; |
1109 | lst->total_free += c->leb_size; | 1106 | lst->total_free += c->leb_size; |
1110 | lst->total_dark += calc_dark(c, c->leb_size); | 1107 | lst->total_dark += ubifs_calc_dark(c, c->leb_size); |
1111 | return LPT_SCAN_CONTINUE; | 1108 | return LPT_SCAN_CONTINUE; |
1112 | } | 1109 | } |
1113 | 1110 | ||
@@ -1117,7 +1114,7 @@ static int scan_check_cb(struct ubifs_info *c, | |||
1117 | "- continuing checking"); | 1114 | "- continuing checking"); |
1118 | lst->total_free += lp->free; | 1115 | lst->total_free += lp->free; |
1119 | lst->total_dirty += lp->dirty; | 1116 | lst->total_dirty += lp->dirty; |
1120 | lst->total_dark += calc_dark(c, c->leb_size); | 1117 | lst->total_dark += ubifs_calc_dark(c, c->leb_size); |
1121 | return LPT_SCAN_CONTINUE; | 1118 | return LPT_SCAN_CONTINUE; |
1122 | } | 1119 | } |
1123 | data->err = PTR_ERR(sleb); | 1120 | data->err = PTR_ERR(sleb); |
@@ -1235,7 +1232,7 @@ static int scan_check_cb(struct ubifs_info *c, | |||
1235 | if (spc < c->dead_wm) | 1232 | if (spc < c->dead_wm) |
1236 | lst->total_dead += spc; | 1233 | lst->total_dead += spc; |
1237 | else | 1234 | else |
1238 | lst->total_dark += calc_dark(c, spc); | 1235 | lst->total_dark += ubifs_calc_dark(c, spc); |
1239 | } | 1236 | } |
1240 | 1237 | ||
1241 | ubifs_scan_destroy(sleb); | 1238 | ubifs_scan_destroy(sleb); |
diff --git a/fs/ubifs/master.c b/fs/ubifs/master.c index a88f33801b98..28beaeedadc0 100644 --- a/fs/ubifs/master.c +++ b/fs/ubifs/master.c | |||
@@ -29,7 +29,8 @@ | |||
29 | * @c: UBIFS file-system description object | 29 | * @c: UBIFS file-system description object |
30 | * | 30 | * |
31 | * This function scans the master node LEBs and search for the latest master | 31 | * This function scans the master node LEBs and search for the latest master |
32 | * node. Returns zero in case of success and a negative error code in case of | 32 | * node. Returns zero in case of success, %-EUCLEAN if there master area is |
33 | * corrupted and requires recovery, and a negative error code in case of | ||
33 | * failure. | 34 | * failure. |
34 | */ | 35 | */ |
35 | static int scan_for_master(struct ubifs_info *c) | 36 | static int scan_for_master(struct ubifs_info *c) |
@@ -40,7 +41,7 @@ static int scan_for_master(struct ubifs_info *c) | |||
40 | 41 | ||
41 | lnum = UBIFS_MST_LNUM; | 42 | lnum = UBIFS_MST_LNUM; |
42 | 43 | ||
43 | sleb = ubifs_scan(c, lnum, 0, c->sbuf); | 44 | sleb = ubifs_scan(c, lnum, 0, c->sbuf, 1); |
44 | if (IS_ERR(sleb)) | 45 | if (IS_ERR(sleb)) |
45 | return PTR_ERR(sleb); | 46 | return PTR_ERR(sleb); |
46 | nodes_cnt = sleb->nodes_cnt; | 47 | nodes_cnt = sleb->nodes_cnt; |
@@ -48,7 +49,7 @@ static int scan_for_master(struct ubifs_info *c) | |||
48 | snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, | 49 | snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, |
49 | list); | 50 | list); |
50 | if (snod->type != UBIFS_MST_NODE) | 51 | if (snod->type != UBIFS_MST_NODE) |
51 | goto out; | 52 | goto out_dump; |
52 | memcpy(c->mst_node, snod->node, snod->len); | 53 | memcpy(c->mst_node, snod->node, snod->len); |
53 | offs = snod->offs; | 54 | offs = snod->offs; |
54 | } | 55 | } |
@@ -56,7 +57,7 @@ static int scan_for_master(struct ubifs_info *c) | |||
56 | 57 | ||
57 | lnum += 1; | 58 | lnum += 1; |
58 | 59 | ||
59 | sleb = ubifs_scan(c, lnum, 0, c->sbuf); | 60 | sleb = ubifs_scan(c, lnum, 0, c->sbuf, 1); |
60 | if (IS_ERR(sleb)) | 61 | if (IS_ERR(sleb)) |
61 | return PTR_ERR(sleb); | 62 | return PTR_ERR(sleb); |
62 | if (sleb->nodes_cnt != nodes_cnt) | 63 | if (sleb->nodes_cnt != nodes_cnt) |
@@ -65,7 +66,7 @@ static int scan_for_master(struct ubifs_info *c) | |||
65 | goto out; | 66 | goto out; |
66 | snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, list); | 67 | snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, list); |
67 | if (snod->type != UBIFS_MST_NODE) | 68 | if (snod->type != UBIFS_MST_NODE) |
68 | goto out; | 69 | goto out_dump; |
69 | if (snod->offs != offs) | 70 | if (snod->offs != offs) |
70 | goto out; | 71 | goto out; |
71 | if (memcmp((void *)c->mst_node + UBIFS_CH_SZ, | 72 | if (memcmp((void *)c->mst_node + UBIFS_CH_SZ, |
@@ -78,6 +79,12 @@ static int scan_for_master(struct ubifs_info *c) | |||
78 | 79 | ||
79 | out: | 80 | out: |
80 | ubifs_scan_destroy(sleb); | 81 | ubifs_scan_destroy(sleb); |
82 | return -EUCLEAN; | ||
83 | |||
84 | out_dump: | ||
85 | ubifs_err("unexpected node type %d master LEB %d:%d", | ||
86 | snod->type, lnum, snod->offs); | ||
87 | ubifs_scan_destroy(sleb); | ||
81 | return -EINVAL; | 88 | return -EINVAL; |
82 | } | 89 | } |
83 | 90 | ||
@@ -256,7 +263,8 @@ int ubifs_read_master(struct ubifs_info *c) | |||
256 | 263 | ||
257 | err = scan_for_master(c); | 264 | err = scan_for_master(c); |
258 | if (err) { | 265 | if (err) { |
259 | err = ubifs_recover_master_node(c); | 266 | if (err == -EUCLEAN) |
267 | err = ubifs_recover_master_node(c); | ||
260 | if (err) | 268 | if (err) |
261 | /* | 269 | /* |
262 | * Note, we do not free 'c->mst_node' here because the | 270 | * Note, we do not free 'c->mst_node' here because the |
diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c index 152a7b34a141..82009c74b6a3 100644 --- a/fs/ubifs/orphan.c +++ b/fs/ubifs/orphan.c | |||
@@ -670,9 +670,10 @@ static int kill_orphans(struct ubifs_info *c) | |||
670 | struct ubifs_scan_leb *sleb; | 670 | struct ubifs_scan_leb *sleb; |
671 | 671 | ||
672 | dbg_rcvry("LEB %d", lnum); | 672 | dbg_rcvry("LEB %d", lnum); |
673 | sleb = ubifs_scan(c, lnum, 0, c->sbuf); | 673 | sleb = ubifs_scan(c, lnum, 0, c->sbuf, 1); |
674 | if (IS_ERR(sleb)) { | 674 | if (IS_ERR(sleb)) { |
675 | sleb = ubifs_recover_leb(c, lnum, 0, c->sbuf, 0); | 675 | if (PTR_ERR(sleb) == -EUCLEAN) |
676 | sleb = ubifs_recover_leb(c, lnum, 0, c->sbuf, 0); | ||
676 | if (IS_ERR(sleb)) { | 677 | if (IS_ERR(sleb)) { |
677 | err = PTR_ERR(sleb); | 678 | err = PTR_ERR(sleb); |
678 | break; | 679 | break; |
@@ -899,7 +900,7 @@ static int dbg_scan_orphans(struct ubifs_info *c, struct check_info *ci) | |||
899 | for (lnum = c->orph_first; lnum <= c->orph_last; lnum++) { | 900 | for (lnum = c->orph_first; lnum <= c->orph_last; lnum++) { |
900 | struct ubifs_scan_leb *sleb; | 901 | struct ubifs_scan_leb *sleb; |
901 | 902 | ||
902 | sleb = ubifs_scan(c, lnum, 0, c->dbg->buf); | 903 | sleb = ubifs_scan(c, lnum, 0, c->dbg->buf, 0); |
903 | if (IS_ERR(sleb)) { | 904 | if (IS_ERR(sleb)) { |
904 | err = PTR_ERR(sleb); | 905 | err = PTR_ERR(sleb); |
905 | break; | 906 | break; |
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index e5f6cf8a1155..f94ddf7efba0 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c | |||
@@ -286,7 +286,7 @@ int ubifs_recover_master_node(struct ubifs_info *c) | |||
286 | mst = mst2; | 286 | mst = mst2; |
287 | } | 287 | } |
288 | 288 | ||
289 | dbg_rcvry("recovered master node from LEB %d", | 289 | ubifs_msg("recovered master node from LEB %d", |
290 | (mst == mst1 ? UBIFS_MST_LNUM : UBIFS_MST_LNUM + 1)); | 290 | (mst == mst1 ? UBIFS_MST_LNUM : UBIFS_MST_LNUM + 1)); |
291 | 291 | ||
292 | memcpy(c->mst_node, mst, UBIFS_MST_NODE_SZ); | 292 | memcpy(c->mst_node, mst, UBIFS_MST_NODE_SZ); |
@@ -790,7 +790,7 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, | |||
790 | * We can only recover at the end of the log, so check that the | 790 | * We can only recover at the end of the log, so check that the |
791 | * next log LEB is empty or out of date. | 791 | * next log LEB is empty or out of date. |
792 | */ | 792 | */ |
793 | sleb = ubifs_scan(c, next_lnum, 0, sbuf); | 793 | sleb = ubifs_scan(c, next_lnum, 0, sbuf, 0); |
794 | if (IS_ERR(sleb)) | 794 | if (IS_ERR(sleb)) |
795 | return sleb; | 795 | return sleb; |
796 | if (sleb->nodes_cnt) { | 796 | if (sleb->nodes_cnt) { |
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index 2970500f32df..5c2d6d759a3e 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c | |||
@@ -506,7 +506,7 @@ static int replay_bud(struct ubifs_info *c, int lnum, int offs, int jhead, | |||
506 | if (c->need_recovery) | 506 | if (c->need_recovery) |
507 | sleb = ubifs_recover_leb(c, lnum, offs, c->sbuf, jhead != GCHD); | 507 | sleb = ubifs_recover_leb(c, lnum, offs, c->sbuf, jhead != GCHD); |
508 | else | 508 | else |
509 | sleb = ubifs_scan(c, lnum, offs, c->sbuf); | 509 | sleb = ubifs_scan(c, lnum, offs, c->sbuf, 0); |
510 | if (IS_ERR(sleb)) | 510 | if (IS_ERR(sleb)) |
511 | return PTR_ERR(sleb); | 511 | return PTR_ERR(sleb); |
512 | 512 | ||
@@ -836,8 +836,8 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) | |||
836 | const struct ubifs_cs_node *node; | 836 | const struct ubifs_cs_node *node; |
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, c->need_recovery); |
840 | if (IS_ERR(sleb) ) { | 840 | if (IS_ERR(sleb)) { |
841 | if (PTR_ERR(sleb) != -EUCLEAN || !c->need_recovery) | 841 | if (PTR_ERR(sleb) != -EUCLEAN || !c->need_recovery) |
842 | return PTR_ERR(sleb); | 842 | return PTR_ERR(sleb); |
843 | sleb = ubifs_recover_log_leb(c, lnum, offs, sbuf); | 843 | sleb = ubifs_recover_log_leb(c, lnum, offs, sbuf); |
diff --git a/fs/ubifs/scan.c b/fs/ubifs/scan.c index 892ebfee4fe5..96c525384191 100644 --- a/fs/ubifs/scan.c +++ b/fs/ubifs/scan.c | |||
@@ -108,10 +108,9 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum, | |||
108 | 108 | ||
109 | /* Make the node pads to 8-byte boundary */ | 109 | /* Make the node pads to 8-byte boundary */ |
110 | if ((node_len + pad_len) & 7) { | 110 | if ((node_len + pad_len) & 7) { |
111 | if (!quiet) { | 111 | if (!quiet) |
112 | dbg_err("bad padding length %d - %d", | 112 | dbg_err("bad padding length %d - %d", |
113 | offs, offs + node_len + pad_len); | 113 | offs, offs + node_len + pad_len); |
114 | } | ||
115 | return SCANNED_A_BAD_PAD_NODE; | 114 | return SCANNED_A_BAD_PAD_NODE; |
116 | } | 115 | } |
117 | 116 | ||
@@ -253,15 +252,19 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs, | |||
253 | * @c: UBIFS file-system description object | 252 | * @c: UBIFS file-system description object |
254 | * @lnum: logical eraseblock number | 253 | * @lnum: logical eraseblock number |
255 | * @offs: offset to start at (usually zero) | 254 | * @offs: offset to start at (usually zero) |
256 | * @sbuf: scan buffer (must be c->leb_size) | 255 | * @sbuf: scan buffer (must be of @c->leb_size bytes in size) |
256 | * @quiet: print no messages | ||
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 the scaned information in case of success and, | 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 | 260 | * %-EUCLEAN if the LEB neads recovery, and other negative error codes in case |
261 | * of failure. | 261 | * of failure. |
262 | * | ||
263 | * If @quiet is non-zero, this function does not print large and scary | ||
264 | * error messages and flash dumps in case of errors. | ||
262 | */ | 265 | */ |
263 | struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | 266 | struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, |
264 | int offs, void *sbuf) | 267 | int offs, void *sbuf, int quiet) |
265 | { | 268 | { |
266 | void *buf = sbuf + offs; | 269 | void *buf = sbuf + offs; |
267 | int err, len = c->leb_size - offs; | 270 | int err, len = c->leb_size - offs; |
@@ -280,7 +283,7 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | |||
280 | 283 | ||
281 | cond_resched(); | 284 | cond_resched(); |
282 | 285 | ||
283 | ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 0); | 286 | ret = ubifs_scan_a_node(c, buf, len, lnum, offs, quiet); |
284 | if (ret > 0) { | 287 | if (ret > 0) { |
285 | /* Padding bytes or a valid padding node */ | 288 | /* Padding bytes or a valid padding node */ |
286 | offs += ret; | 289 | offs += ret; |
@@ -320,7 +323,9 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | |||
320 | } | 323 | } |
321 | 324 | ||
322 | if (offs % c->min_io_size) { | 325 | if (offs % c->min_io_size) { |
323 | ubifs_err("empty space starts at non-aligned offset %d", offs); | 326 | if (!quiet) |
327 | ubifs_err("empty space starts at non-aligned offset %d", | ||
328 | offs); | ||
324 | goto corrupted;; | 329 | goto corrupted;; |
325 | } | 330 | } |
326 | 331 | ||
@@ -331,18 +336,25 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | |||
331 | break; | 336 | break; |
332 | for (; len; offs++, buf++, len--) | 337 | for (; len; offs++, buf++, len--) |
333 | if (*(uint8_t *)buf != 0xff) { | 338 | if (*(uint8_t *)buf != 0xff) { |
334 | ubifs_err("corrupt empty space at LEB %d:%d", | 339 | if (!quiet) |
335 | lnum, offs); | 340 | ubifs_err("corrupt empty space at LEB %d:%d", |
341 | lnum, offs); | ||
336 | goto corrupted; | 342 | goto corrupted; |
337 | } | 343 | } |
338 | 344 | ||
339 | return sleb; | 345 | return sleb; |
340 | 346 | ||
341 | corrupted: | 347 | corrupted: |
342 | ubifs_scanned_corruption(c, lnum, offs, buf); | 348 | if (!quiet) { |
349 | ubifs_scanned_corruption(c, lnum, offs, buf); | ||
350 | ubifs_err("LEB %d scanning failed", lnum); | ||
351 | } | ||
343 | err = -EUCLEAN; | 352 | err = -EUCLEAN; |
353 | ubifs_scan_destroy(sleb); | ||
354 | return ERR_PTR(err); | ||
355 | |||
344 | error: | 356 | error: |
345 | ubifs_err("LEB %d scanning failed", lnum); | 357 | ubifs_err("LEB %d scanning failed, error %d", lnum, err); |
346 | ubifs_scan_destroy(sleb); | 358 | ubifs_scan_destroy(sleb); |
347 | return ERR_PTR(err); | 359 | return ERR_PTR(err); |
348 | } | 360 | } |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index c4af069df1ad..333e181ee987 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/mount.h> | 36 | #include <linux/mount.h> |
37 | #include <linux/math64.h> | 37 | #include <linux/math64.h> |
38 | #include <linux/writeback.h> | 38 | #include <linux/writeback.h> |
39 | #include <linux/smp_lock.h> | ||
40 | #include "ubifs.h" | 39 | #include "ubifs.h" |
41 | 40 | ||
42 | /* | 41 | /* |
@@ -318,6 +317,8 @@ static int ubifs_write_inode(struct inode *inode, int wait) | |||
318 | if (err) | 317 | if (err) |
319 | ubifs_err("can't write inode %lu, error %d", | 318 | ubifs_err("can't write inode %lu, error %d", |
320 | inode->i_ino, err); | 319 | inode->i_ino, err); |
320 | else | ||
321 | err = dbg_check_inode_size(c, inode, ui->ui_size); | ||
321 | } | 322 | } |
322 | 323 | ||
323 | ui->dirty = 0; | 324 | ui->dirty = 0; |
@@ -448,17 +449,6 @@ static int ubifs_sync_fs(struct super_block *sb, int wait) | |||
448 | return 0; | 449 | return 0; |
449 | 450 | ||
450 | /* | 451 | /* |
451 | * VFS calls '->sync_fs()' before synchronizing all dirty inodes and | ||
452 | * pages, so synchronize them first, then commit the journal. Strictly | ||
453 | * speaking, it is not necessary to commit the journal here, | ||
454 | * synchronizing write-buffers would be enough. But committing makes | ||
455 | * UBIFS free space predictions much more accurate, so we want to let | ||
456 | * the user be able to get more accurate results of 'statfs()' after | ||
457 | * they synchronize the file system. | ||
458 | */ | ||
459 | sync_inodes_sb(sb); | ||
460 | |||
461 | /* | ||
462 | * Synchronize write buffers, because 'ubifs_run_commit()' does not | 452 | * Synchronize write buffers, because 'ubifs_run_commit()' does not |
463 | * do this if it waits for an already running commit. | 453 | * do this if it waits for an already running commit. |
464 | */ | 454 | */ |
@@ -468,6 +458,13 @@ static int ubifs_sync_fs(struct super_block *sb, int wait) | |||
468 | return err; | 458 | return err; |
469 | } | 459 | } |
470 | 460 | ||
461 | /* | ||
462 | * Strictly speaking, it is not necessary to commit the journal here, | ||
463 | * synchronizing write-buffers would be enough. But committing makes | ||
464 | * UBIFS free space predictions much more accurate, so we want to let | ||
465 | * the user be able to get more accurate results of 'statfs()' after | ||
466 | * they synchronize the file system. | ||
467 | */ | ||
471 | err = ubifs_run_commit(c); | 468 | err = ubifs_run_commit(c); |
472 | if (err) | 469 | if (err) |
473 | return err; | 470 | return err; |
@@ -1720,8 +1717,6 @@ static void ubifs_put_super(struct super_block *sb) | |||
1720 | ubifs_msg("un-mount UBI device %d, volume %d", c->vi.ubi_num, | 1717 | ubifs_msg("un-mount UBI device %d, volume %d", c->vi.ubi_num, |
1721 | c->vi.vol_id); | 1718 | c->vi.vol_id); |
1722 | 1719 | ||
1723 | lock_kernel(); | ||
1724 | |||
1725 | /* | 1720 | /* |
1726 | * The following asserts are only valid if there has not been a failure | 1721 | * The following asserts are only valid if there has not been a failure |
1727 | * of the media. For example, there will be dirty inodes if we failed | 1722 | * of the media. For example, there will be dirty inodes if we failed |
@@ -1786,8 +1781,6 @@ static void ubifs_put_super(struct super_block *sb) | |||
1786 | ubi_close_volume(c->ubi); | 1781 | ubi_close_volume(c->ubi); |
1787 | mutex_unlock(&c->umount_mutex); | 1782 | mutex_unlock(&c->umount_mutex); |
1788 | kfree(c); | 1783 | kfree(c); |
1789 | |||
1790 | unlock_kernel(); | ||
1791 | } | 1784 | } |
1792 | 1785 | ||
1793 | static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) | 1786 | static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) |
@@ -1803,22 +1796,17 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) | |||
1803 | return err; | 1796 | return err; |
1804 | } | 1797 | } |
1805 | 1798 | ||
1806 | lock_kernel(); | ||
1807 | if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { | 1799 | if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { |
1808 | if (c->ro_media) { | 1800 | if (c->ro_media) { |
1809 | ubifs_msg("cannot re-mount due to prior errors"); | 1801 | ubifs_msg("cannot re-mount due to prior errors"); |
1810 | unlock_kernel(); | ||
1811 | return -EROFS; | 1802 | return -EROFS; |
1812 | } | 1803 | } |
1813 | err = ubifs_remount_rw(c); | 1804 | err = ubifs_remount_rw(c); |
1814 | if (err) { | 1805 | if (err) |
1815 | unlock_kernel(); | ||
1816 | return err; | 1806 | return err; |
1817 | } | ||
1818 | } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) { | 1807 | } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) { |
1819 | if (c->ro_media) { | 1808 | if (c->ro_media) { |
1820 | ubifs_msg("cannot re-mount due to prior errors"); | 1809 | ubifs_msg("cannot re-mount due to prior errors"); |
1821 | unlock_kernel(); | ||
1822 | return -EROFS; | 1810 | return -EROFS; |
1823 | } | 1811 | } |
1824 | ubifs_remount_ro(c); | 1812 | ubifs_remount_ro(c); |
@@ -1833,7 +1821,6 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) | |||
1833 | } | 1821 | } |
1834 | 1822 | ||
1835 | ubifs_assert(c->lst.taken_empty_lebs > 0); | 1823 | ubifs_assert(c->lst.taken_empty_lebs > 0); |
1836 | unlock_kernel(); | ||
1837 | return 0; | 1824 | return 0; |
1838 | } | 1825 | } |
1839 | 1826 | ||
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index f249f7b0d656..e5b1a7d00fa0 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c | |||
@@ -1159,8 +1159,8 @@ static struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c, | |||
1159 | * o exact match, i.e. the found zero-level znode contains key @key, then %1 | 1159 | * o exact match, i.e. the found zero-level znode contains key @key, then %1 |
1160 | * is returned and slot number of the matched branch is stored in @n; | 1160 | * is returned and slot number of the matched branch is stored in @n; |
1161 | * o not exact match, which means that zero-level znode does not contain | 1161 | * o not exact match, which means that zero-level znode does not contain |
1162 | * @key, then %0 is returned and slot number of the closed branch is stored | 1162 | * @key, then %0 is returned and slot number of the closest branch is stored |
1163 | * in @n; | 1163 | * in @n; |
1164 | * o @key is so small that it is even less than the lowest key of the | 1164 | * o @key is so small that it is even less than the lowest key of the |
1165 | * leftmost zero-level node, then %0 is returned and %0 is stored in @n. | 1165 | * leftmost zero-level node, then %0 is returned and %0 is stored in @n. |
1166 | * | 1166 | * |
@@ -1433,7 +1433,7 @@ static int maybe_leb_gced(struct ubifs_info *c, int lnum, int gc_seq1) | |||
1433 | * @lnum: LEB number is returned here | 1433 | * @lnum: LEB number is returned here |
1434 | * @offs: offset is returned here | 1434 | * @offs: offset is returned here |
1435 | * | 1435 | * |
1436 | * This function look up and reads node with key @key. The caller has to make | 1436 | * This function looks up and reads node with key @key. The caller has to make |
1437 | * sure the @node buffer is large enough to fit the node. Returns zero in case | 1437 | * sure the @node buffer is large enough to fit the node. Returns zero in case |
1438 | * of success, %-ENOENT if the node was not found, and a negative error code in | 1438 | * of success, %-ENOENT if the node was not found, and a negative error code in |
1439 | * case of failure. The node location can be returned in @lnum and @offs. | 1439 | * case of failure. The node location can be returned in @lnum and @offs. |
@@ -3268,3 +3268,73 @@ out_unlock: | |||
3268 | mutex_unlock(&c->tnc_mutex); | 3268 | mutex_unlock(&c->tnc_mutex); |
3269 | return err; | 3269 | return err; |
3270 | } | 3270 | } |
3271 | |||
3272 | #ifdef CONFIG_UBIFS_FS_DEBUG | ||
3273 | |||
3274 | /** | ||
3275 | * dbg_check_inode_size - check if inode size is correct. | ||
3276 | * @c: UBIFS file-system description object | ||
3277 | * @inum: inode number | ||
3278 | * @size: inode size | ||
3279 | * | ||
3280 | * This function makes sure that the inode size (@size) is correct and it does | ||
3281 | * not have any pages beyond @size. Returns zero if the inode is OK, %-EINVAL | ||
3282 | * if it has a data page beyond @size, and other negative error code in case of | ||
3283 | * other errors. | ||
3284 | */ | ||
3285 | int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode, | ||
3286 | loff_t size) | ||
3287 | { | ||
3288 | int err, n; | ||
3289 | union ubifs_key from_key, to_key, *key; | ||
3290 | struct ubifs_znode *znode; | ||
3291 | unsigned int block; | ||
3292 | |||
3293 | if (!S_ISREG(inode->i_mode)) | ||
3294 | return 0; | ||
3295 | if (!(ubifs_chk_flags & UBIFS_CHK_GEN)) | ||
3296 | return 0; | ||
3297 | |||
3298 | block = (size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT; | ||
3299 | data_key_init(c, &from_key, inode->i_ino, block); | ||
3300 | highest_data_key(c, &to_key, inode->i_ino); | ||
3301 | |||
3302 | mutex_lock(&c->tnc_mutex); | ||
3303 | err = ubifs_lookup_level0(c, &from_key, &znode, &n); | ||
3304 | if (err < 0) | ||
3305 | goto out_unlock; | ||
3306 | |||
3307 | if (err) { | ||
3308 | err = -EINVAL; | ||
3309 | key = &from_key; | ||
3310 | goto out_dump; | ||
3311 | } | ||
3312 | |||
3313 | err = tnc_next(c, &znode, &n); | ||
3314 | if (err == -ENOENT) { | ||
3315 | err = 0; | ||
3316 | goto out_unlock; | ||
3317 | } | ||
3318 | if (err < 0) | ||
3319 | goto out_unlock; | ||
3320 | |||
3321 | ubifs_assert(err == 0); | ||
3322 | key = &znode->zbranch[n].key; | ||
3323 | if (!key_in_range(c, key, &from_key, &to_key)) | ||
3324 | goto out_unlock; | ||
3325 | |||
3326 | out_dump: | ||
3327 | block = key_block(c, key); | ||
3328 | ubifs_err("inode %lu has size %lld, but there are data at offset %lld " | ||
3329 | "(data key %s)", (unsigned long)inode->i_ino, size, | ||
3330 | ((loff_t)block) << UBIFS_BLOCK_SHIFT, DBGKEY(key)); | ||
3331 | dbg_dump_inode(c, inode); | ||
3332 | dbg_dump_stack(); | ||
3333 | err = -EINVAL; | ||
3334 | |||
3335 | out_unlock: | ||
3336 | mutex_unlock(&c->tnc_mutex); | ||
3337 | return err; | ||
3338 | } | ||
3339 | |||
3340 | #endif /* CONFIG_UBIFS_FS_DEBUG */ | ||
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c index fde8d127c768..53288e5d604e 100644 --- a/fs/ubifs/tnc_commit.c +++ b/fs/ubifs/tnc_commit.c | |||
@@ -245,7 +245,7 @@ static int layout_leb_in_gaps(struct ubifs_info *c, int *p) | |||
245 | * it is more comprehensive and less efficient than is needed for this | 245 | * it is more comprehensive and less efficient than is needed for this |
246 | * purpose. | 246 | * purpose. |
247 | */ | 247 | */ |
248 | sleb = ubifs_scan(c, lnum, 0, c->ileb_buf); | 248 | sleb = ubifs_scan(c, lnum, 0, c->ileb_buf, 0); |
249 | c->ileb_len = 0; | 249 | c->ileb_len = 0; |
250 | if (IS_ERR(sleb)) | 250 | if (IS_ERR(sleb)) |
251 | return PTR_ERR(sleb); | 251 | return PTR_ERR(sleb); |
diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h index 3eee07e0c495..191ca7863fe7 100644 --- a/fs/ubifs/ubifs-media.h +++ b/fs/ubifs/ubifs-media.h | |||
@@ -135,6 +135,13 @@ | |||
135 | /* The key is always at the same position in all keyed nodes */ | 135 | /* The key is always at the same position in all keyed nodes */ |
136 | #define UBIFS_KEY_OFFSET offsetof(struct ubifs_ino_node, key) | 136 | #define UBIFS_KEY_OFFSET offsetof(struct ubifs_ino_node, key) |
137 | 137 | ||
138 | /* Garbage collector journal head number */ | ||
139 | #define UBIFS_GC_HEAD 0 | ||
140 | /* Base journal head number */ | ||
141 | #define UBIFS_BASE_HEAD 1 | ||
142 | /* Data journal head number */ | ||
143 | #define UBIFS_DATA_HEAD 2 | ||
144 | |||
138 | /* | 145 | /* |
139 | * LEB Properties Tree node types. | 146 | * LEB Properties Tree node types. |
140 | * | 147 | * |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index a29349094422..b2d976366a46 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -105,12 +105,10 @@ | |||
105 | /* Number of non-data journal heads */ | 105 | /* Number of non-data journal heads */ |
106 | #define NONDATA_JHEADS_CNT 2 | 106 | #define NONDATA_JHEADS_CNT 2 |
107 | 107 | ||
108 | /* Garbage collector head */ | 108 | /* Shorter names for journal head numbers for internal usage */ |
109 | #define GCHD 0 | 109 | #define GCHD UBIFS_GC_HEAD |
110 | /* Base journal head number */ | 110 | #define BASEHD UBIFS_BASE_HEAD |
111 | #define BASEHD 1 | 111 | #define DATAHD UBIFS_DATA_HEAD |
112 | /* First "general purpose" journal head */ | ||
113 | #define DATAHD 2 | ||
114 | 112 | ||
115 | /* 'No change' value for 'ubifs_change_lp()' */ | 113 | /* 'No change' value for 'ubifs_change_lp()' */ |
116 | #define LPROPS_NC 0x80000001 | 114 | #define LPROPS_NC 0x80000001 |
@@ -1451,7 +1449,7 @@ int ubifs_sync_wbufs_by_inode(struct ubifs_info *c, struct inode *inode); | |||
1451 | 1449 | ||
1452 | /* scan.c */ | 1450 | /* scan.c */ |
1453 | struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | 1451 | struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, |
1454 | int offs, void *sbuf); | 1452 | int offs, void *sbuf, int quiet); |
1455 | void ubifs_scan_destroy(struct ubifs_scan_leb *sleb); | 1453 | void ubifs_scan_destroy(struct ubifs_scan_leb *sleb); |
1456 | int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum, | 1454 | int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum, |
1457 | int offs, int quiet); | 1455 | int offs, int quiet); |
@@ -1676,6 +1674,7 @@ const struct ubifs_lprops *ubifs_fast_find_free(struct ubifs_info *c); | |||
1676 | const struct ubifs_lprops *ubifs_fast_find_empty(struct ubifs_info *c); | 1674 | const struct ubifs_lprops *ubifs_fast_find_empty(struct ubifs_info *c); |
1677 | const struct ubifs_lprops *ubifs_fast_find_freeable(struct ubifs_info *c); | 1675 | const struct ubifs_lprops *ubifs_fast_find_freeable(struct ubifs_info *c); |
1678 | const struct ubifs_lprops *ubifs_fast_find_frdi_idx(struct ubifs_info *c); | 1676 | const struct ubifs_lprops *ubifs_fast_find_frdi_idx(struct ubifs_info *c); |
1677 | int ubifs_calc_dark(const struct ubifs_info *c, int spc); | ||
1679 | 1678 | ||
1680 | /* file.c */ | 1679 | /* file.c */ |
1681 | int ubifs_fsync(struct file *file, struct dentry *dentry, int datasync); | 1680 | int ubifs_fsync(struct file *file, struct dentry *dentry, int datasync); |
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index adafcf556531..7998cc378250 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c | |||
@@ -78,9 +78,9 @@ enum { | |||
78 | SECURITY_XATTR, | 78 | SECURITY_XATTR, |
79 | }; | 79 | }; |
80 | 80 | ||
81 | static struct inode_operations none_inode_operations; | 81 | static const struct inode_operations none_inode_operations; |
82 | static struct address_space_operations none_address_operations; | 82 | static struct address_space_operations none_address_operations; |
83 | static struct file_operations none_file_operations; | 83 | static const struct file_operations none_file_operations; |
84 | 84 | ||
85 | /** | 85 | /** |
86 | * create_xattr - create an extended attribute. | 86 | * create_xattr - create an extended attribute. |