diff options
Diffstat (limited to 'fs/jffs2/gc.c')
-rw-r--r-- | fs/jffs2/gc.c | 112 |
1 files changed, 56 insertions, 56 deletions
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c index ee54cdc59e06..f9ffece453a3 100644 --- a/fs/jffs2/gc.c +++ b/fs/jffs2/gc.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: gc.c,v 1.154 2005/09/07 08:34:54 havasi Exp $ | 10 | * $Id: gc.c,v 1.155 2005/11/07 11:14:39 gleixner Exp $ |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
@@ -21,14 +21,14 @@ | |||
21 | #include "nodelist.h" | 21 | #include "nodelist.h" |
22 | #include "compr.h" | 22 | #include "compr.h" |
23 | 23 | ||
24 | static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, | 24 | static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, |
25 | struct jffs2_inode_cache *ic, | 25 | struct jffs2_inode_cache *ic, |
26 | struct jffs2_raw_node_ref *raw); | 26 | struct jffs2_raw_node_ref *raw); |
27 | static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 27 | static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, |
28 | struct jffs2_inode_info *f, struct jffs2_full_dnode *fd); | 28 | struct jffs2_inode_info *f, struct jffs2_full_dnode *fd); |
29 | static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 29 | static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, |
30 | struct jffs2_inode_info *f, struct jffs2_full_dirent *fd); | 30 | struct jffs2_inode_info *f, struct jffs2_full_dirent *fd); |
31 | static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 31 | static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, |
32 | struct jffs2_inode_info *f, struct jffs2_full_dirent *fd); | 32 | struct jffs2_inode_info *f, struct jffs2_full_dirent *fd); |
33 | static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 33 | static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, |
34 | struct jffs2_inode_info *f, struct jffs2_full_dnode *fn, | 34 | struct jffs2_inode_info *f, struct jffs2_full_dnode *fn, |
@@ -55,7 +55,7 @@ again: | |||
55 | D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n")); | 55 | D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n")); |
56 | nextlist = &c->bad_used_list; | 56 | nextlist = &c->bad_used_list; |
57 | } else if (n < 50 && !list_empty(&c->erasable_list)) { | 57 | } else if (n < 50 && !list_empty(&c->erasable_list)) { |
58 | /* Note that most of them will have gone directly to be erased. | 58 | /* Note that most of them will have gone directly to be erased. |
59 | So don't favour the erasable_list _too_ much. */ | 59 | So don't favour the erasable_list _too_ much. */ |
60 | D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next\n")); | 60 | D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next\n")); |
61 | nextlist = &c->erasable_list; | 61 | nextlist = &c->erasable_list; |
@@ -101,7 +101,7 @@ again: | |||
101 | printk(KERN_WARNING "Eep. ret->gc_node for block at 0x%08x is NULL\n", ret->offset); | 101 | printk(KERN_WARNING "Eep. ret->gc_node for block at 0x%08x is NULL\n", ret->offset); |
102 | BUG(); | 102 | BUG(); |
103 | } | 103 | } |
104 | 104 | ||
105 | /* Have we accidentally picked a clean block with wasted space ? */ | 105 | /* Have we accidentally picked a clean block with wasted space ? */ |
106 | if (ret->wasted_size) { | 106 | if (ret->wasted_size) { |
107 | D1(printk(KERN_DEBUG "Converting wasted_size %08x to dirty_size\n", ret->wasted_size)); | 107 | D1(printk(KERN_DEBUG "Converting wasted_size %08x to dirty_size\n", ret->wasted_size)); |
@@ -136,7 +136,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) | |||
136 | 136 | ||
137 | /* We can't start doing GC yet. We haven't finished checking | 137 | /* We can't start doing GC yet. We haven't finished checking |
138 | the node CRCs etc. Do it now. */ | 138 | the node CRCs etc. Do it now. */ |
139 | 139 | ||
140 | /* checked_ino is protected by the alloc_sem */ | 140 | /* checked_ino is protected by the alloc_sem */ |
141 | if (c->checked_ino > c->highest_ino) { | 141 | if (c->checked_ino > c->highest_ino) { |
142 | printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n", | 142 | printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n", |
@@ -178,7 +178,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) | |||
178 | 178 | ||
179 | case INO_STATE_READING: | 179 | case INO_STATE_READING: |
180 | /* We need to wait for it to finish, lest we move on | 180 | /* We need to wait for it to finish, lest we move on |
181 | and trigger the BUG() above while we haven't yet | 181 | and trigger the BUG() above while we haven't yet |
182 | finished checking all its nodes */ | 182 | finished checking all its nodes */ |
183 | D1(printk(KERN_DEBUG "Waiting for ino #%u to finish reading\n", ic->ino)); | 183 | D1(printk(KERN_DEBUG "Waiting for ino #%u to finish reading\n", ic->ino)); |
184 | up(&c->alloc_sem); | 184 | up(&c->alloc_sem); |
@@ -228,13 +228,13 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) | |||
228 | } | 228 | } |
229 | 229 | ||
230 | raw = jeb->gc_node; | 230 | raw = jeb->gc_node; |
231 | 231 | ||
232 | while(ref_obsolete(raw)) { | 232 | while(ref_obsolete(raw)) { |
233 | D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", ref_offset(raw))); | 233 | D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", ref_offset(raw))); |
234 | raw = raw->next_phys; | 234 | raw = raw->next_phys; |
235 | if (unlikely(!raw)) { | 235 | if (unlikely(!raw)) { |
236 | printk(KERN_WARNING "eep. End of raw list while still supposedly nodes to GC\n"); | 236 | printk(KERN_WARNING "eep. End of raw list while still supposedly nodes to GC\n"); |
237 | printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n", | 237 | printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n", |
238 | jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size); | 238 | jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size); |
239 | jeb->gc_node = raw; | 239 | jeb->gc_node = raw; |
240 | spin_unlock(&c->erase_completion_lock); | 240 | spin_unlock(&c->erase_completion_lock); |
@@ -259,7 +259,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) | |||
259 | ic = jffs2_raw_ref_to_ic(raw); | 259 | ic = jffs2_raw_ref_to_ic(raw); |
260 | 260 | ||
261 | /* We need to hold the inocache. Either the erase_completion_lock or | 261 | /* We need to hold the inocache. Either the erase_completion_lock or |
262 | the inocache_lock are sufficient; we trade down since the inocache_lock | 262 | the inocache_lock are sufficient; we trade down since the inocache_lock |
263 | causes less contention. */ | 263 | causes less contention. */ |
264 | spin_lock(&c->inocache_lock); | 264 | spin_lock(&c->inocache_lock); |
265 | 265 | ||
@@ -278,14 +278,14 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) | |||
278 | 278 | ||
279 | switch(ic->state) { | 279 | switch(ic->state) { |
280 | case INO_STATE_CHECKEDABSENT: | 280 | case INO_STATE_CHECKEDABSENT: |
281 | /* It's been checked, but it's not currently in-core. | 281 | /* It's been checked, but it's not currently in-core. |
282 | We can just copy any pristine nodes, but have | 282 | We can just copy any pristine nodes, but have |
283 | to prevent anyone else from doing read_inode() while | 283 | to prevent anyone else from doing read_inode() while |
284 | we're at it, so we set the state accordingly */ | 284 | we're at it, so we set the state accordingly */ |
285 | if (ref_flags(raw) == REF_PRISTINE) | 285 | if (ref_flags(raw) == REF_PRISTINE) |
286 | ic->state = INO_STATE_GC; | 286 | ic->state = INO_STATE_GC; |
287 | else { | 287 | else { |
288 | D1(printk(KERN_DEBUG "Ino #%u is absent but node not REF_PRISTINE. Reading.\n", | 288 | D1(printk(KERN_DEBUG "Ino #%u is absent but node not REF_PRISTINE. Reading.\n", |
289 | ic->ino)); | 289 | ic->ino)); |
290 | } | 290 | } |
291 | break; | 291 | break; |
@@ -298,8 +298,8 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) | |||
298 | case INO_STATE_CHECKING: | 298 | case INO_STATE_CHECKING: |
299 | case INO_STATE_GC: | 299 | case INO_STATE_GC: |
300 | /* Should never happen. We should have finished checking | 300 | /* Should never happen. We should have finished checking |
301 | by the time we actually start doing any GC, and since | 301 | by the time we actually start doing any GC, and since |
302 | we're holding the alloc_sem, no other garbage collection | 302 | we're holding the alloc_sem, no other garbage collection |
303 | can happen. | 303 | can happen. |
304 | */ | 304 | */ |
305 | printk(KERN_CRIT "Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n", | 305 | printk(KERN_CRIT "Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n", |
@@ -319,21 +319,21 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) | |||
319 | D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() waiting for ino #%u in state %d\n", | 319 | D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() waiting for ino #%u in state %d\n", |
320 | ic->ino, ic->state)); | 320 | ic->ino, ic->state)); |
321 | sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); | 321 | sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); |
322 | /* And because we dropped the alloc_sem we must start again from the | 322 | /* And because we dropped the alloc_sem we must start again from the |
323 | beginning. Ponder chance of livelock here -- we're returning success | 323 | beginning. Ponder chance of livelock here -- we're returning success |
324 | without actually making any progress. | 324 | without actually making any progress. |
325 | 325 | ||
326 | Q: What are the chances that the inode is back in INO_STATE_READING | 326 | Q: What are the chances that the inode is back in INO_STATE_READING |
327 | again by the time we next enter this function? And that this happens | 327 | again by the time we next enter this function? And that this happens |
328 | enough times to cause a real delay? | 328 | enough times to cause a real delay? |
329 | 329 | ||
330 | A: Small enough that I don't care :) | 330 | A: Small enough that I don't care :) |
331 | */ | 331 | */ |
332 | return 0; | 332 | return 0; |
333 | } | 333 | } |
334 | 334 | ||
335 | /* OK. Now if the inode is in state INO_STATE_GC, we are going to copy the | 335 | /* OK. Now if the inode is in state INO_STATE_GC, we are going to copy the |
336 | node intact, and we don't have to muck about with the fragtree etc. | 336 | node intact, and we don't have to muck about with the fragtree etc. |
337 | because we know it's not in-core. If it _was_ in-core, we go through | 337 | because we know it's not in-core. If it _was_ in-core, we go through |
338 | all the iget() crap anyway */ | 338 | all the iget() crap anyway */ |
339 | 339 | ||
@@ -453,7 +453,7 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era | |||
453 | if (!ret) { | 453 | if (!ret) { |
454 | /* Urgh. Return it sensibly. */ | 454 | /* Urgh. Return it sensibly. */ |
455 | frag->node->raw = f->inocache->nodes; | 455 | frag->node->raw = f->inocache->nodes; |
456 | } | 456 | } |
457 | if (ret != -EBADFD) | 457 | if (ret != -EBADFD) |
458 | goto upnout; | 458 | goto upnout; |
459 | } | 459 | } |
@@ -467,7 +467,7 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era | |||
467 | } | 467 | } |
468 | goto upnout; | 468 | goto upnout; |
469 | } | 469 | } |
470 | 470 | ||
471 | /* Wasn't a dnode. Try dirent */ | 471 | /* Wasn't a dnode. Try dirent */ |
472 | for (fd = f->dents; fd; fd=fd->next) { | 472 | for (fd = f->dents; fd; fd=fd->next) { |
473 | if (fd->raw == raw) | 473 | if (fd->raw == raw) |
@@ -494,7 +494,7 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era | |||
494 | return ret; | 494 | return ret; |
495 | } | 495 | } |
496 | 496 | ||
497 | static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, | 497 | static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, |
498 | struct jffs2_inode_cache *ic, | 498 | struct jffs2_inode_cache *ic, |
499 | struct jffs2_raw_node_ref *raw) | 499 | struct jffs2_raw_node_ref *raw) |
500 | { | 500 | { |
@@ -580,7 +580,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, | |||
580 | } | 580 | } |
581 | break; | 581 | break; |
582 | default: | 582 | default: |
583 | printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n", | 583 | printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n", |
584 | ref_offset(raw), je16_to_cpu(node->u.nodetype)); | 584 | ref_offset(raw), je16_to_cpu(node->u.nodetype)); |
585 | goto bail; | 585 | goto bail; |
586 | } | 586 | } |
@@ -621,7 +621,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, | |||
621 | retried = 1; | 621 | retried = 1; |
622 | 622 | ||
623 | D1(printk(KERN_DEBUG "Retrying failed write of REF_PRISTINE node.\n")); | 623 | D1(printk(KERN_DEBUG "Retrying failed write of REF_PRISTINE node.\n")); |
624 | 624 | ||
625 | jffs2_dbg_acct_sanity_check(c,jeb); | 625 | jffs2_dbg_acct_sanity_check(c,jeb); |
626 | jffs2_dbg_acct_paranoia_check(c, jeb); | 626 | jffs2_dbg_acct_paranoia_check(c, jeb); |
627 | 627 | ||
@@ -669,7 +669,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, | |||
669 | goto out_node; | 669 | goto out_node; |
670 | } | 670 | } |
671 | 671 | ||
672 | static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 672 | static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, |
673 | struct jffs2_inode_info *f, struct jffs2_full_dnode *fn) | 673 | struct jffs2_inode_info *f, struct jffs2_full_dnode *fn) |
674 | { | 674 | { |
675 | struct jffs2_full_dnode *new_fn; | 675 | struct jffs2_full_dnode *new_fn; |
@@ -684,7 +684,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_ | |||
684 | S_ISCHR(JFFS2_F_I_MODE(f)) ) { | 684 | S_ISCHR(JFFS2_F_I_MODE(f)) ) { |
685 | /* For these, we don't actually need to read the old node */ | 685 | /* For these, we don't actually need to read the old node */ |
686 | /* FIXME: for minor or major > 255. */ | 686 | /* FIXME: for minor or major > 255. */ |
687 | dev = cpu_to_je16(((JFFS2_F_I_RDEV_MAJ(f) << 8) | | 687 | dev = cpu_to_je16(((JFFS2_F_I_RDEV_MAJ(f) << 8) | |
688 | JFFS2_F_I_RDEV_MIN(f))); | 688 | JFFS2_F_I_RDEV_MIN(f))); |
689 | mdata = (char *)&dev; | 689 | mdata = (char *)&dev; |
690 | mdatalen = sizeof(dev); | 690 | mdatalen = sizeof(dev); |
@@ -705,7 +705,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_ | |||
705 | D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bites of symlink target\n", mdatalen)); | 705 | D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bites of symlink target\n", mdatalen)); |
706 | 706 | ||
707 | } | 707 | } |
708 | 708 | ||
709 | ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen, | 709 | ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen, |
710 | JFFS2_SUMMARY_INODE_SIZE); | 710 | JFFS2_SUMMARY_INODE_SIZE); |
711 | if (ret) { | 711 | if (ret) { |
@@ -713,7 +713,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_ | |||
713 | sizeof(ri)+ mdatalen, ret); | 713 | sizeof(ri)+ mdatalen, ret); |
714 | goto out; | 714 | goto out; |
715 | } | 715 | } |
716 | 716 | ||
717 | last_frag = frag_last(&f->fragtree); | 717 | last_frag = frag_last(&f->fragtree); |
718 | if (last_frag) | 718 | if (last_frag) |
719 | /* Fetch the inode length from the fragtree rather then | 719 | /* Fetch the inode length from the fragtree rather then |
@@ -721,7 +721,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_ | |||
721 | ilen = last_frag->ofs + last_frag->size; | 721 | ilen = last_frag->ofs + last_frag->size; |
722 | else | 722 | else |
723 | ilen = JFFS2_F_I_SIZE(f); | 723 | ilen = JFFS2_F_I_SIZE(f); |
724 | 724 | ||
725 | memset(&ri, 0, sizeof(ri)); | 725 | memset(&ri, 0, sizeof(ri)); |
726 | ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); | 726 | ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); |
727 | ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); | 727 | ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); |
@@ -760,7 +760,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_ | |||
760 | return ret; | 760 | return ret; |
761 | } | 761 | } |
762 | 762 | ||
763 | static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 763 | static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, |
764 | struct jffs2_inode_info *f, struct jffs2_full_dirent *fd) | 764 | struct jffs2_inode_info *f, struct jffs2_full_dirent *fd) |
765 | { | 765 | { |
766 | struct jffs2_full_dirent *new_fd; | 766 | struct jffs2_full_dirent *new_fd; |
@@ -781,12 +781,12 @@ static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_er | |||
781 | so refrain from splatting them. */ | 781 | so refrain from splatting them. */ |
782 | if (JFFS2_F_I_MTIME(f) == JFFS2_F_I_CTIME(f)) | 782 | if (JFFS2_F_I_MTIME(f) == JFFS2_F_I_CTIME(f)) |
783 | rd.mctime = cpu_to_je32(JFFS2_F_I_MTIME(f)); | 783 | rd.mctime = cpu_to_je32(JFFS2_F_I_MTIME(f)); |
784 | else | 784 | else |
785 | rd.mctime = cpu_to_je32(0); | 785 | rd.mctime = cpu_to_je32(0); |
786 | rd.type = fd->type; | 786 | rd.type = fd->type; |
787 | rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8)); | 787 | rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8)); |
788 | rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize)); | 788 | rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize)); |
789 | 789 | ||
790 | ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen, | 790 | ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen, |
791 | JFFS2_SUMMARY_DIRENT_SIZE(rd.nsize)); | 791 | JFFS2_SUMMARY_DIRENT_SIZE(rd.nsize)); |
792 | if (ret) { | 792 | if (ret) { |
@@ -804,7 +804,7 @@ static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_er | |||
804 | return 0; | 804 | return 0; |
805 | } | 805 | } |
806 | 806 | ||
807 | static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 807 | static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, |
808 | struct jffs2_inode_info *f, struct jffs2_full_dirent *fd) | 808 | struct jffs2_inode_info *f, struct jffs2_full_dirent *fd) |
809 | { | 809 | { |
810 | struct jffs2_full_dirent **fdp = &f->dents; | 810 | struct jffs2_full_dirent **fdp = &f->dents; |
@@ -843,7 +843,7 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct | |||
843 | if (ref_totlen(c, NULL, raw) != rawlen) | 843 | if (ref_totlen(c, NULL, raw) != rawlen) |
844 | continue; | 844 | continue; |
845 | 845 | ||
846 | /* Doesn't matter if there's one in the same erase block. We're going to | 846 | /* Doesn't matter if there's one in the same erase block. We're going to |
847 | delete it too at the same time. */ | 847 | delete it too at the same time. */ |
848 | if (SECTOR_ADDR(raw->flash_offset) == SECTOR_ADDR(fd->raw->flash_offset)) | 848 | if (SECTOR_ADDR(raw->flash_offset) == SECTOR_ADDR(fd->raw->flash_offset)) |
849 | continue; | 849 | continue; |
@@ -895,7 +895,7 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct | |||
895 | kfree(rd); | 895 | kfree(rd); |
896 | } | 896 | } |
897 | 897 | ||
898 | /* FIXME: If we're deleting a dirent which contains the current mtime and ctime, | 898 | /* FIXME: If we're deleting a dirent which contains the current mtime and ctime, |
899 | we should update the metadata node with those times accordingly */ | 899 | we should update the metadata node with those times accordingly */ |
900 | 900 | ||
901 | /* No need for it any more. Just mark it obsolete and remove it from the list */ | 901 | /* No need for it any more. Just mark it obsolete and remove it from the list */ |
@@ -927,13 +927,13 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras | |||
927 | 927 | ||
928 | D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n", | 928 | D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n", |
929 | f->inocache->ino, start, end)); | 929 | f->inocache->ino, start, end)); |
930 | 930 | ||
931 | memset(&ri, 0, sizeof(ri)); | 931 | memset(&ri, 0, sizeof(ri)); |
932 | 932 | ||
933 | if(fn->frags > 1) { | 933 | if(fn->frags > 1) { |
934 | size_t readlen; | 934 | size_t readlen; |
935 | uint32_t crc; | 935 | uint32_t crc; |
936 | /* It's partially obsoleted by a later write. So we have to | 936 | /* It's partially obsoleted by a later write. So we have to |
937 | write it out again with the _same_ version as before */ | 937 | write it out again with the _same_ version as before */ |
938 | ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(ri), &readlen, (char *)&ri); | 938 | ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(ri), &readlen, (char *)&ri); |
939 | if (readlen != sizeof(ri) || ret) { | 939 | if (readlen != sizeof(ri) || ret) { |
@@ -955,16 +955,16 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras | |||
955 | crc = crc32(0, &ri, sizeof(ri)-8); | 955 | crc = crc32(0, &ri, sizeof(ri)-8); |
956 | if (crc != je32_to_cpu(ri.node_crc)) { | 956 | if (crc != je32_to_cpu(ri.node_crc)) { |
957 | printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n", | 957 | printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n", |
958 | ref_offset(fn->raw), | 958 | ref_offset(fn->raw), |
959 | je32_to_cpu(ri.node_crc), crc); | 959 | je32_to_cpu(ri.node_crc), crc); |
960 | /* FIXME: We could possibly deal with this by writing new holes for each frag */ | 960 | /* FIXME: We could possibly deal with this by writing new holes for each frag */ |
961 | printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", | 961 | printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", |
962 | start, end, f->inocache->ino); | 962 | start, end, f->inocache->ino); |
963 | goto fill; | 963 | goto fill; |
964 | } | 964 | } |
965 | if (ri.compr != JFFS2_COMPR_ZERO) { | 965 | if (ri.compr != JFFS2_COMPR_ZERO) { |
966 | printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", ref_offset(fn->raw)); | 966 | printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", ref_offset(fn->raw)); |
967 | printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", | 967 | printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", |
968 | start, end, f->inocache->ino); | 968 | start, end, f->inocache->ino); |
969 | goto fill; | 969 | goto fill; |
970 | } | 970 | } |
@@ -982,7 +982,7 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras | |||
982 | ri.csize = cpu_to_je32(0); | 982 | ri.csize = cpu_to_je32(0); |
983 | ri.compr = JFFS2_COMPR_ZERO; | 983 | ri.compr = JFFS2_COMPR_ZERO; |
984 | } | 984 | } |
985 | 985 | ||
986 | frag = frag_last(&f->fragtree); | 986 | frag = frag_last(&f->fragtree); |
987 | if (frag) | 987 | if (frag) |
988 | /* Fetch the inode length from the fragtree rather then | 988 | /* Fetch the inode length from the fragtree rather then |
@@ -1024,10 +1024,10 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras | |||
1024 | return 0; | 1024 | return 0; |
1025 | } | 1025 | } |
1026 | 1026 | ||
1027 | /* | 1027 | /* |
1028 | * We should only get here in the case where the node we are | 1028 | * We should only get here in the case where the node we are |
1029 | * replacing had more than one frag, so we kept the same version | 1029 | * replacing had more than one frag, so we kept the same version |
1030 | * number as before. (Except in case of error -- see 'goto fill;' | 1030 | * number as before. (Except in case of error -- see 'goto fill;' |
1031 | * above.) | 1031 | * above.) |
1032 | */ | 1032 | */ |
1033 | D1(if(unlikely(fn->frags <= 1)) { | 1033 | D1(if(unlikely(fn->frags <= 1)) { |
@@ -1039,7 +1039,7 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras | |||
1039 | /* This is a partially-overlapped hole node. Mark it REF_NORMAL not REF_PRISTINE */ | 1039 | /* This is a partially-overlapped hole node. Mark it REF_NORMAL not REF_PRISTINE */ |
1040 | mark_ref_normal(new_fn->raw); | 1040 | mark_ref_normal(new_fn->raw); |
1041 | 1041 | ||
1042 | for (frag = jffs2_lookup_node_frag(&f->fragtree, fn->ofs); | 1042 | for (frag = jffs2_lookup_node_frag(&f->fragtree, fn->ofs); |
1043 | frag; frag = frag_next(frag)) { | 1043 | frag; frag = frag_next(frag)) { |
1044 | if (frag->ofs > fn->size + fn->ofs) | 1044 | if (frag->ofs > fn->size + fn->ofs) |
1045 | break; | 1045 | break; |
@@ -1057,10 +1057,10 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras | |||
1057 | printk(KERN_WARNING "jffs2_garbage_collect_hole: New node has no frags!\n"); | 1057 | printk(KERN_WARNING "jffs2_garbage_collect_hole: New node has no frags!\n"); |
1058 | BUG(); | 1058 | BUG(); |
1059 | } | 1059 | } |
1060 | 1060 | ||
1061 | jffs2_mark_node_obsolete(c, fn->raw); | 1061 | jffs2_mark_node_obsolete(c, fn->raw); |
1062 | jffs2_free_full_dnode(fn); | 1062 | jffs2_free_full_dnode(fn); |
1063 | 1063 | ||
1064 | return 0; | 1064 | return 0; |
1065 | } | 1065 | } |
1066 | 1066 | ||
@@ -1070,12 +1070,12 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era | |||
1070 | { | 1070 | { |
1071 | struct jffs2_full_dnode *new_fn; | 1071 | struct jffs2_full_dnode *new_fn; |
1072 | struct jffs2_raw_inode ri; | 1072 | struct jffs2_raw_inode ri; |
1073 | uint32_t alloclen, phys_ofs, offset, orig_end, orig_start; | 1073 | uint32_t alloclen, phys_ofs, offset, orig_end, orig_start; |
1074 | int ret = 0; | 1074 | int ret = 0; |
1075 | unsigned char *comprbuf = NULL, *writebuf; | 1075 | unsigned char *comprbuf = NULL, *writebuf; |
1076 | unsigned long pg; | 1076 | unsigned long pg; |
1077 | unsigned char *pg_ptr; | 1077 | unsigned char *pg_ptr; |
1078 | 1078 | ||
1079 | memset(&ri, 0, sizeof(ri)); | 1079 | memset(&ri, 0, sizeof(ri)); |
1080 | 1080 | ||
1081 | D1(printk(KERN_DEBUG "Writing replacement dnode for ino #%u from offset 0x%x to 0x%x\n", | 1081 | D1(printk(KERN_DEBUG "Writing replacement dnode for ino #%u from offset 0x%x to 0x%x\n", |
@@ -1087,8 +1087,8 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era | |||
1087 | if (c->nr_free_blocks + c->nr_erasing_blocks > c->resv_blocks_gcmerge) { | 1087 | if (c->nr_free_blocks + c->nr_erasing_blocks > c->resv_blocks_gcmerge) { |
1088 | /* Attempt to do some merging. But only expand to cover logically | 1088 | /* Attempt to do some merging. But only expand to cover logically |
1089 | adjacent frags if the block containing them is already considered | 1089 | adjacent frags if the block containing them is already considered |
1090 | to be dirty. Otherwise we end up with GC just going round in | 1090 | to be dirty. Otherwise we end up with GC just going round in |
1091 | circles dirtying the nodes it already wrote out, especially | 1091 | circles dirtying the nodes it already wrote out, especially |
1092 | on NAND where we have small eraseblocks and hence a much higher | 1092 | on NAND where we have small eraseblocks and hence a much higher |
1093 | chance of nodes having to be split to cross boundaries. */ | 1093 | chance of nodes having to be split to cross boundaries. */ |
1094 | 1094 | ||
@@ -1122,7 +1122,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era | |||
1122 | break; | 1122 | break; |
1123 | } else { | 1123 | } else { |
1124 | 1124 | ||
1125 | /* OK, it's a frag which extends to the beginning of the page. Does it live | 1125 | /* OK, it's a frag which extends to the beginning of the page. Does it live |
1126 | in a block which is still considered clean? If so, don't obsolete it. | 1126 | in a block which is still considered clean? If so, don't obsolete it. |
1127 | If not, cover it anyway. */ | 1127 | If not, cover it anyway. */ |
1128 | 1128 | ||
@@ -1172,7 +1172,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era | |||
1172 | break; | 1172 | break; |
1173 | } else { | 1173 | } else { |
1174 | 1174 | ||
1175 | /* OK, it's a frag which extends to the beginning of the page. Does it live | 1175 | /* OK, it's a frag which extends to the beginning of the page. Does it live |
1176 | in a block which is still considered clean? If so, don't obsolete it. | 1176 | in a block which is still considered clean? If so, don't obsolete it. |
1177 | If not, cover it anyway. */ | 1177 | If not, cover it anyway. */ |
1178 | 1178 | ||
@@ -1199,14 +1199,14 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era | |||
1199 | break; | 1199 | break; |
1200 | } | 1200 | } |
1201 | } | 1201 | } |
1202 | D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n", | 1202 | D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n", |
1203 | orig_start, orig_end, start, end)); | 1203 | orig_start, orig_end, start, end)); |
1204 | 1204 | ||
1205 | D1(BUG_ON(end > frag_last(&f->fragtree)->ofs + frag_last(&f->fragtree)->size)); | 1205 | D1(BUG_ON(end > frag_last(&f->fragtree)->ofs + frag_last(&f->fragtree)->size)); |
1206 | BUG_ON(end < orig_end); | 1206 | BUG_ON(end < orig_end); |
1207 | BUG_ON(start > orig_start); | 1207 | BUG_ON(start > orig_start); |
1208 | } | 1208 | } |
1209 | 1209 | ||
1210 | /* First, use readpage() to read the appropriate page into the page cache */ | 1210 | /* First, use readpage() to read the appropriate page into the page cache */ |
1211 | /* Q: What happens if we actually try to GC the _same_ page for which commit_write() | 1211 | /* Q: What happens if we actually try to GC the _same_ page for which commit_write() |
1212 | * triggered garbage collection in the first place? | 1212 | * triggered garbage collection in the first place? |
@@ -1263,7 +1263,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era | |||
1263 | ri.usercompr = (comprtype >> 8) & 0xff; | 1263 | ri.usercompr = (comprtype >> 8) & 0xff; |
1264 | ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); | 1264 | ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); |
1265 | ri.data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen)); | 1265 | ri.data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen)); |
1266 | 1266 | ||
1267 | new_fn = jffs2_write_dnode(c, f, &ri, comprbuf, cdatalen, phys_ofs, ALLOC_GC); | 1267 | new_fn = jffs2_write_dnode(c, f, &ri, comprbuf, cdatalen, phys_ofs, ALLOC_GC); |
1268 | 1268 | ||
1269 | jffs2_free_comprbuf(comprbuf, writebuf); | 1269 | jffs2_free_comprbuf(comprbuf, writebuf); |