diff options
-rw-r--r-- | fs/ubifs/budget.c | 37 | ||||
-rw-r--r-- | fs/ubifs/debug.c | 6 | ||||
-rw-r--r-- | fs/ubifs/file.c | 16 | ||||
-rw-r--r-- | fs/ubifs/find.c | 12 | ||||
-rw-r--r-- | fs/ubifs/gc.c | 428 | ||||
-rw-r--r-- | fs/ubifs/journal.c | 7 | ||||
-rw-r--r-- | fs/ubifs/key.h | 6 | ||||
-rw-r--r-- | fs/ubifs/log.c | 5 | ||||
-rw-r--r-- | fs/ubifs/lpt_commit.c | 34 | ||||
-rw-r--r-- | fs/ubifs/recovery.c | 70 | ||||
-rw-r--r-- | fs/ubifs/replay.c | 2 | ||||
-rw-r--r-- | fs/ubifs/sb.c | 36 | ||||
-rw-r--r-- | fs/ubifs/shrinker.c | 6 | ||||
-rw-r--r-- | fs/ubifs/super.c | 37 | ||||
-rw-r--r-- | fs/ubifs/tnc.c | 2 | ||||
-rw-r--r-- | fs/ubifs/ubifs-media.h | 30 | ||||
-rw-r--r-- | fs/ubifs/ubifs.h | 13 |
17 files changed, 482 insertions, 265 deletions
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c index f393620890ee..af1914462f02 100644 --- a/fs/ubifs/budget.c +++ b/fs/ubifs/budget.c | |||
@@ -194,29 +194,26 @@ static int make_free_space(struct ubifs_info *c) | |||
194 | } | 194 | } |
195 | 195 | ||
196 | /** | 196 | /** |
197 | * ubifs_calc_min_idx_lebs - calculate amount of eraseblocks for the index. | 197 | * ubifs_calc_min_idx_lebs - calculate amount of LEBs for the index. |
198 | * @c: UBIFS file-system description object | 198 | * @c: UBIFS file-system description object |
199 | * | 199 | * |
200 | * This function calculates and returns the number of eraseblocks which should | 200 | * This function calculates and returns the number of LEBs which should be kept |
201 | * be kept for index usage. | 201 | * for index usage. |
202 | */ | 202 | */ |
203 | int ubifs_calc_min_idx_lebs(struct ubifs_info *c) | 203 | int ubifs_calc_min_idx_lebs(struct ubifs_info *c) |
204 | { | 204 | { |
205 | int idx_lebs, eff_leb_size = c->leb_size - c->max_idx_node_sz; | 205 | int idx_lebs; |
206 | long long idx_size; | 206 | long long idx_size; |
207 | 207 | ||
208 | idx_size = c->old_idx_sz + c->budg_idx_growth + c->budg_uncommitted_idx; | 208 | idx_size = c->old_idx_sz + c->budg_idx_growth + c->budg_uncommitted_idx; |
209 | |||
210 | /* And make sure we have thrice the index size of space reserved */ | 209 | /* And make sure we have thrice the index size of space reserved */ |
211 | idx_size = idx_size + (idx_size << 1); | 210 | idx_size += idx_size << 1; |
212 | |||
213 | /* | 211 | /* |
214 | * We do not maintain 'old_idx_size' as 'old_idx_lebs'/'old_idx_bytes' | 212 | * We do not maintain 'old_idx_size' as 'old_idx_lebs'/'old_idx_bytes' |
215 | * pair, nor similarly the two variables for the new index size, so we | 213 | * pair, nor similarly the two variables for the new index size, so we |
216 | * have to do this costly 64-bit division on fast-path. | 214 | * have to do this costly 64-bit division on fast-path. |
217 | */ | 215 | */ |
218 | idx_size += eff_leb_size - 1; | 216 | idx_lebs = div_u64(idx_size + c->idx_leb_size - 1, c->idx_leb_size); |
219 | idx_lebs = div_u64(idx_size, eff_leb_size); | ||
220 | /* | 217 | /* |
221 | * The index head is not available for the in-the-gaps method, so add an | 218 | * The index head is not available for the in-the-gaps method, so add an |
222 | * extra LEB to compensate. | 219 | * extra LEB to compensate. |
@@ -310,23 +307,23 @@ static int can_use_rp(struct ubifs_info *c) | |||
310 | * do_budget_space - reserve flash space for index and data growth. | 307 | * do_budget_space - reserve flash space for index and data growth. |
311 | * @c: UBIFS file-system description object | 308 | * @c: UBIFS file-system description object |
312 | * | 309 | * |
313 | * This function makes sure UBIFS has enough free eraseblocks for index growth | 310 | * This function makes sure UBIFS has enough free LEBs for index growth and |
314 | * and data. | 311 | * data. |
315 | * | 312 | * |
316 | * When budgeting index space, UBIFS reserves thrice as many LEBs as the index | 313 | * When budgeting index space, UBIFS reserves thrice as many LEBs as the index |
317 | * would take if it was consolidated and written to the flash. This guarantees | 314 | * would take if it was consolidated and written to the flash. This guarantees |
318 | * that the "in-the-gaps" commit method always succeeds and UBIFS will always | 315 | * that the "in-the-gaps" commit method always succeeds and UBIFS will always |
319 | * be able to commit dirty index. So this function basically adds amount of | 316 | * be able to commit dirty index. So this function basically adds amount of |
320 | * budgeted index space to the size of the current index, multiplies this by 3, | 317 | * budgeted index space to the size of the current index, multiplies this by 3, |
321 | * and makes sure this does not exceed the amount of free eraseblocks. | 318 | * and makes sure this does not exceed the amount of free LEBs. |
322 | * | 319 | * |
323 | * Notes about @c->min_idx_lebs and @c->lst.idx_lebs variables: | 320 | * Notes about @c->min_idx_lebs and @c->lst.idx_lebs variables: |
324 | * o @c->lst.idx_lebs is the number of LEBs the index currently uses. It might | 321 | * o @c->lst.idx_lebs is the number of LEBs the index currently uses. It might |
325 | * be large, because UBIFS does not do any index consolidation as long as | 322 | * be large, because UBIFS does not do any index consolidation as long as |
326 | * there is free space. IOW, the index may take a lot of LEBs, but the LEBs | 323 | * there is free space. IOW, the index may take a lot of LEBs, but the LEBs |
327 | * will contain a lot of dirt. | 324 | * will contain a lot of dirt. |
328 | * o @c->min_idx_lebs is the the index presumably takes. IOW, the index may be | 325 | * o @c->min_idx_lebs is the number of LEBS the index presumably takes. IOW, |
329 | * consolidated to take up to @c->min_idx_lebs LEBs. | 326 | * the index may be consolidated to take up to @c->min_idx_lebs LEBs. |
330 | * | 327 | * |
331 | * This function returns zero in case of success, and %-ENOSPC in case of | 328 | * This function returns zero in case of success, and %-ENOSPC in case of |
332 | * failure. | 329 | * failure. |
@@ -695,12 +692,12 @@ long long ubifs_reported_space(const struct ubifs_info *c, long long free) | |||
695 | * This function calculates amount of free space to report to user-space. | 692 | * This function calculates amount of free space to report to user-space. |
696 | * | 693 | * |
697 | * Because UBIFS may introduce substantial overhead (the index, node headers, | 694 | * Because UBIFS may introduce substantial overhead (the index, node headers, |
698 | * alignment, wastage at the end of eraseblocks, etc), it cannot report real | 695 | * alignment, wastage at the end of LEBs, etc), it cannot report real amount of |
699 | * amount of free flash space it has (well, because not all dirty space is | 696 | * free flash space it has (well, because not all dirty space is reclaimable, |
700 | * reclaimable, UBIFS does not actually know the real amount). If UBIFS did so, | 697 | * UBIFS does not actually know the real amount). If UBIFS did so, it would |
701 | * it would bread user expectations about what free space is. Users seem to | 698 | * bread user expectations about what free space is. Users seem to accustomed |
702 | * accustomed to assume that if the file-system reports N bytes of free space, | 699 | * to assume that if the file-system reports N bytes of free space, they would |
703 | * they would be able to fit a file of N bytes to the FS. This almost works for | 700 | * be able to fit a file of N bytes to the FS. This almost works for |
704 | * traditional file-systems, because they have way less overhead than UBIFS. | 701 | * traditional file-systems, because they have way less overhead than UBIFS. |
705 | * So, to keep users happy, UBIFS tries to take the overhead into account. | 702 | * So, to keep users happy, UBIFS tries to take the overhead into account. |
706 | */ | 703 | */ |
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index e975bd82f38b..ce2cd8343618 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c | |||
@@ -479,9 +479,9 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node) | |||
479 | "bad or corrupted node)"); | 479 | "bad or corrupted node)"); |
480 | else { | 480 | else { |
481 | for (i = 0; i < nlen && dent->name[i]; i++) | 481 | for (i = 0; i < nlen && dent->name[i]; i++) |
482 | printk("%c", dent->name[i]); | 482 | printk(KERN_CONT "%c", dent->name[i]); |
483 | } | 483 | } |
484 | printk("\n"); | 484 | printk(KERN_CONT "\n"); |
485 | 485 | ||
486 | break; | 486 | break; |
487 | } | 487 | } |
@@ -1214,7 +1214,7 @@ static int dbg_check_znode(struct ubifs_info *c, struct ubifs_zbranch *zbr) | |||
1214 | 1214 | ||
1215 | /* | 1215 | /* |
1216 | * Make sure the last key in our znode is less or | 1216 | * Make sure the last key in our znode is less or |
1217 | * equivalent than the the key in zbranch which goes | 1217 | * equivalent than the key in the zbranch which goes |
1218 | * after our pointing zbranch. | 1218 | * after our pointing zbranch. |
1219 | */ | 1219 | */ |
1220 | cmp = keys_cmp(c, max, | 1220 | cmp = keys_cmp(c, max, |
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 0ff89fe71e51..6d34dc7e33e1 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c | |||
@@ -430,6 +430,7 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, | |||
430 | struct ubifs_inode *ui = ubifs_inode(inode); | 430 | struct ubifs_inode *ui = ubifs_inode(inode); |
431 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; | 431 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; |
432 | int uninitialized_var(err), appending = !!(pos + len > inode->i_size); | 432 | int uninitialized_var(err), appending = !!(pos + len > inode->i_size); |
433 | int skipped_read = 0; | ||
433 | struct page *page; | 434 | struct page *page; |
434 | 435 | ||
435 | ubifs_assert(ubifs_inode(inode)->ui_size == inode->i_size); | 436 | ubifs_assert(ubifs_inode(inode)->ui_size == inode->i_size); |
@@ -444,7 +445,7 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, | |||
444 | 445 | ||
445 | if (!PageUptodate(page)) { | 446 | if (!PageUptodate(page)) { |
446 | /* The page is not loaded from the flash */ | 447 | /* The page is not loaded from the flash */ |
447 | if (!(pos & ~PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE) | 448 | if (!(pos & ~PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE) { |
448 | /* | 449 | /* |
449 | * We change whole page so no need to load it. But we | 450 | * We change whole page so no need to load it. But we |
450 | * have to set the @PG_checked flag to make the further | 451 | * have to set the @PG_checked flag to make the further |
@@ -453,7 +454,8 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, | |||
453 | * the media. | 454 | * the media. |
454 | */ | 455 | */ |
455 | SetPageChecked(page); | 456 | SetPageChecked(page); |
456 | else { | 457 | skipped_read = 1; |
458 | } else { | ||
457 | err = do_readpage(page); | 459 | err = do_readpage(page); |
458 | if (err) { | 460 | if (err) { |
459 | unlock_page(page); | 461 | unlock_page(page); |
@@ -470,6 +472,14 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, | |||
470 | if (unlikely(err)) { | 472 | if (unlikely(err)) { |
471 | ubifs_assert(err == -ENOSPC); | 473 | ubifs_assert(err == -ENOSPC); |
472 | /* | 474 | /* |
475 | * If we skipped reading the page because we were going to | ||
476 | * write all of it, then it is not up to date. | ||
477 | */ | ||
478 | if (skipped_read) { | ||
479 | ClearPageChecked(page); | ||
480 | ClearPageUptodate(page); | ||
481 | } | ||
482 | /* | ||
473 | * Budgeting failed which means it would have to force | 483 | * Budgeting failed which means it would have to force |
474 | * write-back but didn't, because we set the @fast flag in the | 484 | * write-back but didn't, because we set the @fast flag in the |
475 | * request. Write-back cannot be done now, while we have the | 485 | * request. Write-back cannot be done now, while we have the |
@@ -949,7 +959,7 @@ static int do_writepage(struct page *page, int len) | |||
949 | * whole index and correct all inode sizes, which is long an unacceptable. | 959 | * whole index and correct all inode sizes, which is long an unacceptable. |
950 | * | 960 | * |
951 | * To prevent situations like this, UBIFS writes pages back only if they are | 961 | * To prevent situations like this, UBIFS writes pages back only if they are |
952 | * within last synchronized inode size, i.e. the the size which has been | 962 | * within the last synchronized inode size, i.e. the size which has been |
953 | * written to the flash media last time. Otherwise, UBIFS forces inode | 963 | * written to the flash media last time. Otherwise, UBIFS forces inode |
954 | * write-back, thus making sure the on-flash inode contains current inode size, | 964 | * write-back, thus making sure the on-flash inode contains current inode size, |
955 | * and then keeps writing pages back. | 965 | * and then keeps writing pages back. |
diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c index 717d79c97c5e..1d54383d1269 100644 --- a/fs/ubifs/find.c +++ b/fs/ubifs/find.c | |||
@@ -478,7 +478,7 @@ const struct ubifs_lprops *do_find_free_space(struct ubifs_info *c, | |||
478 | * ubifs_find_free_space - find a data LEB with free space. | 478 | * ubifs_find_free_space - find a data LEB with free space. |
479 | * @c: the UBIFS file-system description object | 479 | * @c: the UBIFS file-system description object |
480 | * @min_space: minimum amount of required free space | 480 | * @min_space: minimum amount of required free space |
481 | * @free: contains amount of free space in the LEB on exit | 481 | * @offs: contains offset of where free space starts on exit |
482 | * @squeeze: whether to try to find space in a non-empty LEB first | 482 | * @squeeze: whether to try to find space in a non-empty LEB first |
483 | * | 483 | * |
484 | * This function looks for an LEB with at least @min_space bytes of free space. | 484 | * This function looks for an LEB with at least @min_space bytes of free space. |
@@ -490,7 +490,7 @@ const struct ubifs_lprops *do_find_free_space(struct ubifs_info *c, | |||
490 | * failed to find a LEB with @min_space bytes of free space and other a negative | 490 | * failed to find a LEB with @min_space bytes of free space and other a negative |
491 | * error codes in case of failure. | 491 | * error codes in case of failure. |
492 | */ | 492 | */ |
493 | int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free, | 493 | int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *offs, |
494 | int squeeze) | 494 | int squeeze) |
495 | { | 495 | { |
496 | const struct ubifs_lprops *lprops; | 496 | const struct ubifs_lprops *lprops; |
@@ -558,10 +558,10 @@ int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free, | |||
558 | spin_unlock(&c->space_lock); | 558 | spin_unlock(&c->space_lock); |
559 | } | 559 | } |
560 | 560 | ||
561 | *free = lprops->free; | 561 | *offs = c->leb_size - lprops->free; |
562 | ubifs_release_lprops(c); | 562 | ubifs_release_lprops(c); |
563 | 563 | ||
564 | if (*free == c->leb_size) { | 564 | if (*offs == 0) { |
565 | /* | 565 | /* |
566 | * Ensure that empty LEBs have been unmapped. They may not have | 566 | * Ensure that empty LEBs have been unmapped. They may not have |
567 | * been, for example, because of an unclean unmount. Also | 567 | * been, for example, because of an unclean unmount. Also |
@@ -573,8 +573,8 @@ int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free, | |||
573 | return err; | 573 | return err; |
574 | } | 574 | } |
575 | 575 | ||
576 | dbg_find("found LEB %d, free %d", lnum, *free); | 576 | dbg_find("found LEB %d, free %d", lnum, c->leb_size - *offs); |
577 | ubifs_assert(*free >= min_space); | 577 | ubifs_assert(*offs <= c->leb_size - min_space); |
578 | return lnum; | 578 | return lnum; |
579 | 579 | ||
580 | out: | 580 | out: |
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c index a711d33b3d3e..f0f5f15d384e 100644 --- a/fs/ubifs/gc.c +++ b/fs/ubifs/gc.c | |||
@@ -47,7 +47,7 @@ | |||
47 | * have to waste large pieces of free space at the end of LEB B, because nodes | 47 | * have to waste large pieces of free space at the end of LEB B, because nodes |
48 | * from LEB A would not fit. And the worst situation is when all nodes are of | 48 | * from LEB A would not fit. And the worst situation is when all nodes are of |
49 | * maximum size. So dark watermark is the amount of free + dirty space in LEB | 49 | * maximum size. So dark watermark is the amount of free + dirty space in LEB |
50 | * which are guaranteed to be reclaimable. If LEB has less space, the GC migh | 50 | * which are guaranteed to be reclaimable. If LEB has less space, the GC might |
51 | * be unable to reclaim it. So, LEBs with free + dirty greater than dark | 51 | * be unable to reclaim it. So, LEBs with free + dirty greater than dark |
52 | * watermark are "good" LEBs from GC's point of few. The other LEBs are not so | 52 | * watermark are "good" LEBs from GC's point of few. The other LEBs are not so |
53 | * good, and GC takes extra care when moving them. | 53 | * good, and GC takes extra care when moving them. |
@@ -57,14 +57,6 @@ | |||
57 | #include "ubifs.h" | 57 | #include "ubifs.h" |
58 | 58 | ||
59 | /* | 59 | /* |
60 | * GC tries to optimize the way it fit nodes to available space, and it sorts | ||
61 | * nodes a little. The below constants are watermarks which define "large", | ||
62 | * "medium", and "small" nodes. | ||
63 | */ | ||
64 | #define MEDIUM_NODE_WM (UBIFS_BLOCK_SIZE / 4) | ||
65 | #define SMALL_NODE_WM UBIFS_MAX_DENT_NODE_SZ | ||
66 | |||
67 | /* | ||
68 | * GC may need to move more than one LEB to make progress. The below constants | 60 | * GC may need to move more than one LEB to make progress. The below constants |
69 | * define "soft" and "hard" limits on the number of LEBs the garbage collector | 61 | * define "soft" and "hard" limits on the number of LEBs the garbage collector |
70 | * may move. | 62 | * may move. |
@@ -116,83 +108,222 @@ static int switch_gc_head(struct ubifs_info *c) | |||
116 | } | 108 | } |
117 | 109 | ||
118 | /** | 110 | /** |
119 | * joinup - bring data nodes for an inode together. | 111 | * list_sort - sort a list. |
120 | * @c: UBIFS file-system description object | 112 | * @priv: private data, passed to @cmp |
121 | * @sleb: describes scanned LEB | 113 | * @head: the list to sort |
122 | * @inum: inode number | 114 | * @cmp: the elements comparison function |
123 | * @blk: block number | ||
124 | * @data: list to which to add data nodes | ||
125 | * | 115 | * |
126 | * This function looks at the first few nodes in the scanned LEB @sleb and adds | 116 | * This function has been implemented by Mark J Roberts <mjr@znex.org>. It |
127 | * them to @data if they are data nodes from @inum and have a larger block | 117 | * implements "merge sort" which has O(nlog(n)) complexity. The list is sorted |
128 | * number than @blk. This function returns %0 on success and a negative error | 118 | * in ascending order. |
129 | * code on failure. | 119 | * |
120 | * The comparison function @cmp is supposed to return a negative value if @a is | ||
121 | * than @b, and a positive value if @a is greater than @b. If @a and @b are | ||
122 | * equivalent, then it does not matter what this function returns. | ||
130 | */ | 123 | */ |
131 | static int joinup(struct ubifs_info *c, struct ubifs_scan_leb *sleb, ino_t inum, | 124 | static void list_sort(void *priv, struct list_head *head, |
132 | unsigned int blk, struct list_head *data) | 125 | int (*cmp)(void *priv, struct list_head *a, |
126 | struct list_head *b)) | ||
133 | { | 127 | { |
134 | int err, cnt = 6, lnum = sleb->lnum, offs; | 128 | struct list_head *p, *q, *e, *list, *tail, *oldhead; |
135 | struct ubifs_scan_node *snod, *tmp; | 129 | int insize, nmerges, psize, qsize, i; |
136 | union ubifs_key *key; | 130 | |
131 | if (list_empty(head)) | ||
132 | return; | ||
133 | |||
134 | list = head->next; | ||
135 | list_del(head); | ||
136 | insize = 1; | ||
137 | for (;;) { | ||
138 | p = oldhead = list; | ||
139 | list = tail = NULL; | ||
140 | nmerges = 0; | ||
141 | |||
142 | while (p) { | ||
143 | nmerges++; | ||
144 | q = p; | ||
145 | psize = 0; | ||
146 | for (i = 0; i < insize; i++) { | ||
147 | psize++; | ||
148 | q = q->next == oldhead ? NULL : q->next; | ||
149 | if (!q) | ||
150 | break; | ||
151 | } | ||
137 | 152 | ||
138 | list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) { | 153 | qsize = insize; |
139 | key = &snod->key; | 154 | while (psize > 0 || (qsize > 0 && q)) { |
140 | if (key_inum(c, key) == inum && | 155 | if (!psize) { |
141 | key_type(c, key) == UBIFS_DATA_KEY && | 156 | e = q; |
142 | key_block(c, key) > blk) { | 157 | q = q->next; |
143 | offs = snod->offs; | 158 | qsize--; |
144 | err = ubifs_tnc_has_node(c, key, 0, lnum, offs, 0); | 159 | if (q == oldhead) |
145 | if (err < 0) | 160 | q = NULL; |
146 | return err; | 161 | } else if (!qsize || !q) { |
147 | list_del(&snod->list); | 162 | e = p; |
148 | if (err) { | 163 | p = p->next; |
149 | list_add_tail(&snod->list, data); | 164 | psize--; |
150 | blk = key_block(c, key); | 165 | if (p == oldhead) |
151 | } else | 166 | p = NULL; |
152 | kfree(snod); | 167 | } else if (cmp(priv, p, q) <= 0) { |
153 | cnt = 6; | 168 | e = p; |
154 | } else if (--cnt == 0) | 169 | p = p->next; |
170 | psize--; | ||
171 | if (p == oldhead) | ||
172 | p = NULL; | ||
173 | } else { | ||
174 | e = q; | ||
175 | q = q->next; | ||
176 | qsize--; | ||
177 | if (q == oldhead) | ||
178 | q = NULL; | ||
179 | } | ||
180 | if (tail) | ||
181 | tail->next = e; | ||
182 | else | ||
183 | list = e; | ||
184 | e->prev = tail; | ||
185 | tail = e; | ||
186 | } | ||
187 | p = q; | ||
188 | } | ||
189 | |||
190 | tail->next = list; | ||
191 | list->prev = tail; | ||
192 | |||
193 | if (nmerges <= 1) | ||
155 | break; | 194 | break; |
195 | |||
196 | insize *= 2; | ||
156 | } | 197 | } |
157 | return 0; | 198 | |
199 | head->next = list; | ||
200 | head->prev = list->prev; | ||
201 | list->prev->next = head; | ||
202 | list->prev = head; | ||
158 | } | 203 | } |
159 | 204 | ||
160 | /** | 205 | /** |
161 | * move_nodes - move nodes. | 206 | * data_nodes_cmp - compare 2 data nodes. |
207 | * @priv: UBIFS file-system description object | ||
208 | * @a: first data node | ||
209 | * @a: second data node | ||
210 | * | ||
211 | * This function compares data nodes @a and @b. Returns %1 if @a has greater | ||
212 | * inode or block number, and %-1 otherwise. | ||
213 | */ | ||
214 | int data_nodes_cmp(void *priv, struct list_head *a, struct list_head *b) | ||
215 | { | ||
216 | ino_t inuma, inumb; | ||
217 | struct ubifs_info *c = priv; | ||
218 | struct ubifs_scan_node *sa, *sb; | ||
219 | |||
220 | cond_resched(); | ||
221 | sa = list_entry(a, struct ubifs_scan_node, list); | ||
222 | sb = list_entry(b, struct ubifs_scan_node, list); | ||
223 | ubifs_assert(key_type(c, &sa->key) == UBIFS_DATA_KEY); | ||
224 | ubifs_assert(key_type(c, &sb->key) == UBIFS_DATA_KEY); | ||
225 | |||
226 | inuma = key_inum(c, &sa->key); | ||
227 | inumb = key_inum(c, &sb->key); | ||
228 | |||
229 | if (inuma == inumb) { | ||
230 | unsigned int blka = key_block(c, &sa->key); | ||
231 | unsigned int blkb = key_block(c, &sb->key); | ||
232 | |||
233 | if (blka <= blkb) | ||
234 | return -1; | ||
235 | } else if (inuma <= inumb) | ||
236 | return -1; | ||
237 | |||
238 | return 1; | ||
239 | } | ||
240 | |||
241 | /* | ||
242 | * nondata_nodes_cmp - compare 2 non-data nodes. | ||
243 | * @priv: UBIFS file-system description object | ||
244 | * @a: first node | ||
245 | * @a: second node | ||
246 | * | ||
247 | * This function compares nodes @a and @b. It makes sure that inode nodes go | ||
248 | * first and sorted by length in descending order. Directory entry nodes go | ||
249 | * after inode nodes and are sorted in ascending hash valuer order. | ||
250 | */ | ||
251 | int nondata_nodes_cmp(void *priv, struct list_head *a, struct list_head *b) | ||
252 | { | ||
253 | int typea, typeb; | ||
254 | ino_t inuma, inumb; | ||
255 | struct ubifs_info *c = priv; | ||
256 | struct ubifs_scan_node *sa, *sb; | ||
257 | |||
258 | cond_resched(); | ||
259 | sa = list_entry(a, struct ubifs_scan_node, list); | ||
260 | sb = list_entry(b, struct ubifs_scan_node, list); | ||
261 | typea = key_type(c, &sa->key); | ||
262 | typeb = key_type(c, &sb->key); | ||
263 | ubifs_assert(typea != UBIFS_DATA_KEY && typeb != UBIFS_DATA_KEY); | ||
264 | |||
265 | /* Inodes go before directory entries */ | ||
266 | if (typea == UBIFS_INO_KEY) { | ||
267 | if (typeb == UBIFS_INO_KEY) | ||
268 | return sb->len - sa->len; | ||
269 | return -1; | ||
270 | } | ||
271 | if (typeb == UBIFS_INO_KEY) | ||
272 | return 1; | ||
273 | |||
274 | ubifs_assert(typea == UBIFS_DENT_KEY && typeb == UBIFS_DENT_KEY); | ||
275 | inuma = key_inum(c, &sa->key); | ||
276 | inumb = key_inum(c, &sb->key); | ||
277 | |||
278 | if (inuma == inumb) { | ||
279 | uint32_t hasha = key_hash(c, &sa->key); | ||
280 | uint32_t hashb = key_hash(c, &sb->key); | ||
281 | |||
282 | if (hasha <= hashb) | ||
283 | return -1; | ||
284 | } else if (inuma <= inumb) | ||
285 | return -1; | ||
286 | |||
287 | return 1; | ||
288 | } | ||
289 | |||
290 | /** | ||
291 | * sort_nodes - sort nodes for GC. | ||
162 | * @c: UBIFS file-system description object | 292 | * @c: UBIFS file-system description object |
163 | * @sleb: describes nodes to move | 293 | * @sleb: describes nodes to sort and contains the result on exit |
294 | * @nondata: contains non-data nodes on exit | ||
295 | * @min: minimum node size is returned here | ||
164 | * | 296 | * |
165 | * This function moves valid nodes from data LEB described by @sleb to the GC | 297 | * This function sorts the list of inodes to garbage collect. First of all, it |
166 | * journal head. The obsolete nodes are dropped. | 298 | * kills obsolete nodes and separates data and non-data nodes to the |
299 | * @sleb->nodes and @nondata lists correspondingly. | ||
300 | * | ||
301 | * Data nodes are then sorted in block number order - this is important for | ||
302 | * bulk-read; data nodes with lower inode number go before data nodes with | ||
303 | * higher inode number, and data nodes with lower block number go before data | ||
304 | * nodes with higher block number; | ||
167 | * | 305 | * |
168 | * When moving nodes we have to deal with classical bin-packing problem: the | 306 | * Non-data nodes are sorted as follows. |
169 | * space in the current GC journal head LEB and in @c->gc_lnum are the "bins", | 307 | * o First go inode nodes - they are sorted in descending length order. |
170 | * where the nodes in the @sleb->nodes list are the elements which should be | 308 | * o Then go directory entry nodes - they are sorted in hash order, which |
171 | * fit optimally to the bins. This function uses the "first fit decreasing" | 309 | * should supposedly optimize 'readdir()'. Direntry nodes with lower parent |
172 | * strategy, although it does not really sort the nodes but just split them on | 310 | * inode number go before direntry nodes with higher parent inode number, |
173 | * 3 classes - large, medium, and small, so they are roughly sorted. | 311 | * and direntry nodes with lower name hash values go before direntry nodes |
312 | * with higher name hash values. | ||
174 | * | 313 | * |
175 | * This function returns zero in case of success, %-EAGAIN if commit is | 314 | * This function returns zero in case of success and a negative error code in |
176 | * required, and other negative error codes in case of other failures. | 315 | * case of failure. |
177 | */ | 316 | */ |
178 | static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) | 317 | static int sort_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb, |
318 | struct list_head *nondata, int *min) | ||
179 | { | 319 | { |
180 | struct ubifs_scan_node *snod, *tmp; | 320 | struct ubifs_scan_node *snod, *tmp; |
181 | struct list_head data, large, medium, small; | ||
182 | struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf; | ||
183 | int avail, err, min = INT_MAX; | ||
184 | unsigned int blk = 0; | ||
185 | ino_t inum = 0; | ||
186 | 321 | ||
187 | INIT_LIST_HEAD(&data); | 322 | *min = INT_MAX; |
188 | INIT_LIST_HEAD(&large); | ||
189 | INIT_LIST_HEAD(&medium); | ||
190 | INIT_LIST_HEAD(&small); | ||
191 | 323 | ||
192 | while (!list_empty(&sleb->nodes)) { | 324 | /* Separate data nodes and non-data nodes */ |
193 | struct list_head *lst = sleb->nodes.next; | 325 | list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) { |
194 | 326 | int err; | |
195 | snod = list_entry(lst, struct ubifs_scan_node, list); | ||
196 | 327 | ||
197 | ubifs_assert(snod->type != UBIFS_IDX_NODE); | 328 | ubifs_assert(snod->type != UBIFS_IDX_NODE); |
198 | ubifs_assert(snod->type != UBIFS_REF_NODE); | 329 | ubifs_assert(snod->type != UBIFS_REF_NODE); |
@@ -201,53 +332,72 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) | |||
201 | err = ubifs_tnc_has_node(c, &snod->key, 0, sleb->lnum, | 332 | err = ubifs_tnc_has_node(c, &snod->key, 0, sleb->lnum, |
202 | snod->offs, 0); | 333 | snod->offs, 0); |
203 | if (err < 0) | 334 | if (err < 0) |
204 | goto out; | 335 | return err; |
205 | 336 | ||
206 | list_del(lst); | ||
207 | if (!err) { | 337 | if (!err) { |
208 | /* The node is obsolete, remove it from the list */ | 338 | /* The node is obsolete, remove it from the list */ |
339 | list_del(&snod->list); | ||
209 | kfree(snod); | 340 | kfree(snod); |
210 | continue; | 341 | continue; |
211 | } | 342 | } |
212 | 343 | ||
213 | /* | 344 | if (snod->len < *min) |
214 | * Sort the list of nodes so that data nodes go first, large | 345 | *min = snod->len; |
215 | * nodes go second, and small nodes go last. | 346 | |
216 | */ | 347 | if (key_type(c, &snod->key) != UBIFS_DATA_KEY) |
217 | if (key_type(c, &snod->key) == UBIFS_DATA_KEY) { | 348 | list_move_tail(&snod->list, nondata); |
218 | if (inum != key_inum(c, &snod->key)) { | ||
219 | if (inum) { | ||
220 | /* | ||
221 | * Try to move data nodes from the same | ||
222 | * inode together. | ||
223 | */ | ||
224 | err = joinup(c, sleb, inum, blk, &data); | ||
225 | if (err) | ||
226 | goto out; | ||
227 | } | ||
228 | inum = key_inum(c, &snod->key); | ||
229 | blk = key_block(c, &snod->key); | ||
230 | } | ||
231 | list_add_tail(lst, &data); | ||
232 | } else if (snod->len > MEDIUM_NODE_WM) | ||
233 | list_add_tail(lst, &large); | ||
234 | else if (snod->len > SMALL_NODE_WM) | ||
235 | list_add_tail(lst, &medium); | ||
236 | else | ||
237 | list_add_tail(lst, &small); | ||
238 | |||
239 | /* And find the smallest node */ | ||
240 | if (snod->len < min) | ||
241 | min = snod->len; | ||
242 | } | 349 | } |
243 | 350 | ||
244 | /* | 351 | /* Sort data and non-data nodes */ |
245 | * Join the tree lists so that we'd have one roughly sorted list | 352 | list_sort(c, &sleb->nodes, &data_nodes_cmp); |
246 | * ('large' will be the head of the joined list). | 353 | list_sort(c, nondata, &nondata_nodes_cmp); |
247 | */ | 354 | return 0; |
248 | list_splice(&data, &large); | 355 | } |
249 | list_splice(&medium, large.prev); | 356 | |
250 | list_splice(&small, large.prev); | 357 | /** |
358 | * move_node - move a node. | ||
359 | * @c: UBIFS file-system description object | ||
360 | * @sleb: describes the LEB to move nodes from | ||
361 | * @snod: the mode to move | ||
362 | * @wbuf: write-buffer to move node to | ||
363 | * | ||
364 | * This function moves node @snod to @wbuf, changes TNC correspondingly, and | ||
365 | * destroys @snod. Returns zero in case of success and a negative error code in | ||
366 | * case of failure. | ||
367 | */ | ||
368 | static int move_node(struct ubifs_info *c, struct ubifs_scan_leb *sleb, | ||
369 | struct ubifs_scan_node *snod, struct ubifs_wbuf *wbuf) | ||
370 | { | ||
371 | int err, new_lnum = wbuf->lnum, new_offs = wbuf->offs + wbuf->used; | ||
372 | |||
373 | cond_resched(); | ||
374 | err = ubifs_wbuf_write_nolock(wbuf, snod->node, snod->len); | ||
375 | if (err) | ||
376 | return err; | ||
377 | |||
378 | err = ubifs_tnc_replace(c, &snod->key, sleb->lnum, | ||
379 | snod->offs, new_lnum, new_offs, | ||
380 | snod->len); | ||
381 | list_del(&snod->list); | ||
382 | kfree(snod); | ||
383 | return err; | ||
384 | } | ||
385 | |||
386 | /** | ||
387 | * move_nodes - move nodes. | ||
388 | * @c: UBIFS file-system description object | ||
389 | * @sleb: describes the LEB to move nodes from | ||
390 | * | ||
391 | * This function moves valid nodes from data LEB described by @sleb to the GC | ||
392 | * journal head. This function returns zero in case of success, %-EAGAIN if | ||
393 | * commit is required, and other negative error codes in case of other | ||
394 | * failures. | ||
395 | */ | ||
396 | static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) | ||
397 | { | ||
398 | int err, min; | ||
399 | LIST_HEAD(nondata); | ||
400 | struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf; | ||
251 | 401 | ||
252 | if (wbuf->lnum == -1) { | 402 | if (wbuf->lnum == -1) { |
253 | /* | 403 | /* |
@@ -256,42 +406,59 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) | |||
256 | */ | 406 | */ |
257 | err = switch_gc_head(c); | 407 | err = switch_gc_head(c); |
258 | if (err) | 408 | if (err) |
259 | goto out; | 409 | return err; |
260 | } | 410 | } |
261 | 411 | ||
412 | err = sort_nodes(c, sleb, &nondata, &min); | ||
413 | if (err) | ||
414 | goto out; | ||
415 | |||
262 | /* Write nodes to their new location. Use the first-fit strategy */ | 416 | /* Write nodes to their new location. Use the first-fit strategy */ |
263 | while (1) { | 417 | while (1) { |
264 | avail = c->leb_size - wbuf->offs - wbuf->used; | 418 | int avail; |
265 | list_for_each_entry_safe(snod, tmp, &large, list) { | 419 | struct ubifs_scan_node *snod, *tmp; |
266 | int new_lnum, new_offs; | 420 | |
421 | /* Move data nodes */ | ||
422 | list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) { | ||
423 | avail = c->leb_size - wbuf->offs - wbuf->used; | ||
424 | if (snod->len > avail) | ||
425 | /* | ||
426 | * Do not skip data nodes in order to optimize | ||
427 | * bulk-read. | ||
428 | */ | ||
429 | break; | ||
430 | |||
431 | err = move_node(c, sleb, snod, wbuf); | ||
432 | if (err) | ||
433 | goto out; | ||
434 | } | ||
267 | 435 | ||
436 | /* Move non-data nodes */ | ||
437 | list_for_each_entry_safe(snod, tmp, &nondata, list) { | ||
438 | avail = c->leb_size - wbuf->offs - wbuf->used; | ||
268 | if (avail < min) | 439 | if (avail < min) |
269 | break; | 440 | break; |
270 | 441 | ||
271 | if (snod->len > avail) | 442 | if (snod->len > avail) { |
272 | /* This node does not fit */ | 443 | /* |
444 | * Keep going only if this is an inode with | ||
445 | * some data. Otherwise stop and switch the GC | ||
446 | * head. IOW, we assume that data-less inode | ||
447 | * nodes and direntry nodes are roughly of the | ||
448 | * same size. | ||
449 | */ | ||
450 | if (key_type(c, &snod->key) == UBIFS_DENT_KEY || | ||
451 | snod->len == UBIFS_INO_NODE_SZ) | ||
452 | break; | ||
273 | continue; | 453 | continue; |
454 | } | ||
274 | 455 | ||
275 | cond_resched(); | 456 | err = move_node(c, sleb, snod, wbuf); |
276 | |||
277 | new_lnum = wbuf->lnum; | ||
278 | new_offs = wbuf->offs + wbuf->used; | ||
279 | err = ubifs_wbuf_write_nolock(wbuf, snod->node, | ||
280 | snod->len); | ||
281 | if (err) | 457 | if (err) |
282 | goto out; | 458 | goto out; |
283 | err = ubifs_tnc_replace(c, &snod->key, sleb->lnum, | ||
284 | snod->offs, new_lnum, new_offs, | ||
285 | snod->len); | ||
286 | if (err) | ||
287 | goto out; | ||
288 | |||
289 | avail = c->leb_size - wbuf->offs - wbuf->used; | ||
290 | list_del(&snod->list); | ||
291 | kfree(snod); | ||
292 | } | 459 | } |
293 | 460 | ||
294 | if (list_empty(&large)) | 461 | if (list_empty(&sleb->nodes) && list_empty(&nondata)) |
295 | break; | 462 | break; |
296 | 463 | ||
297 | /* | 464 | /* |
@@ -306,10 +473,7 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb) | |||
306 | return 0; | 473 | return 0; |
307 | 474 | ||
308 | out: | 475 | out: |
309 | list_for_each_entry_safe(snod, tmp, &large, list) { | 476 | list_splice_tail(&nondata, &sleb->nodes); |
310 | list_del(&snod->list); | ||
311 | kfree(snod); | ||
312 | } | ||
313 | return err; | 477 | return err; |
314 | } | 478 | } |
315 | 479 | ||
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index a11ca0958a23..64b5f3a309f5 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c | |||
@@ -114,7 +114,7 @@ static inline void zero_trun_node_unused(struct ubifs_trun_node *trun) | |||
114 | */ | 114 | */ |
115 | static int reserve_space(struct ubifs_info *c, int jhead, int len) | 115 | static int reserve_space(struct ubifs_info *c, int jhead, int len) |
116 | { | 116 | { |
117 | int err = 0, err1, retries = 0, avail, lnum, offs, free, squeeze; | 117 | int err = 0, err1, retries = 0, avail, lnum, offs, squeeze; |
118 | struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf; | 118 | struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf; |
119 | 119 | ||
120 | /* | 120 | /* |
@@ -139,10 +139,9 @@ again: | |||
139 | * Write buffer wasn't seek'ed or there is no enough space - look for an | 139 | * Write buffer wasn't seek'ed or there is no enough space - look for an |
140 | * LEB with some empty space. | 140 | * LEB with some empty space. |
141 | */ | 141 | */ |
142 | lnum = ubifs_find_free_space(c, len, &free, squeeze); | 142 | lnum = ubifs_find_free_space(c, len, &offs, squeeze); |
143 | if (lnum >= 0) { | 143 | if (lnum >= 0) { |
144 | /* Found an LEB, add it to the journal head */ | 144 | /* Found an LEB, add it to the journal head */ |
145 | offs = c->leb_size - free; | ||
146 | err = ubifs_add_bud_to_log(c, jhead, lnum, offs); | 145 | err = ubifs_add_bud_to_log(c, jhead, lnum, offs); |
147 | if (err) | 146 | if (err) |
148 | goto out_return; | 147 | goto out_return; |
@@ -1366,7 +1365,7 @@ out_ro: | |||
1366 | * @host: host inode | 1365 | * @host: host inode |
1367 | * | 1366 | * |
1368 | * This function writes the updated version of an extended attribute inode and | 1367 | * This function writes the updated version of an extended attribute inode and |
1369 | * the host inode tho the journal (to the base head). The host inode is written | 1368 | * the host inode to the journal (to the base head). The host inode is written |
1370 | * after the extended attribute inode in order to guarantee that the extended | 1369 | * after the extended attribute inode in order to guarantee that the extended |
1371 | * attribute will be flushed when the inode is synchronized by 'fsync()' and | 1370 | * attribute will be flushed when the inode is synchronized by 'fsync()' and |
1372 | * consequently, the write-buffer is synchronized. This function returns zero | 1371 | * consequently, the write-buffer is synchronized. This function returns zero |
diff --git a/fs/ubifs/key.h b/fs/ubifs/key.h index efb3430a2581..5fa27ea031ba 100644 --- a/fs/ubifs/key.h +++ b/fs/ubifs/key.h | |||
@@ -381,8 +381,8 @@ static inline ino_t key_inum_flash(const struct ubifs_info *c, const void *k) | |||
381 | * @c: UBIFS file-system description object | 381 | * @c: UBIFS file-system description object |
382 | * @key: the key to get hash from | 382 | * @key: the key to get hash from |
383 | */ | 383 | */ |
384 | static inline int key_hash(const struct ubifs_info *c, | 384 | static inline uint32_t key_hash(const struct ubifs_info *c, |
385 | const union ubifs_key *key) | 385 | const union ubifs_key *key) |
386 | { | 386 | { |
387 | return key->u32[1] & UBIFS_S_KEY_HASH_MASK; | 387 | return key->u32[1] & UBIFS_S_KEY_HASH_MASK; |
388 | } | 388 | } |
@@ -392,7 +392,7 @@ static inline int key_hash(const struct ubifs_info *c, | |||
392 | * @c: UBIFS file-system description object | 392 | * @c: UBIFS file-system description object |
393 | * @k: the key to get hash from | 393 | * @k: the key to get hash from |
394 | */ | 394 | */ |
395 | static inline int key_hash_flash(const struct ubifs_info *c, const void *k) | 395 | static inline uint32_t key_hash_flash(const struct ubifs_info *c, const void *k) |
396 | { | 396 | { |
397 | const union ubifs_key *key = k; | 397 | const union ubifs_key *key = k; |
398 | 398 | ||
diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c index 3e0aa7367556..56e33772a1ee 100644 --- a/fs/ubifs/log.c +++ b/fs/ubifs/log.c | |||
@@ -239,7 +239,7 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs) | |||
239 | } | 239 | } |
240 | 240 | ||
241 | /* | 241 | /* |
242 | * Make sure the the amount of space in buds will not exceed | 242 | * Make sure the amount of space in buds will not exceed the |
243 | * 'c->max_bud_bytes' limit, because we want to guarantee mount time | 243 | * 'c->max_bud_bytes' limit, because we want to guarantee mount time |
244 | * limits. | 244 | * limits. |
245 | * | 245 | * |
@@ -367,7 +367,6 @@ static void remove_buds(struct ubifs_info *c) | |||
367 | bud->jhead, c->leb_size - bud->start, | 367 | 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 | list_del(&bud->list); | ||
371 | /* | 370 | /* |
372 | * If the commit does not finish, the recovery will need | 371 | * If the commit does not finish, the recovery will need |
373 | * to replay the journal, in which case the old buds | 372 | * to replay the journal, in which case the old buds |
@@ -375,7 +374,7 @@ static void remove_buds(struct ubifs_info *c) | |||
375 | * commit i.e. do not allow them to be garbage | 374 | * commit i.e. do not allow them to be garbage |
376 | * collected. | 375 | * collected. |
377 | */ | 376 | */ |
378 | list_add(&bud->list, &c->old_buds); | 377 | list_move(&bud->list, &c->old_buds); |
379 | } | 378 | } |
380 | } | 379 | } |
381 | spin_unlock(&c->buds_lock); | 380 | spin_unlock(&c->buds_lock); |
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c index 3216a1f277f8..8cbfb8248025 100644 --- a/fs/ubifs/lpt_commit.c +++ b/fs/ubifs/lpt_commit.c | |||
@@ -229,7 +229,7 @@ static int layout_cnodes(struct ubifs_info *c) | |||
229 | while (offs + len > c->leb_size) { | 229 | while (offs + len > c->leb_size) { |
230 | alen = ALIGN(offs, c->min_io_size); | 230 | alen = ALIGN(offs, c->min_io_size); |
231 | upd_ltab(c, lnum, c->leb_size - alen, alen - offs); | 231 | upd_ltab(c, lnum, c->leb_size - alen, alen - offs); |
232 | dbg_chk_lpt_sz(c, 2, alen - offs); | 232 | dbg_chk_lpt_sz(c, 2, c->leb_size - offs); |
233 | err = alloc_lpt_leb(c, &lnum); | 233 | err = alloc_lpt_leb(c, &lnum); |
234 | if (err) | 234 | if (err) |
235 | goto no_space; | 235 | goto no_space; |
@@ -272,7 +272,7 @@ static int layout_cnodes(struct ubifs_info *c) | |||
272 | if (offs + c->lsave_sz > c->leb_size) { | 272 | if (offs + c->lsave_sz > c->leb_size) { |
273 | alen = ALIGN(offs, c->min_io_size); | 273 | alen = ALIGN(offs, c->min_io_size); |
274 | upd_ltab(c, lnum, c->leb_size - alen, alen - offs); | 274 | upd_ltab(c, lnum, c->leb_size - alen, alen - offs); |
275 | dbg_chk_lpt_sz(c, 2, alen - offs); | 275 | dbg_chk_lpt_sz(c, 2, c->leb_size - offs); |
276 | err = alloc_lpt_leb(c, &lnum); | 276 | err = alloc_lpt_leb(c, &lnum); |
277 | if (err) | 277 | if (err) |
278 | goto no_space; | 278 | goto no_space; |
@@ -292,7 +292,7 @@ static int layout_cnodes(struct ubifs_info *c) | |||
292 | if (offs + c->ltab_sz > c->leb_size) { | 292 | if (offs + c->ltab_sz > c->leb_size) { |
293 | alen = ALIGN(offs, c->min_io_size); | 293 | alen = ALIGN(offs, c->min_io_size); |
294 | upd_ltab(c, lnum, c->leb_size - alen, alen - offs); | 294 | upd_ltab(c, lnum, c->leb_size - alen, alen - offs); |
295 | dbg_chk_lpt_sz(c, 2, alen - offs); | 295 | dbg_chk_lpt_sz(c, 2, c->leb_size - offs); |
296 | err = alloc_lpt_leb(c, &lnum); | 296 | err = alloc_lpt_leb(c, &lnum); |
297 | if (err) | 297 | if (err) |
298 | goto no_space; | 298 | goto no_space; |
@@ -416,14 +416,12 @@ static int write_cnodes(struct ubifs_info *c) | |||
416 | alen, UBI_SHORTTERM); | 416 | alen, UBI_SHORTTERM); |
417 | if (err) | 417 | if (err) |
418 | return err; | 418 | return err; |
419 | dbg_chk_lpt_sz(c, 4, alen - wlen); | ||
420 | } | 419 | } |
421 | dbg_chk_lpt_sz(c, 2, 0); | 420 | dbg_chk_lpt_sz(c, 2, c->leb_size - offs); |
422 | err = realloc_lpt_leb(c, &lnum); | 421 | err = realloc_lpt_leb(c, &lnum); |
423 | if (err) | 422 | if (err) |
424 | goto no_space; | 423 | goto no_space; |
425 | offs = 0; | 424 | offs = from = 0; |
426 | from = 0; | ||
427 | ubifs_assert(lnum >= c->lpt_first && | 425 | ubifs_assert(lnum >= c->lpt_first && |
428 | lnum <= c->lpt_last); | 426 | lnum <= c->lpt_last); |
429 | err = ubifs_leb_unmap(c, lnum); | 427 | err = ubifs_leb_unmap(c, lnum); |
@@ -477,11 +475,11 @@ static int write_cnodes(struct ubifs_info *c) | |||
477 | UBI_SHORTTERM); | 475 | UBI_SHORTTERM); |
478 | if (err) | 476 | if (err) |
479 | return err; | 477 | return err; |
480 | dbg_chk_lpt_sz(c, 2, alen - wlen); | 478 | dbg_chk_lpt_sz(c, 2, c->leb_size - offs); |
481 | err = realloc_lpt_leb(c, &lnum); | 479 | err = realloc_lpt_leb(c, &lnum); |
482 | if (err) | 480 | if (err) |
483 | goto no_space; | 481 | goto no_space; |
484 | offs = 0; | 482 | offs = from = 0; |
485 | ubifs_assert(lnum >= c->lpt_first && | 483 | ubifs_assert(lnum >= c->lpt_first && |
486 | lnum <= c->lpt_last); | 484 | lnum <= c->lpt_last); |
487 | err = ubifs_leb_unmap(c, lnum); | 485 | err = ubifs_leb_unmap(c, lnum); |
@@ -504,11 +502,11 @@ static int write_cnodes(struct ubifs_info *c) | |||
504 | UBI_SHORTTERM); | 502 | UBI_SHORTTERM); |
505 | if (err) | 503 | if (err) |
506 | return err; | 504 | return err; |
507 | dbg_chk_lpt_sz(c, 2, alen - wlen); | 505 | dbg_chk_lpt_sz(c, 2, c->leb_size - offs); |
508 | err = realloc_lpt_leb(c, &lnum); | 506 | err = realloc_lpt_leb(c, &lnum); |
509 | if (err) | 507 | if (err) |
510 | goto no_space; | 508 | goto no_space; |
511 | offs = 0; | 509 | offs = from = 0; |
512 | ubifs_assert(lnum >= c->lpt_first && | 510 | ubifs_assert(lnum >= c->lpt_first && |
513 | lnum <= c->lpt_last); | 511 | lnum <= c->lpt_last); |
514 | err = ubifs_leb_unmap(c, lnum); | 512 | err = ubifs_leb_unmap(c, lnum); |
@@ -1756,10 +1754,16 @@ int dbg_chk_lpt_free_spc(struct ubifs_info *c) | |||
1756 | /** | 1754 | /** |
1757 | * dbg_chk_lpt_sz - check LPT does not write more than LPT size. | 1755 | * dbg_chk_lpt_sz - check LPT does not write more than LPT size. |
1758 | * @c: the UBIFS file-system description object | 1756 | * @c: the UBIFS file-system description object |
1759 | * @action: action | 1757 | * @action: what to do |
1760 | * @len: length written | 1758 | * @len: length written |
1761 | * | 1759 | * |
1762 | * This function returns %0 on success and a negative error code on failure. | 1760 | * This function returns %0 on success and a negative error code on failure. |
1761 | * The @action argument may be one of: | ||
1762 | * o %0 - LPT debugging checking starts, initialize debugging variables; | ||
1763 | * o %1 - wrote an LPT node, increase LPT size by @len bytes; | ||
1764 | * o %2 - switched to a different LEB and wasted @len bytes; | ||
1765 | * o %3 - check that we've written the right number of bytes. | ||
1766 | * o %4 - wasted @len bytes; | ||
1763 | */ | 1767 | */ |
1764 | int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len) | 1768 | int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len) |
1765 | { | 1769 | { |
@@ -1917,12 +1921,12 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum) | |||
1917 | lnum, offs); | 1921 | lnum, offs); |
1918 | err = ubifs_unpack_nnode(c, buf, &nnode); | 1922 | err = ubifs_unpack_nnode(c, buf, &nnode); |
1919 | for (i = 0; i < UBIFS_LPT_FANOUT; i++) { | 1923 | for (i = 0; i < UBIFS_LPT_FANOUT; i++) { |
1920 | printk("%d:%d", nnode.nbranch[i].lnum, | 1924 | printk(KERN_CONT "%d:%d", nnode.nbranch[i].lnum, |
1921 | nnode.nbranch[i].offs); | 1925 | nnode.nbranch[i].offs); |
1922 | if (i != UBIFS_LPT_FANOUT - 1) | 1926 | if (i != UBIFS_LPT_FANOUT - 1) |
1923 | printk(", "); | 1927 | printk(KERN_CONT ", "); |
1924 | } | 1928 | } |
1925 | printk("\n"); | 1929 | printk(KERN_CONT "\n"); |
1926 | break; | 1930 | break; |
1927 | } | 1931 | } |
1928 | case UBIFS_LPT_LTAB: | 1932 | case UBIFS_LPT_LTAB: |
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index 90acac603e63..10662975d2ef 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c | |||
@@ -425,59 +425,35 @@ static void clean_buf(const struct ubifs_info *c, void **buf, int lnum, | |||
425 | * @lnum: LEB number of the LEB from which @buf was read | 425 | * @lnum: LEB number of the LEB from which @buf was read |
426 | * @offs: offset from which @buf was read | 426 | * @offs: offset from which @buf was read |
427 | * | 427 | * |
428 | * This function scans @buf for more nodes and returns %0 is a node is found and | 428 | * This function ensures that the corrupted node at @offs is the last thing |
429 | * %1 if no more nodes are found. | 429 | * written to a LEB. This function returns %1 if more data is not found and |
430 | * %0 if more data is found. | ||
430 | */ | 431 | */ |
431 | static int no_more_nodes(const struct ubifs_info *c, void *buf, int len, | 432 | static int no_more_nodes(const struct ubifs_info *c, void *buf, int len, |
432 | int lnum, int offs) | 433 | int lnum, int offs) |
433 | { | 434 | { |
434 | int skip, next_offs = 0; | 435 | struct ubifs_ch *ch = buf; |
436 | int skip, dlen = le32_to_cpu(ch->len); | ||
435 | 437 | ||
436 | if (len > UBIFS_DATA_NODE_SZ) { | 438 | /* Check for empty space after the corrupt node's common header */ |
437 | struct ubifs_ch *ch = buf; | 439 | skip = ALIGN(offs + UBIFS_CH_SZ, c->min_io_size) - offs; |
438 | int dlen = le32_to_cpu(ch->len); | 440 | if (is_empty(buf + skip, len - skip)) |
439 | 441 | return 1; | |
440 | if (ch->node_type == UBIFS_DATA_NODE && dlen >= UBIFS_CH_SZ && | 442 | /* |
441 | dlen <= UBIFS_MAX_DATA_NODE_SZ) | 443 | * The area after the common header size is not empty, so the common |
442 | /* The corrupt node looks like a data node */ | 444 | * header must be intact. Check it. |
443 | next_offs = ALIGN(offs + dlen, 8); | 445 | */ |
444 | } | 446 | if (ubifs_check_node(c, buf, lnum, offs, 1, 0) != -EUCLEAN) { |
445 | 447 | dbg_rcvry("unexpected bad common header at %d:%d", lnum, offs); | |
446 | if (c->min_io_size == 1) | 448 | return 0; |
447 | skip = 8; | ||
448 | else | ||
449 | skip = ALIGN(offs + 1, c->min_io_size) - offs; | ||
450 | |||
451 | offs += skip; | ||
452 | buf += skip; | ||
453 | len -= skip; | ||
454 | while (len > 8) { | ||
455 | struct ubifs_ch *ch = buf; | ||
456 | uint32_t magic = le32_to_cpu(ch->magic); | ||
457 | int ret; | ||
458 | |||
459 | if (magic == UBIFS_NODE_MAGIC) { | ||
460 | ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 1); | ||
461 | if (ret == SCANNED_A_NODE || ret > 0) { | ||
462 | /* | ||
463 | * There is a small chance this is just data in | ||
464 | * a data node, so check that possibility. e.g. | ||
465 | * this is part of a file that itself contains | ||
466 | * a UBIFS image. | ||
467 | */ | ||
468 | if (next_offs && offs + le32_to_cpu(ch->len) <= | ||
469 | next_offs) | ||
470 | continue; | ||
471 | dbg_rcvry("unexpected node at %d:%d", lnum, | ||
472 | offs); | ||
473 | return 0; | ||
474 | } | ||
475 | } | ||
476 | offs += 8; | ||
477 | buf += 8; | ||
478 | len -= 8; | ||
479 | } | 449 | } |
480 | return 1; | 450 | /* Now we know the corrupt node's length we can skip over it */ |
451 | skip = ALIGN(offs + dlen, c->min_io_size) - offs; | ||
452 | /* After which there should be empty space */ | ||
453 | if (is_empty(buf + skip, len - skip)) | ||
454 | return 1; | ||
455 | dbg_rcvry("unexpected data at %d:%d", lnum, offs + skip); | ||
456 | return 0; | ||
481 | } | 457 | } |
482 | 458 | ||
483 | /** | 459 | /** |
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index ce42a7b0ca5a..11cc80125a49 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c | |||
@@ -143,7 +143,7 @@ static int set_bud_lprops(struct ubifs_info *c, struct replay_entry *r) | |||
143 | dirty -= c->leb_size - lp->free; | 143 | dirty -= c->leb_size - lp->free; |
144 | /* | 144 | /* |
145 | * If the replay order was perfect the dirty space would now be | 145 | * If the replay order was perfect the dirty space would now be |
146 | * zero. The order is not perfect because the the journal heads | 146 | * zero. The order is not perfect because the journal heads |
147 | * race with each other. This is not a problem but is does mean | 147 | * race with each other. This is not a problem but is does mean |
148 | * that the dirty space may temporarily exceed c->leb_size | 148 | * that the dirty space may temporarily exceed c->leb_size |
149 | * during the replay. | 149 | * during the replay. |
diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c index e070c643d1bb..57085e43320f 100644 --- a/fs/ubifs/sb.c +++ b/fs/ubifs/sb.c | |||
@@ -193,6 +193,7 @@ static int create_default_filesystem(struct ubifs_info *c) | |||
193 | if (tmp64 > DEFAULT_MAX_RP_SIZE) | 193 | if (tmp64 > DEFAULT_MAX_RP_SIZE) |
194 | tmp64 = DEFAULT_MAX_RP_SIZE; | 194 | tmp64 = DEFAULT_MAX_RP_SIZE; |
195 | sup->rp_size = cpu_to_le64(tmp64); | 195 | sup->rp_size = cpu_to_le64(tmp64); |
196 | sup->ro_compat_version = cpu_to_le32(UBIFS_RO_COMPAT_VERSION); | ||
196 | 197 | ||
197 | err = ubifs_write_node(c, sup, UBIFS_SB_NODE_SZ, 0, 0, UBI_LONGTERM); | 198 | err = ubifs_write_node(c, sup, UBIFS_SB_NODE_SZ, 0, 0, UBI_LONGTERM); |
198 | kfree(sup); | 199 | kfree(sup); |
@@ -532,17 +533,39 @@ int ubifs_read_superblock(struct ubifs_info *c) | |||
532 | if (IS_ERR(sup)) | 533 | if (IS_ERR(sup)) |
533 | return PTR_ERR(sup); | 534 | return PTR_ERR(sup); |
534 | 535 | ||
536 | c->fmt_version = le32_to_cpu(sup->fmt_version); | ||
537 | c->ro_compat_version = le32_to_cpu(sup->ro_compat_version); | ||
538 | |||
535 | /* | 539 | /* |
536 | * The software supports all previous versions but not future versions, | 540 | * The software supports all previous versions but not future versions, |
537 | * due to the unavailability of time-travelling equipment. | 541 | * due to the unavailability of time-travelling equipment. |
538 | */ | 542 | */ |
539 | c->fmt_version = le32_to_cpu(sup->fmt_version); | ||
540 | if (c->fmt_version > UBIFS_FORMAT_VERSION) { | 543 | if (c->fmt_version > UBIFS_FORMAT_VERSION) { |
541 | ubifs_err("on-flash format version is %d, but software only " | 544 | struct super_block *sb = c->vfs_sb; |
542 | "supports up to version %d", c->fmt_version, | 545 | int mounting_ro = sb->s_flags & MS_RDONLY; |
543 | UBIFS_FORMAT_VERSION); | 546 | |
544 | err = -EINVAL; | 547 | ubifs_assert(!c->ro_media || mounting_ro); |
545 | goto out; | 548 | if (!mounting_ro || |
549 | c->ro_compat_version > UBIFS_RO_COMPAT_VERSION) { | ||
550 | ubifs_err("on-flash format version is w%d/r%d, but " | ||
551 | "software only supports up to version " | ||
552 | "w%d/r%d", c->fmt_version, | ||
553 | c->ro_compat_version, UBIFS_FORMAT_VERSION, | ||
554 | UBIFS_RO_COMPAT_VERSION); | ||
555 | if (c->ro_compat_version <= UBIFS_RO_COMPAT_VERSION) { | ||
556 | ubifs_msg("only R/O mounting is possible"); | ||
557 | err = -EROFS; | ||
558 | } else | ||
559 | err = -EINVAL; | ||
560 | goto out; | ||
561 | } | ||
562 | |||
563 | /* | ||
564 | * The FS is mounted R/O, and the media format is | ||
565 | * R/O-compatible with the UBIFS implementation, so we can | ||
566 | * mount. | ||
567 | */ | ||
568 | c->rw_incompat = 1; | ||
546 | } | 569 | } |
547 | 570 | ||
548 | if (c->fmt_version < 3) { | 571 | if (c->fmt_version < 3) { |
@@ -623,7 +646,6 @@ int ubifs_read_superblock(struct ubifs_info *c) | |||
623 | c->main_lebs = c->leb_cnt - UBIFS_SB_LEBS - UBIFS_MST_LEBS; | 646 | c->main_lebs = c->leb_cnt - UBIFS_SB_LEBS - UBIFS_MST_LEBS; |
624 | c->main_lebs -= c->log_lebs + c->lpt_lebs + c->orph_lebs; | 647 | c->main_lebs -= c->log_lebs + c->lpt_lebs + c->orph_lebs; |
625 | c->main_first = c->leb_cnt - c->main_lebs; | 648 | c->main_first = c->leb_cnt - c->main_lebs; |
626 | c->report_rp_size = ubifs_reported_space(c, c->rp_size); | ||
627 | 649 | ||
628 | err = validate_sb(c, sup); | 650 | err = validate_sb(c, sup); |
629 | out: | 651 | out: |
diff --git a/fs/ubifs/shrinker.c b/fs/ubifs/shrinker.c index e7bab52a1410..02feb59cefca 100644 --- a/fs/ubifs/shrinker.c +++ b/fs/ubifs/shrinker.c | |||
@@ -206,8 +206,7 @@ static int shrink_tnc_trees(int nr, int age, int *contention) | |||
206 | * Move this one to the end of the list to provide some | 206 | * Move this one to the end of the list to provide some |
207 | * fairness. | 207 | * fairness. |
208 | */ | 208 | */ |
209 | list_del(&c->infos_list); | 209 | list_move_tail(&c->infos_list, &ubifs_infos); |
210 | list_add_tail(&c->infos_list, &ubifs_infos); | ||
211 | mutex_unlock(&c->umount_mutex); | 210 | mutex_unlock(&c->umount_mutex); |
212 | if (freed >= nr) | 211 | if (freed >= nr) |
213 | break; | 212 | break; |
@@ -263,8 +262,7 @@ static int kick_a_thread(void) | |||
263 | } | 262 | } |
264 | 263 | ||
265 | if (i == 1) { | 264 | if (i == 1) { |
266 | list_del(&c->infos_list); | 265 | list_move_tail(&c->infos_list, &ubifs_infos); |
267 | list_add_tail(&c->infos_list, &ubifs_infos); | ||
268 | spin_unlock(&ubifs_infos_lock); | 266 | spin_unlock(&ubifs_infos_lock); |
269 | 267 | ||
270 | ubifs_request_bg_commit(c); | 268 | ubifs_request_bg_commit(c); |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index c5c98355459a..faa44f90608a 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -421,8 +421,8 @@ static int ubifs_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
421 | seq_printf(s, ",no_chk_data_crc"); | 421 | seq_printf(s, ",no_chk_data_crc"); |
422 | 422 | ||
423 | if (c->mount_opts.override_compr) { | 423 | if (c->mount_opts.override_compr) { |
424 | seq_printf(s, ",compr="); | 424 | seq_printf(s, ",compr=%s", |
425 | seq_printf(s, ubifs_compr_name(c->mount_opts.compr_type)); | 425 | ubifs_compr_name(c->mount_opts.compr_type)); |
426 | } | 426 | } |
427 | 427 | ||
428 | return 0; | 428 | return 0; |
@@ -700,6 +700,8 @@ static int init_constants_sb(struct ubifs_info *c) | |||
700 | if (err) | 700 | if (err) |
701 | return err; | 701 | return err; |
702 | 702 | ||
703 | /* Initialize effective LEB size used in budgeting calculations */ | ||
704 | c->idx_leb_size = c->leb_size - c->max_idx_node_sz; | ||
703 | return 0; | 705 | return 0; |
704 | } | 706 | } |
705 | 707 | ||
@@ -716,6 +718,7 @@ static void init_constants_master(struct ubifs_info *c) | |||
716 | long long tmp64; | 718 | long long tmp64; |
717 | 719 | ||
718 | c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); | 720 | c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); |
721 | c->report_rp_size = ubifs_reported_space(c, c->rp_size); | ||
719 | 722 | ||
720 | /* | 723 | /* |
721 | * Calculate total amount of FS blocks. This number is not used | 724 | * Calculate total amount of FS blocks. This number is not used |
@@ -1201,7 +1204,7 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1201 | goto out_cbuf; | 1204 | goto out_cbuf; |
1202 | 1205 | ||
1203 | /* Create background thread */ | 1206 | /* Create background thread */ |
1204 | c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name); | 1207 | c->bgt = kthread_create(ubifs_bg_thread, c, "%s", c->bgt_name); |
1205 | if (IS_ERR(c->bgt)) { | 1208 | if (IS_ERR(c->bgt)) { |
1206 | err = PTR_ERR(c->bgt); | 1209 | err = PTR_ERR(c->bgt); |
1207 | c->bgt = NULL; | 1210 | c->bgt = NULL; |
@@ -1318,11 +1321,15 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1318 | else { | 1321 | else { |
1319 | c->need_recovery = 0; | 1322 | c->need_recovery = 0; |
1320 | ubifs_msg("recovery completed"); | 1323 | ubifs_msg("recovery completed"); |
1321 | /* GC LEB has to be empty and taken at this point */ | 1324 | /* |
1322 | ubifs_assert(c->lst.taken_empty_lebs == 1); | 1325 | * GC LEB has to be empty and taken at this point. But |
1326 | * the journal head LEBs may also be accounted as | ||
1327 | * "empty taken" if they are empty. | ||
1328 | */ | ||
1329 | ubifs_assert(c->lst.taken_empty_lebs > 0); | ||
1323 | } | 1330 | } |
1324 | } else | 1331 | } else |
1325 | ubifs_assert(c->lst.taken_empty_lebs == 1); | 1332 | ubifs_assert(c->lst.taken_empty_lebs > 0); |
1326 | 1333 | ||
1327 | err = dbg_check_filesystem(c); | 1334 | err = dbg_check_filesystem(c); |
1328 | if (err) | 1335 | if (err) |
@@ -1344,8 +1351,9 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1344 | x = (long long)c->log_lebs * c->leb_size + c->max_bud_bytes; | 1351 | x = (long long)c->log_lebs * c->leb_size + c->max_bud_bytes; |
1345 | ubifs_msg("journal size: %lld bytes (%lld KiB, %lld MiB, %d " | 1352 | ubifs_msg("journal size: %lld bytes (%lld KiB, %lld MiB, %d " |
1346 | "LEBs)", x, x >> 10, x >> 20, c->log_lebs + c->max_bud_cnt); | 1353 | "LEBs)", x, x >> 10, x >> 20, c->log_lebs + c->max_bud_cnt); |
1347 | ubifs_msg("media format: %d (latest is %d)", | 1354 | ubifs_msg("media format: w%d/r%d (latest is w%d/r%d)", |
1348 | c->fmt_version, UBIFS_FORMAT_VERSION); | 1355 | c->fmt_version, c->ro_compat_version, |
1356 | UBIFS_FORMAT_VERSION, UBIFS_RO_COMPAT_VERSION); | ||
1349 | ubifs_msg("default compressor: %s", ubifs_compr_name(c->default_compr)); | 1357 | ubifs_msg("default compressor: %s", ubifs_compr_name(c->default_compr)); |
1350 | ubifs_msg("reserved for root: %llu bytes (%llu KiB)", | 1358 | ubifs_msg("reserved for root: %llu bytes (%llu KiB)", |
1351 | c->report_rp_size, c->report_rp_size >> 10); | 1359 | c->report_rp_size, c->report_rp_size >> 10); |
@@ -1485,6 +1493,15 @@ static int ubifs_remount_rw(struct ubifs_info *c) | |||
1485 | { | 1493 | { |
1486 | int err, lnum; | 1494 | int err, lnum; |
1487 | 1495 | ||
1496 | if (c->rw_incompat) { | ||
1497 | ubifs_err("the file-system is not R/W-compatible"); | ||
1498 | ubifs_msg("on-flash format version is w%d/r%d, but software " | ||
1499 | "only supports up to version w%d/r%d", c->fmt_version, | ||
1500 | c->ro_compat_version, UBIFS_FORMAT_VERSION, | ||
1501 | UBIFS_RO_COMPAT_VERSION); | ||
1502 | return -EROFS; | ||
1503 | } | ||
1504 | |||
1488 | mutex_lock(&c->umount_mutex); | 1505 | mutex_lock(&c->umount_mutex); |
1489 | dbg_save_space_info(c); | 1506 | dbg_save_space_info(c); |
1490 | c->remounting_rw = 1; | 1507 | c->remounting_rw = 1; |
@@ -1554,7 +1571,7 @@ static int ubifs_remount_rw(struct ubifs_info *c) | |||
1554 | ubifs_create_buds_lists(c); | 1571 | ubifs_create_buds_lists(c); |
1555 | 1572 | ||
1556 | /* Create background thread */ | 1573 | /* Create background thread */ |
1557 | c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name); | 1574 | c->bgt = kthread_create(ubifs_bg_thread, c, "%s", c->bgt_name); |
1558 | if (IS_ERR(c->bgt)) { | 1575 | if (IS_ERR(c->bgt)) { |
1559 | err = PTR_ERR(c->bgt); | 1576 | err = PTR_ERR(c->bgt); |
1560 | c->bgt = NULL; | 1577 | c->bgt = NULL; |
@@ -1775,7 +1792,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) | |||
1775 | c->bu.buf = NULL; | 1792 | c->bu.buf = NULL; |
1776 | } | 1793 | } |
1777 | 1794 | ||
1778 | ubifs_assert(c->lst.taken_empty_lebs == 1); | 1795 | ubifs_assert(c->lst.taken_empty_lebs > 0); |
1779 | return 0; | 1796 | return 0; |
1780 | } | 1797 | } |
1781 | 1798 | ||
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index fa28a84c6a1b..f249f7b0d656 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c | |||
@@ -1252,7 +1252,7 @@ int ubifs_lookup_level0(struct ubifs_info *c, const union ubifs_key *key, | |||
1252 | * splitting in the middle of the colliding sequence. Also, when | 1252 | * splitting in the middle of the colliding sequence. Also, when |
1253 | * removing the leftmost key, we would have to correct the key of the | 1253 | * removing the leftmost key, we would have to correct the key of the |
1254 | * parent node, which would introduce additional complications. Namely, | 1254 | * parent node, which would introduce additional complications. Namely, |
1255 | * if we changed the the leftmost key of the parent znode, the garbage | 1255 | * if we changed the leftmost key of the parent znode, the garbage |
1256 | * collector would be unable to find it (GC is doing this when GC'ing | 1256 | * collector would be unable to find it (GC is doing this when GC'ing |
1257 | * indexing LEBs). Although we already have an additional RB-tree where | 1257 | * indexing LEBs). Although we already have an additional RB-tree where |
1258 | * we save such changed znodes (see 'ins_clr_old_idx_znode()') until | 1258 | * we save such changed znodes (see 'ins_clr_old_idx_znode()') until |
diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h index b25fc36cf72f..3eee07e0c495 100644 --- a/fs/ubifs/ubifs-media.h +++ b/fs/ubifs/ubifs-media.h | |||
@@ -36,9 +36,31 @@ | |||
36 | /* UBIFS node magic number (must not have the padding byte first or last) */ | 36 | /* UBIFS node magic number (must not have the padding byte first or last) */ |
37 | #define UBIFS_NODE_MAGIC 0x06101831 | 37 | #define UBIFS_NODE_MAGIC 0x06101831 |
38 | 38 | ||
39 | /* UBIFS on-flash format version */ | 39 | /* |
40 | * UBIFS on-flash format version. This version is increased when the on-flash | ||
41 | * format is changing. If this happens, UBIFS is will support older versions as | ||
42 | * well. But older UBIFS code will not support newer formats. Format changes | ||
43 | * will be rare and only when absolutely necessary, e.g. to fix a bug or to add | ||
44 | * a new feature. | ||
45 | * | ||
46 | * UBIFS went into mainline kernel with format version 4. The older formats | ||
47 | * were development formats. | ||
48 | */ | ||
40 | #define UBIFS_FORMAT_VERSION 4 | 49 | #define UBIFS_FORMAT_VERSION 4 |
41 | 50 | ||
51 | /* | ||
52 | * Read-only compatibility version. If the UBIFS format is changed, older UBIFS | ||
53 | * implementations will not be able to mount newer formats in read-write mode. | ||
54 | * However, depending on the change, it may be possible to mount newer formats | ||
55 | * in R/O mode. This is indicated by the R/O compatibility version which is | ||
56 | * stored in the super-block. | ||
57 | * | ||
58 | * This is needed to support boot-loaders which only need R/O mounting. With | ||
59 | * this flag it is possible to do UBIFS format changes without a need to update | ||
60 | * boot-loaders. | ||
61 | */ | ||
62 | #define UBIFS_RO_COMPAT_VERSION 0 | ||
63 | |||
42 | /* Minimum logical eraseblock size in bytes */ | 64 | /* Minimum logical eraseblock size in bytes */ |
43 | #define UBIFS_MIN_LEB_SZ (15*1024) | 65 | #define UBIFS_MIN_LEB_SZ (15*1024) |
44 | 66 | ||
@@ -53,7 +75,7 @@ | |||
53 | 75 | ||
54 | /* | 76 | /* |
55 | * If compressed data length is less than %UBIFS_MIN_COMPRESS_DIFF bytes | 77 | * If compressed data length is less than %UBIFS_MIN_COMPRESS_DIFF bytes |
56 | * shorter than uncompressed data length, UBIFS preferes to leave this data | 78 | * shorter than uncompressed data length, UBIFS prefers to leave this data |
57 | * node uncompress, because it'll be read faster. | 79 | * node uncompress, because it'll be read faster. |
58 | */ | 80 | */ |
59 | #define UBIFS_MIN_COMPRESS_DIFF 64 | 81 | #define UBIFS_MIN_COMPRESS_DIFF 64 |
@@ -586,6 +608,7 @@ struct ubifs_pad_node { | |||
586 | * @padding2: reserved for future, zeroes | 608 | * @padding2: reserved for future, zeroes |
587 | * @time_gran: time granularity in nanoseconds | 609 | * @time_gran: time granularity in nanoseconds |
588 | * @uuid: UUID generated when the file system image was created | 610 | * @uuid: UUID generated when the file system image was created |
611 | * @ro_compat_version: UBIFS R/O compatibility version | ||
589 | */ | 612 | */ |
590 | struct ubifs_sb_node { | 613 | struct ubifs_sb_node { |
591 | struct ubifs_ch ch; | 614 | struct ubifs_ch ch; |
@@ -612,7 +635,8 @@ struct ubifs_sb_node { | |||
612 | __le64 rp_size; | 635 | __le64 rp_size; |
613 | __le32 time_gran; | 636 | __le32 time_gran; |
614 | __u8 uuid[16]; | 637 | __u8 uuid[16]; |
615 | __u8 padding2[3972]; | 638 | __le32 ro_compat_version; |
639 | __u8 padding2[3968]; | ||
616 | } __attribute__ ((packed)); | 640 | } __attribute__ ((packed)); |
617 | 641 | ||
618 | /** | 642 | /** |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 039a68bee29a..0a8341e14088 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -934,6 +934,7 @@ struct ubifs_debug_info; | |||
934 | * by @commit_sem | 934 | * by @commit_sem |
935 | * @cnt_lock: protects @highest_inum and @max_sqnum counters | 935 | * @cnt_lock: protects @highest_inum and @max_sqnum counters |
936 | * @fmt_version: UBIFS on-flash format version | 936 | * @fmt_version: UBIFS on-flash format version |
937 | * @ro_compat_version: R/O compatibility version | ||
937 | * @uuid: UUID from super block | 938 | * @uuid: UUID from super block |
938 | * | 939 | * |
939 | * @lhead_lnum: log head logical eraseblock number | 940 | * @lhead_lnum: log head logical eraseblock number |
@@ -966,6 +967,7 @@ struct ubifs_debug_info; | |||
966 | * recovery) | 967 | * recovery) |
967 | * @bulk_read: enable bulk-reads | 968 | * @bulk_read: enable bulk-reads |
968 | * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc) | 969 | * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc) |
970 | * @rw_incompat: the media is not R/W compatible | ||
969 | * | 971 | * |
970 | * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and | 972 | * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and |
971 | * @calc_idx_sz | 973 | * @calc_idx_sz |
@@ -1015,6 +1017,8 @@ struct ubifs_debug_info; | |||
1015 | * @min_io_shift: number of bits in @min_io_size minus one | 1017 | * @min_io_shift: number of bits in @min_io_size minus one |
1016 | * @leb_size: logical eraseblock size in bytes | 1018 | * @leb_size: logical eraseblock size in bytes |
1017 | * @half_leb_size: half LEB size | 1019 | * @half_leb_size: half LEB size |
1020 | * @idx_leb_size: how many bytes of an LEB are effectively available when it is | ||
1021 | * used to store indexing nodes (@leb_size - @max_idx_node_sz) | ||
1018 | * @leb_cnt: count of logical eraseblocks | 1022 | * @leb_cnt: count of logical eraseblocks |
1019 | * @max_leb_cnt: maximum count of logical eraseblocks | 1023 | * @max_leb_cnt: maximum count of logical eraseblocks |
1020 | * @old_leb_cnt: count of logical eraseblocks before re-size | 1024 | * @old_leb_cnt: count of logical eraseblocks before re-size |
@@ -1132,8 +1136,8 @@ struct ubifs_debug_info; | |||
1132 | * previous commit start | 1136 | * previous commit start |
1133 | * @uncat_list: list of un-categorized LEBs | 1137 | * @uncat_list: list of un-categorized LEBs |
1134 | * @empty_list: list of empty LEBs | 1138 | * @empty_list: list of empty LEBs |
1135 | * @freeable_list: list of freeable non-index LEBs (free + dirty == leb_size) | 1139 | * @freeable_list: list of freeable non-index LEBs (free + dirty == @leb_size) |
1136 | * @frdi_idx_list: list of freeable index LEBs (free + dirty == leb_size) | 1140 | * @frdi_idx_list: list of freeable index LEBs (free + dirty == @leb_size) |
1137 | * @freeable_cnt: number of freeable LEBs in @freeable_list | 1141 | * @freeable_cnt: number of freeable LEBs in @freeable_list |
1138 | * | 1142 | * |
1139 | * @ltab_lnum: LEB number of LPT's own lprops table | 1143 | * @ltab_lnum: LEB number of LPT's own lprops table |
@@ -1177,6 +1181,7 @@ struct ubifs_info { | |||
1177 | unsigned long long cmt_no; | 1181 | unsigned long long cmt_no; |
1178 | spinlock_t cnt_lock; | 1182 | spinlock_t cnt_lock; |
1179 | int fmt_version; | 1183 | int fmt_version; |
1184 | int ro_compat_version; | ||
1180 | unsigned char uuid[16]; | 1185 | unsigned char uuid[16]; |
1181 | 1186 | ||
1182 | int lhead_lnum; | 1187 | int lhead_lnum; |
@@ -1205,6 +1210,7 @@ struct ubifs_info { | |||
1205 | unsigned int no_chk_data_crc:1; | 1210 | unsigned int no_chk_data_crc:1; |
1206 | unsigned int bulk_read:1; | 1211 | unsigned int bulk_read:1; |
1207 | unsigned int default_compr:2; | 1212 | unsigned int default_compr:2; |
1213 | unsigned int rw_incompat:1; | ||
1208 | 1214 | ||
1209 | struct mutex tnc_mutex; | 1215 | struct mutex tnc_mutex; |
1210 | struct ubifs_zbranch zroot; | 1216 | struct ubifs_zbranch zroot; |
@@ -1253,6 +1259,7 @@ struct ubifs_info { | |||
1253 | int min_io_shift; | 1259 | int min_io_shift; |
1254 | int leb_size; | 1260 | int leb_size; |
1255 | int half_leb_size; | 1261 | int half_leb_size; |
1262 | int idx_leb_size; | ||
1256 | int leb_cnt; | 1263 | int leb_cnt; |
1257 | int max_leb_cnt; | 1264 | int max_leb_cnt; |
1258 | int old_leb_cnt; | 1265 | int old_leb_cnt; |
@@ -1500,7 +1507,7 @@ long long ubifs_reported_space(const struct ubifs_info *c, long long free); | |||
1500 | long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs); | 1507 | long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs); |
1501 | 1508 | ||
1502 | /* find.c */ | 1509 | /* find.c */ |
1503 | int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free, | 1510 | int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *offs, |
1504 | int squeeze); | 1511 | int squeeze); |
1505 | int ubifs_find_free_leb_for_idx(struct ubifs_info *c); | 1512 | int ubifs_find_free_leb_for_idx(struct ubifs_info *c); |
1506 | int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp, | 1513 | int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp, |