mtd/fs/jffs2 gc.c,1.115,1.116 nodelist.c,1.81,1.82
nodelist.h,1.105,1.106 nodemgmt.c,1.103,1.104 wbuf.c,1.54,1.55
David Woodhouse
dwmw2 at infradead.org
Thu Oct 16 06:22:53 EDT 2003
Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/tmp/cvs-serv32090
Modified Files:
gc.c nodelist.c nodelist.h nodemgmt.c wbuf.c
Log Message:
Add args to ref_totlen() to allow it to be calculated. Sample implementation
Index: gc.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/gc.c,v
retrieving revision 1.115
retrieving revision 1.116
diff -u -r1.115 -r1.116
--- gc.c 16 Oct 2003 09:17:17 -0000 1.115
+++ gc.c 16 Oct 2003 10:22:49 -0000 1.116
@@ -492,30 +492,32 @@
size_t retlen;
int ret;
uint32_t phys_ofs, alloclen;
- uint32_t crc;
+ uint32_t crc, rawlen;
int retried = 0;
D1(printk(KERN_DEBUG "Going to GC REF_PRISTINE node at 0x%08x\n", ref_offset(raw)));
+ rawlen = ref_totlen(c, c->gcblock, raw);
+
/* Ask for a small amount of space (or the totlen if smaller) because we
don't want to force wastage of the end of a block if splitting would
work. */
- ret = jffs2_reserve_space_gc(c, min_t(uint32_t, sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN, ref_totlen(raw)),
- &phys_ofs, &alloclen);
+ ret = jffs2_reserve_space_gc(c, min_t(uint32_t, sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN,
+ rawlen), &phys_ofs, &alloclen);
if (ret)
return ret;
- if (alloclen < ref_totlen(raw)) {
+ if (alloclen < rawlen) {
/* Doesn't fit untouched. We'll go the old route and split it */
return -EBADFD;
}
- node = kmalloc(ref_totlen(raw), GFP_KERNEL);
+ node = kmalloc(rawlen, GFP_KERNEL);
if (!node)
return -ENOMEM;
- ret = jffs2_flash_read(c, ref_offset(raw), ref_totlen(raw), &retlen, (char *)node);
- if (!ret && retlen != ref_totlen(raw))
+ ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (char *)node);
+ if (!ret && retlen != rawlen)
ret = -EIO;
if (ret)
goto out_node;
@@ -578,14 +580,14 @@
/* OK, all the CRCs are good; this node can just be copied as-is. */
retry:
nraw->flash_offset = phys_ofs;
- nraw->__totlen = ref_totlen(raw);
+ nraw->__totlen = rawlen;
nraw->next_phys = NULL;
- ret = jffs2_flash_write(c, phys_ofs, ref_totlen(raw), &retlen, (char *)node);
+ ret = jffs2_flash_write(c, phys_ofs, rawlen, &retlen, (char *)node);
- if (ret || (retlen != ref_totlen(raw))) {
+ if (ret || (retlen != rawlen)) {
printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n",
- ref_totlen(raw), phys_ofs, ret, retlen);
+ rawlen, phys_ofs, ret, retlen);
if (retlen) {
/* Doesn't belong to any inode */
nraw->next_in_ino = NULL;
@@ -609,7 +611,7 @@
ACCT_SANITY_CHECK(c,jeb);
D1(ACCT_PARANOIA_CHECK(jeb));
- ret = jffs2_reserve_space_gc(c, ref_totlen(raw), &phys_ofs, &dummy);
+ ret = jffs2_reserve_space_gc(c, rawlen, &phys_ofs, &dummy);
if (!ret) {
D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", phys_ofs));
Index: nodelist.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/nodelist.c,v
retrieving revision 1.81
retrieving revision 1.82
diff -u -r1.81 -r1.82
--- nodelist.c 16 Oct 2003 09:17:17 -0000 1.81
+++ nodelist.c 16 Oct 2003 10:22:50 -0000 1.82
@@ -133,7 +133,9 @@
cond_resched();
/* FIXME: point() */
- err = jffs2_flash_read(c, (ref_offset(ref)), min_t(uint32_t, ref_totlen(ref), sizeof(node)), &retlen, (void *)&node);
+ err = jffs2_flash_read(c, (ref_offset(ref)),
+ min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node)),
+ &retlen, (void *)&node);
if (err) {
printk(KERN_WARNING "error %d reading node at 0x%08x in get_inode_nodes()\n", err, ref_offset(ref));
goto free_out;
@@ -141,7 +143,7 @@
/* Check we've managed to read at least the common node header */
- if (retlen < min_t(uint32_t, ref_totlen(ref), sizeof(node.u))) {
+ if (retlen < min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node.u))) {
printk(KERN_WARNING "short read in get_inode_nodes()\n");
err = -EIO;
goto free_out;
@@ -246,7 +248,7 @@
/* If we've never checked the CRCs on this node, check them now. */
if (ref_flags(ref) == REF_UNCHECKED) {
- uint32_t crc;
+ uint32_t crc, len;
struct jffs2_eraseblock *jeb;
crc = crc32(0, &node, sizeof(node.i)-8);
@@ -321,10 +323,12 @@
/* Mark the node as having been checked and fix the accounting accordingly */
spin_lock(&c->erase_completion_lock);
jeb = &c->blocks[ref->flash_offset / c->sector_size];
- jeb->used_size += ref_totlen(ref);
- jeb->unchecked_size -= ref_totlen(ref);
- c->used_size += ref_totlen(ref);
- c->unchecked_size -= ref_totlen(ref);
+ len = ref_totlen(c, jeb, ref);
+
+ jeb->used_size += len;
+ jeb->unchecked_size -= len;
+ c->used_size += len;
+ c->unchecked_size -= len;
/* If node covers at least a whole page, or if it starts at the
beginning of a page and runs to the end of the file, or if
@@ -377,6 +381,7 @@
default:
if (ref_flags(ref) == REF_UNCHECKED) {
struct jffs2_eraseblock *jeb;
+ uint32_t len;
printk(KERN_ERR "Eep. Unknown node type %04x at %08x was marked REF_UNCHECKED\n",
je16_to_cpu(node.u.nodetype), ref_offset(ref));
@@ -384,10 +389,12 @@
/* Mark the node as having been checked and fix the accounting accordingly */
spin_lock(&c->erase_completion_lock);
jeb = &c->blocks[ref->flash_offset / c->sector_size];
- jeb->used_size += ref_totlen(ref);
- jeb->unchecked_size -= ref_totlen(ref);
- c->used_size += ref_totlen(ref);
- c->unchecked_size -= ref_totlen(ref);
+ len = ref_totlen(c, jeb, ref);
+
+ jeb->used_size += len;
+ jeb->unchecked_size -= len;
+ c->used_size += len;
+ c->unchecked_size -= len;
mark_ref_normal(ref);
spin_unlock(&c->erase_completion_lock);
Index: nodelist.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/nodelist.h,v
retrieving revision 1.105
retrieving revision 1.106
diff -u -r1.105 -r1.106
--- nodelist.h 16 Oct 2003 09:17:17 -0000 1.105
+++ nodelist.h 16 Oct 2003 10:22:50 -0000 1.106
@@ -59,7 +59,7 @@
word so you know when you've got there :) */
struct jffs2_raw_node_ref *next_phys;
uint32_t flash_offset;
- uint32_t __totlen; /* This may die; use ref_totlen() below */
+ uint32_t __totlen; /* This may die; use ref_totlen(c, jeb, ) below */
};
/* flash_offset & 3 always has to be zero, because nodes are
@@ -244,9 +244,9 @@
BUG(); \
} \
if (ref_flags(ref2) == REF_UNCHECKED) \
- my_unchecked_size += ref_totlen(ref2); \
+ my_unchecked_size += ref_totlen(c, jeb, ref2); \
else if (!ref_obsolete(ref2)) \
- my_used_size += ref_totlen(ref2); \
+ my_used_size += ref_totlen(c, jeb, ref2); \
if (unlikely((!ref2->next_phys) != (ref2 == jeb->last_node))) { \
printk("ref for node at %p (phys %08x) has next_phys->%p (%08x), last_node->%p (phys %08x)\n", \
ref2, ref_offset(ref2), ref2->next_phys, ref_offset(ref2->next_phys), \
@@ -266,7 +266,6 @@
} \
} while(0)
-#if 0 /* This doesn't actually work yet */
/* Calculate totlen from surrounding nodes or eraseblock */
static inline uint32_t __ref_totlen(struct jffs2_sb_info *c,
struct jffs2_eraseblock *jeb,
@@ -277,37 +276,44 @@
if (ref->next_phys)
ref_end = ref_offset(ref->next_phys);
else {
+ if (!jeb)
+ jeb = &c->blocks[ref->flash_offset / c->sector_size];
+
/* Last node in block. Use free_space */
BUG_ON(ref != jeb->last_node);
ref_end = jeb->offset + c->sector_size - jeb->free_size;
}
return ref_end - ref_offset(ref);
}
-/* ...and for a while we'll have this as a sanity check... */
+
static inline uint32_t ref_totlen(struct jffs2_sb_info *c,
- struct jffs2_eraseblock *jeb,
- struct jffs2_raw_node_ref *ref)
+ struct jffs2_eraseblock *jeb,
+ struct jffs2_raw_node_ref *ref)
{
uint32_t ret;
- if (jeb != &c->blocks[ref->flash_offset / c->sector_size]) {
- printk(KERN_CRIT "ref_totlen called with wrong block -- at 0x%08x instead of 0x08x; ref %08x\n",
+ D1(if (jeb && jeb != &c->blocks[ref->flash_offset / c->sector_size]) {
+ printk(KERN_CRIT "ref_totlen called with wrong block -- at 0x%08x instead of 0x%08x; ref 0x%08x\n",
jeb->offset, c->blocks[ref->flash_offset / c->sector_size].offset, ref_offset(ref));
BUG();
- }
+ })
+
+#if 1
+ ret = ref->__totlen;
+#else
+ /* This doesn't actually work yet */
ret = __ref_totlen(c, jeb, ref);
if (ret != ref->__totlen) {
printk(KERN_CRIT "Totlen for ref at %p (0x%08x-0x%08x) miscalculated as 0x%x instead of %x\n",
ref, ref_offset(ref), ref_offset(ref)+ref->__totlen,
ret, ref->__totlen);
+ if (!jeb)
+ jeb = &c->blocks[ref->flash_offset / c->sector_size];
paranoia_failed_dump(jeb);
BUG();
}
-#else
-static inline uint32_t ref_totlen(struct jffs2_raw_node_ref *ref)
-{
#endif
- return ref->__totlen;
+ return ret;
}
Index: nodemgmt.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/nodemgmt.c,v
retrieving revision 1.103
retrieving revision 1.104
diff -u -r1.103 -r1.104
--- nodemgmt.c 16 Oct 2003 09:17:17 -0000 1.103
+++ nodemgmt.c 16 Oct 2003 10:22:50 -0000 1.104
@@ -324,7 +324,7 @@
uint32_t len;
jeb = &c->blocks[new->flash_offset / c->sector_size];
- len = ref_totlen(new);
+ len = ref_totlen(c, jeb, new);
D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n", ref_offset(new), ref_flags(new), len));
#if 1
@@ -422,31 +422,31 @@
spin_lock(&c->erase_completion_lock);
if (ref_flags(ref) == REF_UNCHECKED) {
- D1(if (unlikely(jeb->unchecked_size < ref_totlen(ref))) {
+ D1(if (unlikely(jeb->unchecked_size < ref_totlen(c, jeb, ref))) {
printk(KERN_NOTICE "raw unchecked node of size 0x%08x freed from erase block %d at 0x%08x, but unchecked_size was already 0x%08x\n",
- ref_totlen(ref), blocknr, ref->flash_offset, jeb->used_size);
+ ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size);
BUG();
})
- D1(printk(KERN_DEBUG "Obsoleting previously unchecked node at 0x%08x of len %x: ", ref_offset(ref), ref_totlen(ref)));
- jeb->unchecked_size -= ref_totlen(ref);
- c->unchecked_size -= ref_totlen(ref);
+ D1(printk(KERN_DEBUG "Obsoleting previously unchecked node at 0x%08x of len %x: ", ref_offset(ref), ref_totlen(c, jeb, ref)));
+ jeb->unchecked_size -= ref_totlen(c, jeb, ref);
+ c->unchecked_size -= ref_totlen(c, jeb, ref);
} else {
- D1(if (unlikely(jeb->used_size < ref_totlen(ref))) {
+ D1(if (unlikely(jeb->used_size < ref_totlen(c, jeb, ref))) {
printk(KERN_NOTICE "raw node of size 0x%08x freed from erase block %d at 0x%08x, but used_size was already 0x%08x\n",
- ref_totlen(ref), blocknr, ref->flash_offset, jeb->used_size);
+ ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size);
BUG();
})
- D1(printk(KERN_DEBUG "Obsoleting node at 0x%08x of len %x: ", ref_offset(ref), ref_totlen(ref)));
- jeb->used_size -= ref_totlen(ref);
- c->used_size -= ref_totlen(ref);
+ D1(printk(KERN_DEBUG "Obsoleting node at 0x%08x of len %x: ", ref_offset(ref), ref_totlen(c, jeb, ref)));
+ jeb->used_size -= ref_totlen(c, jeb, ref);
+ c->used_size -= ref_totlen(c, jeb, ref);
}
// Take care, that wasted size is taken into concern
- if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref_totlen(ref))) && jeb != c->nextblock) {
+ if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref_totlen(c, jeb, ref))) && jeb != c->nextblock) {
D1(printk("Dirtying\n"));
- addedsize = ref_totlen(ref);
- jeb->dirty_size += ref_totlen(ref);
- c->dirty_size += ref_totlen(ref);
+ addedsize = ref_totlen(c, jeb, ref);
+ jeb->dirty_size += ref_totlen(c, jeb, ref);
+ c->dirty_size += ref_totlen(c, jeb, ref);
/* Convert wasted space to dirty, if not a bad block */
if (jeb->wasted_size) {
@@ -467,8 +467,8 @@
} else {
D1(printk("Wasting\n"));
addedsize = 0;
- jeb->wasted_size += ref_totlen(ref);
- c->wasted_size += ref_totlen(ref);
+ jeb->wasted_size += ref_totlen(c, jeb, ref);
+ c->wasted_size += ref_totlen(c, jeb, ref);
}
ref->flash_offset = ref_offset(ref) | REF_OBSOLETE;
@@ -574,12 +574,12 @@
printk(KERN_WARNING "Short read from obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen);
return;
}
- if (PAD(je32_to_cpu(n.totlen)) != PAD(ref_totlen(ref))) {
- printk(KERN_WARNING "Node totlen on flash (0x%08x) != totlen in node ref (0x%08x)\n", je32_to_cpu(n.totlen), ref_totlen(ref));
+ if (PAD(je32_to_cpu(n.totlen)) != PAD(ref_totlen(c, jeb, ref))) {
+ printk(KERN_WARNING "Node totlen on flash (0x%08x) != totlen from node ref (0x%08x)\n", je32_to_cpu(n.totlen), ref_totlen(c, jeb, ref));
return;
}
if (!(je16_to_cpu(n.nodetype) & JFFS2_NODE_ACCURATE)) {
- D1(printk(KERN_DEBUG "Node at 0x%08x was already marked obsolete (nodetype 0x%04x\n", ref_offset(ref), je16_to_cpu(n.nodetype)));
+ D1(printk(KERN_DEBUG "Node at 0x%08x was already marked obsolete (nodetype 0x%04x)\n", ref_offset(ref), je16_to_cpu(n.nodetype)));
return;
}
/* XXX FIXME: This is ugly now */
Index: wbuf.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/wbuf.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -r1.54 -r1.55
--- wbuf.c 16 Oct 2003 09:17:17 -0000 1.54
+++ wbuf.c 16 Oct 2003 10:22:50 -0000 1.55
@@ -179,10 +179,10 @@
first_raw = &jeb->first_node;
while (*first_raw &&
(ref_obsolete(*first_raw) ||
- (ref_offset(*first_raw)+ref_totlen(*first_raw)) < c->wbuf_ofs)) {
+ (ref_offset(*first_raw)+ref_totlen(c, jeb, *first_raw)) < c->wbuf_ofs)) {
D1(printk(KERN_DEBUG "Skipping node at 0x%08x(%d)-0x%08x which is either before 0x%08x or obsolete\n",
ref_offset(*first_raw), ref_flags(*first_raw),
- (ref_offset(*first_raw) + ref_totlen(*first_raw)),
+ (ref_offset(*first_raw) + ref_totlen(c, jeb, *first_raw)),
c->wbuf_ofs));
first_raw = &(*first_raw)->next_phys;
}
@@ -195,13 +195,13 @@
}
start = ref_offset(*first_raw);
- end = ref_offset(*first_raw) + ref_totlen(*first_raw);
+ end = ref_offset(*first_raw) + ref_totlen(c, jeb, *first_raw);
/* Find the last node to be recovered */
raw = first_raw;
while ((*raw)) {
if (!ref_obsolete(*raw))
- end = ref_offset(*raw) + ref_totlen(*raw);
+ end = ref_offset(*raw) + ref_totlen(c, jeb, *raw);
raw = &(*raw)->next_phys;
}
@@ -295,7 +295,7 @@
return;
raw2->flash_offset = ofs | REF_OBSOLETE;
- raw2->__totlen = ref_totlen(*first_raw);
+ raw2->__totlen = ref_totlen(c, jeb, *first_raw);
raw2->next_phys = NULL;
raw2->next_in_ino = NULL;
@@ -336,24 +336,26 @@
raw = first_raw;
while (*raw) {
+ uint32_t rawlen = ref_totlen(c, jeb, *raw);
+
D1(printk(KERN_DEBUG "Refiling block of %08x at %08x(%d) to %08x\n",
- ref_totlen(*raw), ref_offset(*raw), ref_flags(*raw), ofs));
+ rawlen, ref_offset(*raw), ref_flags(*raw), ofs));
if (ref_obsolete(*raw)) {
/* Shouldn't really happen much */
- new_jeb->dirty_size += ref_totlen(*raw);
- new_jeb->free_size -= ref_totlen(*raw);
- c->dirty_size += ref_totlen(*raw);
+ new_jeb->dirty_size += rawlen;
+ new_jeb->free_size -= rawlen;
+ c->dirty_size += rawlen;
} else {
- new_jeb->used_size += ref_totlen(*raw);
- new_jeb->free_size -= ref_totlen(*raw);
- jeb->dirty_size += ref_totlen(*raw);
- jeb->used_size -= ref_totlen(*raw);
- c->dirty_size += ref_totlen(*raw);
+ new_jeb->used_size += rawlen;
+ new_jeb->free_size -= rawlen;
+ jeb->dirty_size += rawlen;
+ jeb->used_size -= rawlen;
+ c->dirty_size += rawlen;
}
- c->free_size -= ref_totlen(*raw);
+ c->free_size -= rawlen;
(*raw)->flash_offset = ofs | ref_flags(*raw);
- ofs += ref_totlen(*raw);
+ ofs += rawlen;
new_jeb->last_node = *raw;
raw = &(*raw)->next_phys;
More information about the linux-mtd-cvs
mailing list