aboutsummaryrefslogtreecommitdiff
path: root/fs/jffs2/summary.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-05-21 19:05:55 +0100
committerDavid Woodhouse <dwmw2@infradead.org>2006-05-21 19:05:55 +0100
commit0d25971d7c969debf76f9fab6d6b37cb62408f55 (patch)
tree89e6b432d4e8c84d59b4738e5bc1c47a2402adf2 /fs/jffs2/summary.c
parent615191bb1dfc6980e7c7a85225444d860d74b343 (diff)
parentca89a517fa577e6f26621463d3aa4f3c3d530b1e (diff)
Merge git://git.infradead.org/jffs2-devel-2.6
Diffstat (limited to 'fs/jffs2/summary.c')
-rw-r--r--fs/jffs2/summary.c385
1 files changed, 287 insertions, 98 deletions
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index 48293c197f1..1451732e1fa 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -5,6 +5,7 @@
* Zoltan Sogor <weth@inf.u-szeged.hu>,
* Patrik Kluba <pajko@halom.u-szeged.hu>,
* University of Szeged, Hungary
+ * 2005 KaiGai Kohei <kaigai@ak.jp.nec.com>
*
* For licensing information, see the file 'LICENCE' in this directory.
*
@@ -81,6 +82,19 @@ static int jffs2_sum_add_mem(struct jffs2_summary *s, union jffs2_sum_mem *item)
dbg_summary("dirent (%u) added to summary\n",
je32_to_cpu(item->d.ino));
break;
+#ifdef CONFIG_JFFS2_FS_XATTR
+ case JFFS2_NODETYPE_XATTR:
+ s->sum_size += JFFS2_SUMMARY_XATTR_SIZE;
+ s->sum_num++;
+ dbg_summary("xattr (xid=%u, version=%u) added to summary\n",
+ je32_to_cpu(item->x.xid), je32_to_cpu(item->x.version));
+ break;
+ case JFFS2_NODETYPE_XREF:
+ s->sum_size += JFFS2_SUMMARY_XREF_SIZE;
+ s->sum_num++;
+ dbg_summary("xref added to summary\n");
+ break;
+#endif
default:
JFFS2_WARNING("UNKNOWN node type %u\n",
je16_to_cpu(item->u.nodetype));
@@ -141,6 +155,40 @@ int jffs2_sum_add_dirent_mem(struct jffs2_summary *s, struct jffs2_raw_dirent *r
return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp);
}
+#ifdef CONFIG_JFFS2_FS_XATTR
+int jffs2_sum_add_xattr_mem(struct jffs2_summary *s, struct jffs2_raw_xattr *rx, uint32_t ofs)
+{
+ struct jffs2_sum_xattr_mem *temp;
+
+ temp = kmalloc(sizeof(struct jffs2_sum_xattr_mem), GFP_KERNEL);
+ if (!temp)
+ return -ENOMEM;
+
+ temp->nodetype = rx->nodetype;
+ temp->xid = rx->xid;
+ temp->version = rx->version;
+ temp->offset = cpu_to_je32(ofs);
+ temp->totlen = rx->totlen;
+ temp->next = NULL;
+
+ return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp);
+}
+
+int jffs2_sum_add_xref_mem(struct jffs2_summary *s, struct jffs2_raw_xref *rr, uint32_t ofs)
+{
+ struct jffs2_sum_xref_mem *temp;
+
+ temp = kmalloc(sizeof(struct jffs2_sum_xref_mem), GFP_KERNEL);
+ if (!temp)
+ return -ENOMEM;
+
+ temp->nodetype = rr->nodetype;
+ temp->offset = cpu_to_je32(ofs);
+ temp->next = NULL;
+
+ return jffs2_sum_add_mem(s, (union jffs2_sum_mem *)temp);
+}
+#endif
/* Cleanup every collected summary information */
static void jffs2_sum_clean_collected(struct jffs2_summary *s)
@@ -259,7 +307,40 @@ int jffs2_sum_add_kvec(struct jffs2_sb_info *c, const struct kvec *invecs,
return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp);
}
+#ifdef CONFIG_JFFS2_FS_XATTR
+ case JFFS2_NODETYPE_XATTR: {
+ struct jffs2_sum_xattr_mem *temp;
+ if (je32_to_cpu(node->x.version) == 0xffffffff)
+ return 0;
+ temp = kmalloc(sizeof(struct jffs2_sum_xattr_mem), GFP_KERNEL);
+ if (!temp)
+ goto no_mem;
+
+ temp->nodetype = node->x.nodetype;
+ temp->xid = node->x.xid;
+ temp->version = node->x.version;
+ temp->totlen = node->x.totlen;
+ temp->offset = cpu_to_je32(ofs);
+ temp->next = NULL;
+ return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp);
+ }
+ case JFFS2_NODETYPE_XREF: {
+ struct jffs2_sum_xref_mem *temp;
+
+ if (je32_to_cpu(node->r.ino) == 0xffffffff
+ && je32_to_cpu(node->r.xid) == 0xffffffff)
+ return 0;
+ temp = kmalloc(sizeof(struct jffs2_sum_xref_mem), GFP_KERNEL);
+ if (!temp)
+ goto no_mem;
+ temp->nodetype = node->r.nodetype;
+ temp->offset = cpu_to_je32(ofs);
+ temp->next = NULL;
+
+ return jffs2_sum_add_mem(c->summary, (union jffs2_sum_mem *)temp);
+ }
+#endif
case JFFS2_NODETYPE_PADDING:
dbg_summary("node PADDING\n");
c->summary->sum_padded += je32_to_cpu(node->u.totlen);
@@ -288,6 +369,23 @@ no_mem:
return -ENOMEM;
}
+static struct jffs2_raw_node_ref *alloc_ref_at(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
+ uint32_t offset)
+{
+ struct jffs2_raw_node_ref *ref;
+ /* If there was a gap, mark it dirty */
+ if (offset > c->sector_size - jeb->free_size) {
+ int ret = jffs2_scan_dirty_space(c, jeb, offset - (c->sector_size - jeb->free_size));
+ if (ret)
+ return NULL;
+ }
+ ref = jffs2_alloc_raw_node_ref();
+ if (!ref)
+ return NULL;
+
+ ref->flash_offset = jeb->offset + offset;
+ return ref;
+}
/* Process the stored summary information - helper function for jffs2_sum_scan_sumnode() */
@@ -299,6 +397,7 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
struct jffs2_full_dirent *fd;
void *sp;
int i, ino;
+ int err;
sp = summary->sum;
@@ -312,13 +411,13 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
ino = je32_to_cpu(spi->inode);
- dbg_summary("Inode at 0x%08x\n",
- jeb->offset + je32_to_cpu(spi->offset));
+ dbg_summary("Inode at 0x%08x-0x%08x\n",
+ jeb->offset + je32_to_cpu(spi->offset),
+ jeb->offset + je32_to_cpu(spi->offset) + je32_to_cpu(spu->totlen));
- raw = jffs2_alloc_raw_node_ref();
+ raw = alloc_ref_at(c, jeb, je32_to_cpu(spi->offset));
if (!raw) {
JFFS2_NOTICE("allocation of node reference failed\n");
- kfree(summary);
return -ENOMEM;
}
@@ -326,24 +425,17 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
if (!ic) {
JFFS2_NOTICE("scan_make_ino_cache failed\n");
jffs2_free_raw_node_ref(raw);
- kfree(summary);
return -ENOMEM;
}
- raw->flash_offset = (jeb->offset + je32_to_cpu(spi->offset)) | REF_UNCHECKED;
- raw->__totlen = PAD(je32_to_cpu(spi->totlen));
- raw->next_phys = NULL;
- raw->next_in_ino = ic->nodes;
+ raw->flash_offset |= REF_UNCHECKED;
+ raw->next_in_ino = ic->nodes;
ic->nodes = raw;
- if (!jeb->first_node)
- jeb->first_node = raw;
- if (jeb->last_node)
- jeb->last_node->next_phys = raw;
- jeb->last_node = raw;
- *pseudo_random += je32_to_cpu(spi->version);
- UNCHECKED_SPACE(PAD(je32_to_cpu(spi->totlen)));
+ jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spi->totlen)));
+
+ *pseudo_random += je32_to_cpu(spi->version);
sp += JFFS2_SUMMARY_INODE_SIZE;
@@ -355,22 +447,21 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
spd = sp;
dbg_summary("Dirent at 0x%08x\n",
- jeb->offset + je32_to_cpu(spd->offset));
+ jeb->offset + je32_to_cpu(spd->offset),
+ jeb->offset + je32_to_cpu(spd->offset) + je32_to_cpu(spd->totlen));
+
fd = jffs2_alloc_full_dirent(spd->nsize+1);
- if (!fd) {
- kfree(summary);
+ if (!fd)
return -ENOMEM;
- }
memcpy(&fd->name, spd->name, spd->nsize);
fd->name[spd->nsize] = 0;
- raw = jffs2_alloc_raw_node_ref();
+ raw = alloc_ref_at(c, jeb, je32_to_cpu(spd->offset));
if (!raw) {
jffs2_free_full_dirent(fd);
JFFS2_NOTICE("allocation of node reference failed\n");
- kfree(summary);
return -ENOMEM;
}
@@ -378,20 +469,14 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
if (!ic) {
jffs2_free_full_dirent(fd);
jffs2_free_raw_node_ref(raw);
- kfree(summary);
return -ENOMEM;
}
- raw->__totlen = PAD(je32_to_cpu(spd->totlen));
- raw->flash_offset = (jeb->offset + je32_to_cpu(spd->offset)) | REF_PRISTINE;
- raw->next_phys = NULL;
+ raw->flash_offset |= REF_PRISTINE;
raw->next_in_ino = ic->nodes;
ic->nodes = raw;
- if (!jeb->first_node)
- jeb->first_node = raw;
- if (jeb->last_node)
- jeb->last_node->next_phys = raw;
- jeb->last_node = raw;
+
+ jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spd->totlen)));
fd->raw = raw;
fd->next = NULL;
@@ -399,7 +484,7 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
fd->ino = je32_to_cpu(spd->ino);
fd->nhash = full_name_hash(fd->name, spd->nsize);
fd->type = spd->type;
- USED_SPACE(PAD(je32_to_cpu(spd->totlen)));
+
jffs2_add_fd_to_list(c, fd, &ic->scan_dents);
*pseudo_random += je32_to_cpu(spd->version);
@@ -408,48 +493,122 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
break;
}
+#ifdef CONFIG_JFFS2_FS_XATTR
+ case JFFS2_NODETYPE_XATTR: {
+ struct jffs2_xattr_datum *xd;
+ struct jffs2_sum_xattr_flash *spx;
+
+ spx = (struct jffs2_sum_xattr_flash *)sp;
+ dbg_summary("xattr at %#08x-%#08x (xid=%u, version=%u)\n",
+ jeb->offset + je32_to_cpu(spx->offset),
+ jeb->offset + je32_to_cpu(spx->offset) + je32_to_cpu(spx->totlen),
+ je32_to_cpu(spx->xid), je32_to_cpu(spx->version));
+ raw = alloc_ref_at(c, jeb, je32_to_cpu(spx->offset));
+ if (!raw) {
+ JFFS2_NOTICE("allocation of node reference failed\n");
+ return -ENOMEM;
+ }
+ xd = jffs2_setup_xattr_datum(c, je32_to_cpu(spx->xid),
+ je32_to_cpu(spx->version));
+ if (IS_ERR(xd)) {
+ jffs2_free_raw_node_ref(raw);
+ if (PTR_ERR(xd) == -EEXIST) {
+ /* a newer version of xd exists */
+ if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(spx->totlen))))
+ return err;
+ sp += JFFS2_SUMMARY_XATTR_SIZE;
+ break;
+ }
+ JFFS2_NOTICE("allocation of xattr_datum failed\n");
+ return PTR_ERR(xd);
+ }
+ xd->node = raw;
+
+ raw->flash_offset |= REF_UNCHECKED;
+ raw->next_in_ino = (void *)xd;
+
+ jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spx->totlen)));
+
+ *pseudo_random += je32_to_cpu(spx->xid);
+ sp += JFFS2_SUMMARY_XATTR_SIZE;
+
+ break;
+ }
+ case JFFS2_NODETYPE_XREF: {
+ struct jffs2_xattr_ref *ref;
+ struct jffs2_sum_xref_flash *spr;
+
+ spr = (struct jffs2_sum_xref_flash *)sp;
+ dbg_summary("xref at %#08x-%#08x\n",
+ jeb->offset + je32_to_cpu(spr->offset),
+ jeb->offset + je32_to_cpu(spr->offset) + PAD(sizeof(struct jffs2_raw_xref)));
+
+ raw = alloc_ref_at(c, jeb, je32_to_cpu(spr->offset));
+ if (!raw) {
+ JFFS2_NOTICE("allocation of node reference failed\n");
+ return -ENOMEM;
+ }
+ ref = jffs2_alloc_xattr_ref();
+ if (!ref) {
+ JFFS2_NOTICE("allocation of xattr_datum failed\n");
+ jffs2_free_raw_node_ref(raw);
+ return -ENOMEM;
+ }
+ ref->ino = 0xfffffffe;
+ ref->xid = 0xfffffffd;
+ ref->node = raw;
+ ref->next = c->xref_temp;
+ c->xref_temp = ref;
+
+ raw->flash_offset |= REF_UNCHECKED;
+ raw->next_in_ino = (void *)ref;
+ jffs2_link_node_ref(c, jeb, raw, PAD(sizeof(struct jffs2_raw_xref)));
+
+ *pseudo_random += raw->flash_offset;
+ sp += JFFS2_SUMMARY_XREF_SIZE;
+
+ break;
+ }
+#endif
default : {
- JFFS2_WARNING("Unsupported node type found in summary! Exiting...");
- kfree(summary);
- return -EIO;
+ uint16_t nodetype = je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype);
+ JFFS2_WARNING("Unsupported node type %x found in summary! Exiting...\n", nodetype);
+ if ((nodetype & JFFS2_COMPAT_MASK) == JFFS2_FEATURE_INCOMPAT)
+ return -EIO;
+
+ /* For compatible node types, just fall back to the full scan */
+ c->wasted_size -= jeb->wasted_size;
+ c->free_size += c->sector_size - jeb->free_size;
+ c->used_size -= jeb->used_size;
+ c->dirty_size -= jeb->dirty_size;
+ jeb->wasted_size = jeb->used_size = jeb->dirty_size = 0;
+ jeb->free_size = c->sector_size;
+
+ jffs2_free_all_node_refs(c, jeb);
+ return -ENOTRECOVERABLE;
}
}
}
- kfree(summary);
return 0;
}
/* Process the summary node - called from jffs2_scan_eraseblock() */
-
int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
- uint32_t ofs, uint32_t *pseudo_random)
+ struct jffs2_raw_summary *summary, uint32_t sumsize,
+ uint32_t *pseudo_random)
{
struct jffs2_unknown_node crcnode;
struct jffs2_raw_node_ref *cache_ref;
- struct jffs2_raw_summary *summary;
- int ret, sumsize;
+ int ret, ofs;
uint32_t crc;
+ int err;
- sumsize = c->sector_size - ofs;
- ofs += jeb->offset;
+ ofs = c->sector_size - sumsize;
dbg_summary("summary found for 0x%08x at 0x%08x (0x%x bytes)\n",
- jeb->offset, ofs, sumsize);
-
- summary = kmalloc(sumsize, GFP_KERNEL);
-
- if (!summary) {
- return -ENOMEM;
- }
-
- ret = jffs2_fill_scan_buf(c, (unsigned char *)summary, ofs, sumsize);
-
- if (ret) {
- kfree(summary);
- return ret;
- }
+ jeb->offset, jeb->offset + ofs, sumsize);
/* OK, now check for node validity and CRC */
crcnode.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -489,40 +648,38 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
if (je32_to_cpu(summary->cln_mkr) != c->cleanmarker_size) {
dbg_summary("CLEANMARKER node has totlen 0x%x != normal 0x%x\n",
je32_to_cpu(summary->cln_mkr), c->cleanmarker_size);
- UNCHECKED_SPACE(PAD(je32_to_cpu(summary->cln_mkr)));
+ if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(summary->cln_mkr)))))
+ return err;
} else if (jeb->first_node) {
dbg_summary("CLEANMARKER node not first node in block "
"(0x%08x)\n", jeb->offset);
- UNCHECKED_SPACE(PAD(je32_to_cpu(summary->cln_mkr)));
+ if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(summary->cln_mkr)))))
+ return err;
} else {
struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref();
if (!marker_ref) {
JFFS2_NOTICE("Failed to allocate node ref for clean marker\n");
- kfree(summary);
return -ENOMEM;
}
- marker_ref->next_in_ino = NULL;
- marker_ref->next_phys = NULL;
marker_ref->flash_offset = jeb->offset | REF_NORMAL;
- marker_ref->__totlen = je32_to_cpu(summary->cln_mkr);
- jeb->first_node = jeb->last_node = marker_ref;
+ marker_ref->next_in_ino = NULL;
- USED_SPACE( PAD(je32_to_cpu(summary->cln_mkr)) );
+ jffs2_link_node_ref(c, jeb, marker_ref, je32_to_cpu(summary->cln_mkr));
}
}
- if (je32_to_cpu(summary->padded)) {
- DIRTY_SPACE(je32_to_cpu(summary->padded));
- }
-
ret = jffs2_sum_process_sum_data(c, jeb, summary, pseudo_random);
+ /* -ENOTRECOVERABLE isn't a fatal error -- it means we should do a full
+ scan of this eraseblock. So return zero */
+ if (ret == -ENOTRECOVERABLE)
+ return 0;
if (ret)
- return ret;
+ return ret; /* real error */
/* for PARANOIA_CHECK */
- cache_ref = jffs2_alloc_raw_node_ref();
+ cache_ref = alloc_ref_at(c, jeb, ofs);
if (!cache_ref) {
JFFS2_NOTICE("Failed to allocate node ref for cache\n");
@@ -530,22 +687,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
}
cache_ref->next_in_ino = NULL;
- cache_ref->next_phys = NULL;
- cache_ref->flash_offset = ofs | REF_NORMAL;
- cache_ref->__totlen = sumsize;
+ cache_ref->flash_offset |= REF_NORMAL;
- if (!jeb->first_node)
- jeb->first_node = cache_ref;
- if (jeb->last_node)
- jeb->last_node->next_phys = cache_ref;
- jeb->last_node = cache_ref;
+ jffs2_link_node_ref(c, jeb, cache_ref, sumsize);
- USED_SPACE(sumsize);
-
- jeb->wasted_size += jeb->free_size;
- c->wasted_size += jeb->free_size;
- c->free_size -= jeb->free_size;
- jeb->free_size = 0;
+ if (unlikely(jeb->free_size)) {
+ JFFS2_WARNING("Free size 0x%x bytes in eraseblock @0x%08x with summary?\n",
+ jeb->free_size, jeb->offset);
+ jeb->wasted_size += jeb->free_size;
+ c->wasted_size += jeb->free_size;
+ c->free_size -= jeb->free_size;
+ jeb->free_size = 0;
+ }
return jffs2_scan_classify_jeb(c, jeb);
@@ -617,9 +770,40 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
break;
}
+#ifdef CONFIG_JFFS2_FS_XATTR
+ case JFFS2_NODETYPE_XATTR: {
+ struct jffs2_sum_xattr_flash *sxattr_ptr = wpage;
+
+ temp = c->summary->sum_list_head;
+ sxattr_ptr->nodetype = temp->x.nodetype;
+ sxattr_ptr->xid = temp->x.xid;
+ sxattr_ptr->version = temp->x.version;
+ sxattr_ptr->offset = temp->x.offset;
+ sxattr_ptr->totlen = temp->x.totlen;
+
+ wpage += JFFS2_SUMMARY_XATTR_SIZE;
+ break;
+ }
+ case JFFS2_NODETYPE_XREF: {
+ struct jffs2_sum_xref_flash *sxref_ptr = wpage;
+ temp = c->summary->sum_list_head;
+ sxref_ptr->nodetype = temp->r.nodetype;
+ sxref_ptr->offset = temp->r.offset;
+
+ wpage += JFFS2_SUMMARY_XREF_SIZE;
+ break;
+ }
+#endif
default : {
- BUG(); /* unknown node in summary information */
+ if ((je16_to_cpu(temp->u.nodetype) & JFFS2_COMPAT_MASK)
+ == JFFS2_FEATURE_RWCOMPAT_COPY) {
+ dbg_summary("Writing unknown RWCOMPAT_COPY node type %x\n",
+ je16_to_cpu(temp->u.nodetype));
+ jffs2_sum_disable_collecting(c->summary);
+ } else {
+ BUG(); /* unknown node in summary information */
+ }
}
}
@@ -651,19 +835,32 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
spin_unlock(&c->erase_completion_lock);
ret = jffs2_flash_writev(c, vecs, 2, jeb->offset + c->sector_size -
jeb->free_size, &retlen, 0);
- spin_lock(&c->erase_completion_lock);
-
if (ret || (retlen != infosize)) {
+ struct jffs2_raw_node_ref *ref;
+
JFFS2_WARNING("Write of %u bytes at 0x%08x failed. returned %d, retlen %zd\n",
infosize, jeb->offset + c->sector_size - jeb->free_size, ret, retlen);
+ /* Waste remaining space */
+ ref = jffs2_alloc_raw_node_ref();
+ if (ref) {
+ spin_lock(&c->erase_completion_lock);
+
+ ref->flash_offset = jeb->offset + c->sector_size - jeb->free_size;
+ ref->flash_offset |= REF_OBSOLETE;
+ ref->next_in_ino = 0;
+
+ jffs2_link_node_ref(c, jeb, ref, c->sector_size - jeb->free_size);
+ }
+
c->summary->sum_size = JFFS2_SUMMARY_NOSUM_SIZE;
- WASTED_SPACE(infosize);
return 1;
}
+ spin_lock(&c->erase_completion_lock);
+
return 0;
}
@@ -706,7 +903,6 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
/* for ACCT_PARANOIA_CHECK */
spin_unlock(&c->erase_completion_lock);
summary_ref = jffs2_alloc_raw_node_ref();
- spin_lock(&c->erase_completion_lock);
if (!summary_ref) {
JFFS2_NOTICE("Failed to allocate node ref for summary\n");
@@ -714,17 +910,10 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
}
summary_ref->next_in_ino = NULL;
- summary_ref->next_phys = NULL;
summary_ref->flash_offset = (jeb->offset + c->sector_size - jeb->free_size) | REF_NORMAL;
- summary_ref->__totlen = infosize;
-
- if (!jeb->first_node)
- jeb->first_node = summary_ref;
- if (jeb->last_node)
- jeb->last_node->next_phys = summary_ref;
- jeb->last_node = summary_ref;
- USED_SPACE(infosize);
+ spin_lock(&c->erase_completion_lock);
+ jffs2_link_node_ref(c, jeb, summary_ref, infosize);
return 0;
}