aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/gc.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-05-20 19:02:06 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-05-20 19:02:06 -0400
commit6171586a7ae5198988774e8480631e8d15f65dfe (patch)
treeeef74bde60005c4e39c0c213030b27cb07a5c236 /fs/jffs2/gc.c
parentfb9fbbcc9389edabb172ac1b6419c01e32046787 (diff)
[JFFS2] Correct handling of JFFS2_FEATURE_RWCOMPAT_COPY nodes.
We should preserve these when we come to garbage collect them, not let them get erased. Use jffs2_garbage_collect_pristine() for this, and make sure the summary code copes -- just refrain from writing a summary for any block which contains a node we don't understand. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2/gc.c')
-rw-r--r--fs/jffs2/gc.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
index 23587f8a221f..b0a5c407b476 100644
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.c
@@ -256,10 +256,14 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
256 256
257 if (!raw->next_in_ino) { 257 if (!raw->next_in_ino) {
258 /* Inode-less node. Clean marker, snapshot or something like that */ 258 /* Inode-less node. Clean marker, snapshot or something like that */
259 /* FIXME: If it's something that needs to be copied, including something
260 we don't grok that has JFFS2_NODETYPE_RWCOMPAT_COPY, we should do so */
261 spin_unlock(&c->erase_completion_lock); 259 spin_unlock(&c->erase_completion_lock);
262 jffs2_mark_node_obsolete(c, raw); 260 if (ref_flags(raw) == REF_PRISTINE) {
261 /* It's an unknown node with JFFS2_FEATURE_RWCOMPAT_COPY */
262 jffs2_garbage_collect_pristine(c, NULL, raw);
263 } else {
264 /* Just mark it obsolete */
265 jffs2_mark_node_obsolete(c, raw);
266 }
263 up(&c->alloc_sem); 267 up(&c->alloc_sem);
264 goto eraseit_lock; 268 goto eraseit_lock;
265 } 269 }
@@ -533,15 +537,16 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
533 537
534 D1(printk(KERN_DEBUG "Going to GC REF_PRISTINE node at 0x%08x\n", ref_offset(raw))); 538 D1(printk(KERN_DEBUG "Going to GC REF_PRISTINE node at 0x%08x\n", ref_offset(raw)));
535 539
536 rawlen = ref_totlen(c, c->gcblock, raw); 540 alloclen = rawlen = ref_totlen(c, c->gcblock, raw);
537 541
538 /* Ask for a small amount of space (or the totlen if smaller) because we 542 /* Ask for a small amount of space (or the totlen if smaller) because we
539 don't want to force wastage of the end of a block if splitting would 543 don't want to force wastage of the end of a block if splitting would
540 work. */ 544 work. */
541 ret = jffs2_reserve_space_gc(c, min_t(uint32_t, sizeof(struct jffs2_raw_inode) + 545 if (ic && alloclen > sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN)
542 JFFS2_MIN_DATA_LEN, rawlen), &phys_ofs, &alloclen, rawlen); 546 alloclen = sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN;
543 /* this is not the exact summary size of it, 547
544 it is only an upper estimation */ 548 ret = jffs2_reserve_space_gc(c, alloclen, &phys_ofs, &alloclen, rawlen);
549 /* 'rawlen' is not the exact summary size; it is only an upper estimation */
545 550
546 if (ret) 551 if (ret)
547 return ret; 552 return ret;
@@ -605,9 +610,12 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
605 } 610 }
606 break; 611 break;
607 default: 612 default:
608 printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n", 613 /* If it's inode-less, we don't _know_ what it is. Just copy it intact */
609 ref_offset(raw), je16_to_cpu(node->u.nodetype)); 614 if (ic) {
610 goto bail; 615 printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n",
616 ref_offset(raw), je16_to_cpu(node->u.nodetype));
617 goto bail;
618 }
611 } 619 }
612 620
613 nraw = jffs2_alloc_raw_node_ref(); 621 nraw = jffs2_alloc_raw_node_ref();
@@ -674,15 +682,16 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
674 nraw->flash_offset |= REF_PRISTINE; 682 nraw->flash_offset |= REF_PRISTINE;
675 jffs2_add_physical_node_ref(c, nraw); 683 jffs2_add_physical_node_ref(c, nraw);
676 684
677 /* Link into per-inode list. This is safe because of the ic 685 if (ic) {
678 state being INO_STATE_GC. Note that if we're doing this 686 /* Link into per-inode list. This is safe because of the ic
679 for an inode which is in-core, the 'nraw' pointer is then 687 state being INO_STATE_GC. Note that if we're doing this
680 going to be fetched from ic->nodes by our caller. */ 688 for an inode which is in-core, the 'nraw' pointer is then
681 spin_lock(&c->erase_completion_lock); 689 going to be fetched from ic->nodes by our caller. */
682 nraw->next_in_ino = ic->nodes; 690 spin_lock(&c->erase_completion_lock);
683 ic->nodes = nraw; 691 nraw->next_in_ino = ic->nodes;
684 spin_unlock(&c->erase_completion_lock); 692 ic->nodes = nraw;
685 693 spin_unlock(&c->erase_completion_lock);
694 }
686 jffs2_mark_node_obsolete(c, raw); 695 jffs2_mark_node_obsolete(c, raw);
687 D1(printk(KERN_DEBUG "WHEEE! GC REF_PRISTINE node at 0x%08x succeeded\n", ref_offset(raw))); 696 D1(printk(KERN_DEBUG "WHEEE! GC REF_PRISTINE node at 0x%08x succeeded\n", ref_offset(raw)));
688 697