aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2006-05-23 21:04:45 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-05-23 21:04:45 -0400
commit2f785402f39b96a077b6e62bf26164bfb8e0c980 (patch)
tree3f3a38b484ef2dabda1599d4d8f08b121bd03a76 /fs/jffs2
parent4cbb9b80e171107c6c34116283fe38e5a396c68b (diff)
[JFFS2] Reduce visibility of raw_node_ref to upper layers of JFFS2 code.
As the first step towards eliminating the ref->next_phys member and saving memory by using an _array_ of struct jffs2_raw_node_ref per eraseblock, stop the write functions from allocating their own refs; have them just _reserve_ the appropriate number instead. Then jffs2_link_node_ref() can just fill them in. Use a linked list of pre-allocated refs in the superblock, for now. Once we switch to an array, it'll just be a case of extending that array. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2')
-rw-r--r--fs/jffs2/erase.c16
-rw-r--r--fs/jffs2/gc.c25
-rw-r--r--fs/jffs2/jffs2_fs_sb.h3
-rw-r--r--fs/jffs2/malloc.c26
-rw-r--r--fs/jffs2/nodelist.c51
-rw-r--r--fs/jffs2/nodelist.h19
-rw-r--r--fs/jffs2/nodemgmt.c39
-rw-r--r--fs/jffs2/scan.c77
-rw-r--r--fs/jffs2/summary.c162
-rw-r--r--fs/jffs2/wbuf.c26
-rw-r--r--fs/jffs2/write.c71
-rw-r--r--fs/jffs2/xattr.c38
12 files changed, 204 insertions, 349 deletions
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index 4616fed75730..f939f908b948 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -296,7 +296,7 @@ void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *
296 jffs2_remove_node_refs_from_ino_list(c, ref, jeb); 296 jffs2_remove_node_refs_from_ino_list(c, ref, jeb);
297 /* else it was a non-inode node or already removed, so don't bother */ 297 /* else it was a non-inode node or already removed, so don't bother */
298 298
299 jffs2_free_raw_node_ref(ref); 299 __jffs2_free_raw_node_ref(ref);
300 } 300 }
301 jeb->last_node = NULL; 301 jeb->last_node = NULL;
302} 302}
@@ -351,7 +351,6 @@ fail:
351 351
352static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) 352static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
353{ 353{
354 struct jffs2_raw_node_ref *marker_ref = NULL;
355 size_t retlen; 354 size_t retlen;
356 int ret; 355 int ret;
357 uint32_t bad_offset; 356 uint32_t bad_offset;
@@ -384,11 +383,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
384 .totlen = cpu_to_je32(c->cleanmarker_size) 383 .totlen = cpu_to_je32(c->cleanmarker_size)
385 }; 384 };
386 385
387 marker_ref = jffs2_alloc_raw_node_ref(); 386 jffs2_prealloc_raw_node_refs(c, 1);
388 if (!marker_ref) {
389 printk(KERN_WARNING "Failed to allocate raw node ref for clean marker. Refiling\n");
390 goto refile;
391 }
392 387
393 marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4)); 388 marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4));
394 389
@@ -404,16 +399,13 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
404 printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %zd, got %zd\n", 399 printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %zd, got %zd\n",
405 jeb->offset, sizeof(marker), retlen); 400 jeb->offset, sizeof(marker), retlen);
406 401
407 jffs2_free_raw_node_ref(marker_ref);
408 goto filebad; 402 goto filebad;
409 } 403 }
410 404
411 /* Everything else got zeroed before the erase */ 405 /* Everything else got zeroed before the erase */
412 jeb->free_size = c->sector_size; 406 jeb->free_size = c->sector_size;
413 407 /* FIXME Special case for cleanmarker in empty block */
414 marker_ref->flash_offset = jeb->offset | REF_NORMAL; 408 jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL, c->cleanmarker_size, NULL);
415
416 jffs2_link_node_ref(c, jeb, marker_ref, c->cleanmarker_size, NULL);
417 } 409 }
418 410
419 spin_lock(&c->erase_completion_lock); 411 spin_lock(&c->erase_completion_lock);
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
index f9e982a65ac2..a22ff5df7fcc 100644
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.c
@@ -528,7 +528,6 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
528 struct jffs2_raw_node_ref *raw) 528 struct jffs2_raw_node_ref *raw)
529{ 529{
530 union jffs2_node_union *node; 530 union jffs2_node_union *node;
531 struct jffs2_raw_node_ref *nraw;
532 size_t retlen; 531 size_t retlen;
533 int ret; 532 int ret;
534 uint32_t phys_ofs, alloclen; 533 uint32_t phys_ofs, alloclen;
@@ -618,30 +617,21 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
618 } 617 }
619 } 618 }
620 619
621 nraw = jffs2_alloc_raw_node_ref();
622 if (!nraw) {
623 ret = -ENOMEM;
624 goto out_node;
625 }
626
627 /* OK, all the CRCs are good; this node can just be copied as-is. */ 620 /* OK, all the CRCs are good; this node can just be copied as-is. */
628 retry: 621 retry:
629 nraw->flash_offset = phys_ofs = write_ofs(c); 622 phys_ofs = write_ofs(c);
630 623
631 ret = jffs2_flash_write(c, phys_ofs, rawlen, &retlen, (char *)node); 624 ret = jffs2_flash_write(c, phys_ofs, rawlen, &retlen, (char *)node);
632 625
633 if (ret || (retlen != rawlen)) { 626 if (ret || (retlen != rawlen)) {
634 printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n", 627 printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n",
635 rawlen, nraw->flash_offset, ret, retlen); 628 rawlen, phys_ofs, ret, retlen);
636 if (retlen) { 629 if (retlen) {
637 nraw->flash_offset |= REF_OBSOLETE; 630 jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, rawlen, NULL);
638 jffs2_add_physical_node_ref(c, nraw, rawlen, NULL);
639 jffs2_mark_node_obsolete(c, nraw);
640 } else { 631 } else {
641 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", nraw->flash_offset); 632 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", phys_ofs);
642 jffs2_free_raw_node_ref(nraw);
643 } 633 }
644 if (!retried && (nraw = jffs2_alloc_raw_node_ref())) { 634 if (!retried) {
645 /* Try to reallocate space and retry */ 635 /* Try to reallocate space and retry */
646 uint32_t dummy; 636 uint32_t dummy;
647 struct jffs2_eraseblock *jeb = &c->blocks[phys_ofs / c->sector_size]; 637 struct jffs2_eraseblock *jeb = &c->blocks[phys_ofs / c->sector_size];
@@ -666,16 +656,13 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
666 goto retry; 656 goto retry;
667 } 657 }
668 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); 658 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
669 jffs2_free_raw_node_ref(nraw);
670 } 659 }
671 660
672 jffs2_free_raw_node_ref(nraw);
673 if (!ret) 661 if (!ret)
674 ret = -EIO; 662 ret = -EIO;
675 goto out_node; 663 goto out_node;
676 } 664 }
677 nraw->flash_offset |= REF_PRISTINE; 665 jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, rawlen, ic);
678 jffs2_add_physical_node_ref(c, nraw, rawlen, ic);
679 666
680 jffs2_mark_node_obsolete(c, raw); 667 jffs2_mark_node_obsolete(c, raw);
681 D1(printk(KERN_DEBUG "WHEEE! GC REF_PRISTINE node at 0x%08x succeeded\n", ref_offset(raw))); 668 D1(printk(KERN_DEBUG "WHEEE! GC REF_PRISTINE node at 0x%08x succeeded\n", ref_offset(raw)));
diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h
index 272fbea55192..67529f0a44dd 100644
--- a/fs/jffs2/jffs2_fs_sb.h
+++ b/fs/jffs2/jffs2_fs_sb.h
@@ -26,6 +26,9 @@ struct jffs2_inodirty;
26struct jffs2_sb_info { 26struct jffs2_sb_info {
27 struct mtd_info *mtd; 27 struct mtd_info *mtd;
28 28
29 struct jffs2_raw_node_ref *refs;
30 int reserved_refs;
31
29 uint32_t highest_ino; 32 uint32_t highest_ino;
30 uint32_t checked_ino; 33 uint32_t checked_ino;
31 34
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c
index f2473fa2fd16..3df3250314a2 100644
--- a/fs/jffs2/malloc.c
+++ b/fs/jffs2/malloc.c
@@ -190,7 +190,29 @@ void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x)
190 kmem_cache_free(tmp_dnode_info_slab, x); 190 kmem_cache_free(tmp_dnode_info_slab, x);
191} 191}
192 192
193struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void) 193int jffs2_prealloc_raw_node_refs(struct jffs2_sb_info *c, int nr)
194{
195 struct jffs2_raw_node_ref *p = c->refs;
196
197 dbg_memalloc("%d\n", nr);
198
199 while (nr && p) {
200 p = p->next_in_ino;
201 nr--;
202 }
203 while (nr) {
204 p = __jffs2_alloc_raw_node_ref();
205 if (!p)
206 return -ENOMEM;
207 p->next_in_ino = c->refs;
208 c->refs = p;
209 nr--;
210 }
211 c->reserved_refs = nr;
212 return 0;
213}
214
215struct jffs2_raw_node_ref *__jffs2_alloc_raw_node_ref(void)
194{ 216{
195 struct jffs2_raw_node_ref *ret; 217 struct jffs2_raw_node_ref *ret;
196 ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL); 218 ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL);
@@ -198,7 +220,7 @@ struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void)
198 return ret; 220 return ret;
199} 221}
200 222
201void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x) 223void __jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x)
202{ 224{
203 dbg_memalloc("%p\n", x); 225 dbg_memalloc("%p\n", x);
204 kmem_cache_free(raw_node_ref_slab, x); 226 kmem_cache_free(raw_node_ref_slab, x);
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
index d25d4919ca97..1e6eabd730f2 100644
--- a/fs/jffs2/nodelist.c
+++ b/fs/jffs2/nodelist.c
@@ -953,13 +953,19 @@ void jffs2_free_raw_node_refs(struct jffs2_sb_info *c)
953 953
954 for (i=0; i<c->nr_blocks; i++) { 954 for (i=0; i<c->nr_blocks; i++) {
955 this = c->blocks[i].first_node; 955 this = c->blocks[i].first_node;
956 while(this) { 956 while (this) {
957 next = this->next_phys; 957 next = this->next_phys;
958 jffs2_free_raw_node_ref(this); 958 __jffs2_free_raw_node_ref(this);
959 this = next; 959 this = next;
960 } 960 }
961 c->blocks[i].first_node = c->blocks[i].last_node = NULL; 961 c->blocks[i].first_node = c->blocks[i].last_node = NULL;
962 } 962 }
963 this = c->refs;
964 while (this) {
965 next = this->next_in_ino;
966 __jffs2_free_raw_node_ref(this);
967 this = next;
968 }
963} 969}
964 970
965struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset) 971struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset)
@@ -1047,10 +1053,27 @@ void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c)
1047 } 1053 }
1048} 1054}
1049 1055
1050void jffs2_link_node_ref(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 1056struct jffs2_raw_node_ref *jffs2_link_node_ref(struct jffs2_sb_info *c,
1051 struct jffs2_raw_node_ref *ref, uint32_t len, 1057 struct jffs2_eraseblock *jeb,
1052 struct jffs2_inode_cache *ic) 1058 uint32_t ofs, uint32_t len,
1059 struct jffs2_inode_cache *ic)
1053{ 1060{
1061 struct jffs2_raw_node_ref *ref;
1062
1063 /* These will be preallocated _very_ shortly. */
1064 ref = c->refs;
1065 if (!c->refs) {
1066 JFFS2_WARNING("Using non-preallocated refs!\n");
1067 ref = __jffs2_alloc_raw_node_ref();
1068 BUG_ON(!ref);
1069 WARN_ON(1);
1070 } else {
1071 c->refs = ref->next_in_ino;
1072 }
1073
1074 ref->next_phys = NULL;
1075 ref->flash_offset = ofs;
1076
1054 if (!jeb->first_node) 1077 if (!jeb->first_node)
1055 jeb->first_node = ref; 1078 jeb->first_node = ref;
1056 if (jeb->last_node) { 1079 if (jeb->last_node) {
@@ -1093,15 +1116,15 @@ void jffs2_link_node_ref(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
1093 c->free_size -= len; 1116 c->free_size -= len;
1094 jeb->free_size -= len; 1117 jeb->free_size -= len;
1095 1118
1096 ref->next_phys = NULL;
1097#ifdef TEST_TOTLEN 1119#ifdef TEST_TOTLEN
1098 /* Set (and test) __totlen field... for now */ 1120 /* Set (and test) __totlen field... for now */
1099 ref->__totlen = len; 1121 ref->__totlen = len;
1100 ref_totlen(c, jeb, ref); 1122 ref_totlen(c, jeb, ref);
1101#endif 1123#endif
1124 return ref;
1102} 1125}
1103 1126
1104/* No locking. Do not use on a live file system */ 1127/* No locking, no reservation of 'ref'. Do not use on a live file system */
1105int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 1128int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
1106 uint32_t size) 1129 uint32_t size)
1107{ 1130{
@@ -1121,18 +1144,10 @@ int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
1121 jeb->dirty_size += size; 1144 jeb->dirty_size += size;
1122 jeb->free_size -= size; 1145 jeb->free_size -= size;
1123 } else { 1146 } else {
1124 struct jffs2_raw_node_ref *ref; 1147 uint32_t ofs = jeb->offset + c->sector_size - jeb->free_size;
1125 ref = jffs2_alloc_raw_node_ref(); 1148 ofs |= REF_OBSOLETE;
1126 if (!ref)
1127 return -ENOMEM;
1128
1129 ref->flash_offset = jeb->offset + c->sector_size - jeb->free_size;
1130 ref->flash_offset |= REF_OBSOLETE;
1131#ifdef TEST_TOTLEN
1132 ref->__totlen = size;
1133#endif
1134 1149
1135 jffs2_link_node_ref(c, jeb, ref, size, NULL); 1150 jffs2_link_node_ref(c, jeb, ofs, size, NULL);
1136 } 1151 }
1137 1152
1138 return 0; 1153 return 0;
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index 76f1b9419eea..7cc74d2ab4dc 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -318,9 +318,10 @@ void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *t
318int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn); 318int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn);
319void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size); 319void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size);
320int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn); 320int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn);
321void jffs2_link_node_ref(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 321struct jffs2_raw_node_ref *jffs2_link_node_ref(struct jffs2_sb_info *c,
322 struct jffs2_raw_node_ref *ref, uint32_t len, 322 struct jffs2_eraseblock *jeb,
323 struct jffs2_inode_cache *ic); 323 uint32_t ofs, uint32_t len,
324 struct jffs2_inode_cache *ic);
324extern uint32_t __jffs2_ref_totlen(struct jffs2_sb_info *c, 325extern uint32_t __jffs2_ref_totlen(struct jffs2_sb_info *c,
325 struct jffs2_eraseblock *jeb, 326 struct jffs2_eraseblock *jeb,
326 struct jffs2_raw_node_ref *ref); 327 struct jffs2_raw_node_ref *ref);
@@ -331,10 +332,9 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
331 uint32_t *len, int prio, uint32_t sumsize); 332 uint32_t *len, int prio, uint32_t sumsize);
332int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, 333int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize,
333 uint32_t *len, uint32_t sumsize); 334 uint32_t *len, uint32_t sumsize);
334int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, 335struct jffs2_raw_node_ref *jffs2_add_physical_node_ref(struct jffs2_sb_info *c,
335 struct jffs2_raw_node_ref *new, 336 uint32_t ofs, uint32_t len,
336 uint32_t len, 337 struct jffs2_inode_cache *ic);
337 struct jffs2_inode_cache *ic);
338void jffs2_complete_reservation(struct jffs2_sb_info *c); 338void jffs2_complete_reservation(struct jffs2_sb_info *c);
339void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *raw); 339void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *raw);
340 340
@@ -378,8 +378,9 @@ struct jffs2_raw_inode *jffs2_alloc_raw_inode(void);
378void jffs2_free_raw_inode(struct jffs2_raw_inode *); 378void jffs2_free_raw_inode(struct jffs2_raw_inode *);
379struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void); 379struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void);
380void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *); 380void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *);
381struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void); 381int jffs2_prealloc_raw_node_refs(struct jffs2_sb_info *c, int nr);
382void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *); 382struct jffs2_raw_node_ref *__jffs2_alloc_raw_node_ref(void);
383void __jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *);
383struct jffs2_node_frag *jffs2_alloc_node_frag(void); 384struct jffs2_node_frag *jffs2_alloc_node_frag(void);
384void jffs2_free_node_frag(struct jffs2_node_frag *); 385void jffs2_free_node_frag(struct jffs2_node_frag *);
385struct jffs2_inode_cache *jffs2_alloc_inode_cache(void); 386struct jffs2_inode_cache *jffs2_alloc_inode_cache(void);
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
index 8feb8749bc75..01bf2773fe4d 100644
--- a/fs/jffs2/nodemgmt.c
+++ b/fs/jffs2/nodemgmt.c
@@ -137,6 +137,8 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
137 } 137 }
138 } 138 }
139 spin_unlock(&c->erase_completion_lock); 139 spin_unlock(&c->erase_completion_lock);
140 if (!ret)
141 ret = jffs2_prealloc_raw_node_refs(c, 1);
140 if (ret) 142 if (ret)
141 up(&c->alloc_sem); 143 up(&c->alloc_sem);
142 return ret; 144 return ret;
@@ -158,6 +160,9 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize,
158 } 160 }
159 } 161 }
160 spin_unlock(&c->erase_completion_lock); 162 spin_unlock(&c->erase_completion_lock);
163 if (!ret)
164 ret = jffs2_prealloc_raw_node_refs(c, 1);
165
161 return ret; 166 return ret;
162} 167}
163 168
@@ -381,30 +386,30 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize,
381 * Must be called with the alloc_sem held. 386 * Must be called with the alloc_sem held.
382 */ 387 */
383 388
384int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new, 389struct jffs2_raw_node_ref *jffs2_add_physical_node_ref(struct jffs2_sb_info *c,
385 uint32_t len, struct jffs2_inode_cache *ic) 390 uint32_t ofs, uint32_t len,
391 struct jffs2_inode_cache *ic)
386{ 392{
387 struct jffs2_eraseblock *jeb; 393 struct jffs2_eraseblock *jeb;
394 struct jffs2_raw_node_ref *new;
388 395
389 jeb = &c->blocks[new->flash_offset / c->sector_size]; 396 jeb = &c->blocks[ofs / c->sector_size];
390#ifdef TEST_TOTLEN
391 new->__totlen = len;
392#endif
393 397
394 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)); 398 D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n",
399 ofs & ~3, ofs & 3, len));
395#if 1 400#if 1
396 /* we could get some obsolete nodes after nextblock was refiled 401 /* Allow non-obsolete nodes only to be added at the end of c->nextblock,
397 in wbuf.c */ 402 if c->nextblock is set. Note that wbuf.c will file obsolete nodes
398 if ((c->nextblock || !ref_obsolete(new)) 403 even after refiling c->nextblock */
399 &&(jeb != c->nextblock || ref_offset(new) != jeb->offset + (c->sector_size - jeb->free_size))) { 404 if ((c->nextblock || ((ofs & 3) != REF_OBSOLETE))
405 && (jeb != c->nextblock || (ofs & ~3) != jeb->offset + (c->sector_size - jeb->free_size))) {
400 printk(KERN_WARNING "argh. node added in wrong place\n"); 406 printk(KERN_WARNING "argh. node added in wrong place\n");
401 jffs2_free_raw_node_ref(new); 407 return ERR_PTR(-EINVAL);
402 return -EINVAL;
403 } 408 }
404#endif 409#endif
405 spin_lock(&c->erase_completion_lock); 410 spin_lock(&c->erase_completion_lock);
406 411
407 jffs2_link_node_ref(c, jeb, new, len, ic); 412 new = jffs2_link_node_ref(c, jeb, ofs, len, ic);
408 413
409 if (!jeb->free_size && !jeb->dirty_size && !ISDIRTY(jeb->wasted_size)) { 414 if (!jeb->free_size && !jeb->dirty_size && !ISDIRTY(jeb->wasted_size)) {
410 /* If it lives on the dirty_list, jffs2_reserve_space will put it there */ 415 /* If it lives on the dirty_list, jffs2_reserve_space will put it there */
@@ -425,7 +430,7 @@ int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_r
425 430
426 spin_unlock(&c->erase_completion_lock); 431 spin_unlock(&c->erase_completion_lock);
427 432
428 return 0; 433 return new;
429} 434}
430 435
431 436
@@ -697,7 +702,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
697 } 702 }
698 spin_unlock(&c->erase_completion_lock); 703 spin_unlock(&c->erase_completion_lock);
699 704
700 jffs2_free_raw_node_ref(n); 705 __jffs2_free_raw_node_ref(n);
701 } 706 }
702 707
703 /* Also merge with the previous node in the list, if there is one 708 /* Also merge with the previous node in the list, if there is one
@@ -722,7 +727,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
722 jeb->gc_node=p; 727 jeb->gc_node=p;
723 } 728 }
724 p->next_phys = ref->next_phys; 729 p->next_phys = ref->next_phys;
725 jffs2_free_raw_node_ref(ref); 730 __jffs2_free_raw_node_ref(ref);
726 } 731 }
727 spin_unlock(&c->erase_completion_lock); 732 spin_unlock(&c->erase_completion_lock);
728 } 733 }
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index 6fce703c0543..87b0a416b6a0 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -317,7 +317,6 @@ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
317 struct jffs2_summary *s) 317 struct jffs2_summary *s)
318{ 318{
319 struct jffs2_xattr_datum *xd; 319 struct jffs2_xattr_datum *xd;
320 struct jffs2_raw_node_ref *raw;
321 uint32_t totlen, crc; 320 uint32_t totlen, crc;
322 int err; 321 int err;
323 322
@@ -340,13 +339,8 @@ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
340 return 0; 339 return 0;
341 } 340 }
342 341
343 raw = jffs2_alloc_raw_node_ref();
344 if (!raw)
345 return -ENOMEM;
346
347 xd = jffs2_setup_xattr_datum(c, je32_to_cpu(rx->xid), je32_to_cpu(rx->version)); 342 xd = jffs2_setup_xattr_datum(c, je32_to_cpu(rx->xid), je32_to_cpu(rx->version));
348 if (IS_ERR(xd)) { 343 if (IS_ERR(xd)) {
349 jffs2_free_raw_node_ref(raw);
350 if (PTR_ERR(xd) == -EEXIST) { 344 if (PTR_ERR(xd) == -EEXIST) {
351 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rx->totlen))))) 345 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rx->totlen)))))
352 return err; 346 return err;
@@ -358,12 +352,9 @@ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
358 xd->name_len = rx->name_len; 352 xd->name_len = rx->name_len;
359 xd->value_len = je16_to_cpu(rx->value_len); 353 xd->value_len = je16_to_cpu(rx->value_len);
360 xd->data_crc = je32_to_cpu(rx->data_crc); 354 xd->data_crc = je32_to_cpu(rx->data_crc);
361 xd->node = raw;
362
363 raw->flash_offset = ofs | REF_PRISTINE;
364 355
365 jffs2_link_node_ref(c, jeb, raw, totlen, NULL); 356 xd->node = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, totlen, NULL);
366 /* FIXME */ raw->next_in_ino = (void *)xd; 357 /* FIXME */ xd->node->next_in_ino = (void *)xd;
367 358
368 if (jffs2_sum_active()) 359 if (jffs2_sum_active())
369 jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset); 360 jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset);
@@ -377,7 +368,6 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock
377 struct jffs2_summary *s) 368 struct jffs2_summary *s)
378{ 369{
379 struct jffs2_xattr_ref *ref; 370 struct jffs2_xattr_ref *ref;
380 struct jffs2_raw_node_ref *raw;
381 uint32_t crc; 371 uint32_t crc;
382 int err; 372 int err;
383 373
@@ -404,12 +394,6 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock
404 if (!ref) 394 if (!ref)
405 return -ENOMEM; 395 return -ENOMEM;
406 396
407 raw = jffs2_alloc_raw_node_ref();
408 if (!raw) {
409 jffs2_free_xattr_ref(ref);
410 return -ENOMEM;
411 }
412
413 /* BEFORE jffs2_build_xattr_subsystem() called, 397 /* BEFORE jffs2_build_xattr_subsystem() called,
414 * ref->xid is used to store 32bit xid, xd is not used 398 * ref->xid is used to store 32bit xid, xd is not used
415 * ref->ino is used to store 32bit inode-number, ic is not used 399 * ref->ino is used to store 32bit inode-number, ic is not used
@@ -418,16 +402,13 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock
418 * used to chain all xattr_ref object. It's re-chained to 402 * used to chain all xattr_ref object. It's re-chained to
419 * jffs2_inode_cache in jffs2_build_xattr_subsystem() correctly. 403 * jffs2_inode_cache in jffs2_build_xattr_subsystem() correctly.
420 */ 404 */
421 ref->node = raw;
422 ref->ino = je32_to_cpu(rr->ino); 405 ref->ino = je32_to_cpu(rr->ino);
423 ref->xid = je32_to_cpu(rr->xid); 406 ref->xid = je32_to_cpu(rr->xid);
424 ref->next = c->xref_temp; 407 ref->next = c->xref_temp;
425 c->xref_temp = ref; 408 c->xref_temp = ref;
426 409
427 raw->flash_offset = ofs | REF_PRISTINE; 410 ref->node = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(rr->totlen)), NULL);
428 411 /* FIXME */ ref->node->next_in_ino = (void *)ref;
429 jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(rr->totlen)), NULL);
430 /* FIXME */ raw->next_in_ino = (void *)ref;
431 412
432 if (jffs2_sum_active()) 413 if (jffs2_sum_active())
433 jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset); 414 jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset);
@@ -597,6 +578,11 @@ scan_more:
597 578
598 jffs2_dbg_acct_paranoia_check_nolock(c, jeb); 579 jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
599 580
581 /* Make sure there are node refs available for use */
582 err = jffs2_prealloc_raw_node_refs(c, 2);
583 if (err)
584 return err;
585
600 cond_resched(); 586 cond_resched();
601 587
602 if (ofs & 3) { 588 if (ofs & 3) {
@@ -839,14 +825,7 @@ scan_more:
839 return err; 825 return err;
840 ofs += PAD(sizeof(struct jffs2_unknown_node)); 826 ofs += PAD(sizeof(struct jffs2_unknown_node));
841 } else { 827 } else {
842 struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref(); 828 jffs2_link_node_ref(c, jeb, ofs | REF_NORMAL, c->cleanmarker_size, NULL);
843 if (!marker_ref) {
844 printk(KERN_NOTICE "Failed to allocate node ref for clean marker\n");
845 return -ENOMEM;
846 }
847 marker_ref->flash_offset = ofs | REF_NORMAL;
848
849 jffs2_link_node_ref(c, jeb, marker_ref, c->cleanmarker_size, NULL);
850 829
851 ofs += PAD(c->cleanmarker_size); 830 ofs += PAD(c->cleanmarker_size);
852 } 831 }
@@ -884,14 +863,9 @@ scan_more:
884 break; 863 break;
885 864
886 case JFFS2_FEATURE_RWCOMPAT_COPY: { 865 case JFFS2_FEATURE_RWCOMPAT_COPY: {
887 struct jffs2_raw_node_ref *ref;
888 D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs)); 866 D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs));
889 867
890 ref = jffs2_alloc_raw_node_ref(); 868 jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(node->totlen)), NULL);
891 if (!ref)
892 return -ENOMEM;
893 ref->flash_offset = ofs | REF_PRISTINE;
894 jffs2_link_node_ref(c, jeb, ref, PAD(je32_to_cpu(node->totlen)), NULL);
895 869
896 /* We can't summarise nodes we don't grok */ 870 /* We can't summarise nodes we don't grok */
897 jffs2_sum_disable_collecting(s); 871 jffs2_sum_disable_collecting(s);
@@ -953,7 +927,6 @@ struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uin
953static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 927static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
954 struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s) 928 struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s)
955{ 929{
956 struct jffs2_raw_node_ref *raw;
957 struct jffs2_inode_cache *ic; 930 struct jffs2_inode_cache *ic;
958 uint32_t ino = je32_to_cpu(ri->ino); 931 uint32_t ino = je32_to_cpu(ri->ino);
959 int err; 932 int err;
@@ -969,12 +942,6 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
969 Which means that the _full_ amount of time to get to proper write mode with GC 942 Which means that the _full_ amount of time to get to proper write mode with GC
970 operational may actually be _longer_ than before. Sucks to be me. */ 943 operational may actually be _longer_ than before. Sucks to be me. */
971 944
972 raw = jffs2_alloc_raw_node_ref();
973 if (!raw) {
974 printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of node reference failed\n");
975 return -ENOMEM;
976 }
977
978 ic = jffs2_get_ino_cache(c, ino); 945 ic = jffs2_get_ino_cache(c, ino);
979 if (!ic) { 946 if (!ic) {
980 /* Inocache get failed. Either we read a bogus ino# or it's just genuinely the 947 /* Inocache get failed. Either we read a bogus ino# or it's just genuinely the
@@ -988,21 +955,15 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
988 /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */ 955 /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */
989 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(ri->totlen))))) 956 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(ri->totlen)))))
990 return err; 957 return err;
991 jffs2_free_raw_node_ref(raw);
992 return 0; 958 return 0;
993 } 959 }
994 ic = jffs2_scan_make_ino_cache(c, ino); 960 ic = jffs2_scan_make_ino_cache(c, ino);
995 if (!ic) { 961 if (!ic)
996 jffs2_free_raw_node_ref(raw);
997 return -ENOMEM; 962 return -ENOMEM;
998 }
999 } 963 }
1000 964
1001 /* Wheee. It worked */ 965 /* Wheee. It worked */
1002 966 jffs2_link_node_ref(c, jeb, ofs | REF_UNCHECKED, PAD(je32_to_cpu(ri->totlen)), ic);
1003 raw->flash_offset = ofs | REF_UNCHECKED;
1004
1005 jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(ri->totlen)), ic);
1006 967
1007 D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n", 968 D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n",
1008 je32_to_cpu(ri->ino), je32_to_cpu(ri->version), 969 je32_to_cpu(ri->ino), je32_to_cpu(ri->version),
@@ -1021,7 +982,6 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
1021static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 982static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
1022 struct jffs2_raw_dirent *rd, uint32_t ofs, struct jffs2_summary *s) 983 struct jffs2_raw_dirent *rd, uint32_t ofs, struct jffs2_summary *s)
1023{ 984{
1024 struct jffs2_raw_node_ref *raw;
1025 struct jffs2_full_dirent *fd; 985 struct jffs2_full_dirent *fd;
1026 struct jffs2_inode_cache *ic; 986 struct jffs2_inode_cache *ic;
1027 uint32_t crc; 987 uint32_t crc;
@@ -1063,23 +1023,14 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
1063 return err; 1023 return err;
1064 return 0; 1024 return 0;
1065 } 1025 }
1066 raw = jffs2_alloc_raw_node_ref();
1067 if (!raw) {
1068 jffs2_free_full_dirent(fd);
1069 printk(KERN_NOTICE "jffs2_scan_dirent_node(): allocation of node reference failed\n");
1070 return -ENOMEM;
1071 }
1072 ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(rd->pino)); 1026 ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(rd->pino));
1073 if (!ic) { 1027 if (!ic) {
1074 jffs2_free_full_dirent(fd); 1028 jffs2_free_full_dirent(fd);
1075 jffs2_free_raw_node_ref(raw);
1076 return -ENOMEM; 1029 return -ENOMEM;
1077 } 1030 }
1078 1031
1079 raw->flash_offset = ofs | REF_PRISTINE; 1032 fd->raw = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(rd->totlen)), ic);
1080 jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(rd->totlen)), ic);
1081 1033
1082 fd->raw = raw;
1083 fd->next = NULL; 1034 fd->next = NULL;
1084 fd->version = je32_to_cpu(rd->version); 1035 fd->version = je32_to_cpu(rd->version);
1085 fd->ino = je32_to_cpu(rd->ino); 1036 fd->ino = je32_to_cpu(rd->ino);
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index 351ba9f8185e..ccb6803a6e41 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -369,22 +369,18 @@ no_mem:
369 return -ENOMEM; 369 return -ENOMEM;
370} 370}
371 371
372static struct jffs2_raw_node_ref *alloc_ref_at(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 372static struct jffs2_raw_node_ref *sum_link_node_ref(struct jffs2_sb_info *c,
373 uint32_t offset) 373 struct jffs2_eraseblock *jeb,
374 uint32_t ofs, uint32_t len,
375 struct jffs2_inode_cache *ic)
374{ 376{
375 struct jffs2_raw_node_ref *ref;
376 /* If there was a gap, mark it dirty */ 377 /* If there was a gap, mark it dirty */
377 if (offset > c->sector_size - jeb->free_size) { 378 if ((ofs & ~3) > c->sector_size - jeb->free_size) {
378 int ret = jffs2_scan_dirty_space(c, jeb, offset - (c->sector_size - jeb->free_size)); 379 /* Ew. Summary doesn't actually tell us explicitly about dirty space */
379 if (ret) 380 jffs2_scan_dirty_space(c, jeb, (ofs & ~3) - (c->sector_size - jeb->free_size));
380 return NULL;
381 } 381 }
382 ref = jffs2_alloc_raw_node_ref();
383 if (!ref)
384 return NULL;
385 382
386 ref->flash_offset = jeb->offset + offset; 383 return jffs2_link_node_ref(c, jeb, jeb->offset + ofs, len, ic);
387 return ref;
388} 384}
389 385
390/* Process the stored summary information - helper function for jffs2_sum_scan_sumnode() */ 386/* Process the stored summary information - helper function for jffs2_sum_scan_sumnode() */
@@ -392,7 +388,6 @@ static struct jffs2_raw_node_ref *alloc_ref_at(struct jffs2_sb_info *c, struct j
392static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 388static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
393 struct jffs2_raw_summary *summary, uint32_t *pseudo_random) 389 struct jffs2_raw_summary *summary, uint32_t *pseudo_random)
394{ 390{
395 struct jffs2_raw_node_ref *raw;
396 struct jffs2_inode_cache *ic; 391 struct jffs2_inode_cache *ic;
397 struct jffs2_full_dirent *fd; 392 struct jffs2_full_dirent *fd;
398 void *sp; 393 void *sp;
@@ -404,6 +399,11 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
404 for (i=0; i<je32_to_cpu(summary->sum_num); i++) { 399 for (i=0; i<je32_to_cpu(summary->sum_num); i++) {
405 dbg_summary("processing summary index %d\n", i); 400 dbg_summary("processing summary index %d\n", i);
406 401
402 /* Make sure there's a spare ref for dirty space */
403 err = jffs2_prealloc_raw_node_refs(c, 2);
404 if (err)
405 return err;
406
407 switch (je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)) { 407 switch (je16_to_cpu(((struct jffs2_sum_unknown_flash *)sp)->nodetype)) {
408 case JFFS2_NODETYPE_INODE: { 408 case JFFS2_NODETYPE_INODE: {
409 struct jffs2_sum_inode_flash *spi; 409 struct jffs2_sum_inode_flash *spi;
@@ -415,22 +415,14 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
415 jeb->offset + je32_to_cpu(spi->offset), 415 jeb->offset + je32_to_cpu(spi->offset),
416 jeb->offset + je32_to_cpu(spi->offset) + je32_to_cpu(spu->totlen)); 416 jeb->offset + je32_to_cpu(spi->offset) + je32_to_cpu(spu->totlen));
417 417
418 raw = alloc_ref_at(c, jeb, je32_to_cpu(spi->offset));
419 if (!raw) {
420 JFFS2_NOTICE("allocation of node reference failed\n");
421 return -ENOMEM;
422 }
423
424 ic = jffs2_scan_make_ino_cache(c, ino); 418 ic = jffs2_scan_make_ino_cache(c, ino);
425 if (!ic) { 419 if (!ic) {
426 JFFS2_NOTICE("scan_make_ino_cache failed\n"); 420 JFFS2_NOTICE("scan_make_ino_cache failed\n");
427 jffs2_free_raw_node_ref(raw);
428 return -ENOMEM; 421 return -ENOMEM;
429 } 422 }
430 423
431 raw->flash_offset |= REF_UNCHECKED; 424 sum_link_node_ref(c, jeb, je32_to_cpu(spi->offset) | REF_UNCHECKED,
432 425 PAD(je32_to_cpu(spi->totlen)), ic);
433 jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spi->totlen)), ic);
434 426
435 *pseudo_random += je32_to_cpu(spi->version); 427 *pseudo_random += je32_to_cpu(spi->version);
436 428
@@ -455,24 +447,15 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
455 memcpy(&fd->name, spd->name, spd->nsize); 447 memcpy(&fd->name, spd->name, spd->nsize);
456 fd->name[spd->nsize] = 0; 448 fd->name[spd->nsize] = 0;
457 449
458 raw = alloc_ref_at(c, jeb, je32_to_cpu(spd->offset));
459 if (!raw) {
460 jffs2_free_full_dirent(fd);
461 JFFS2_NOTICE("allocation of node reference failed\n");
462 return -ENOMEM;
463 }
464
465 ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(spd->pino)); 450 ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(spd->pino));
466 if (!ic) { 451 if (!ic) {
467 jffs2_free_full_dirent(fd); 452 jffs2_free_full_dirent(fd);
468 jffs2_free_raw_node_ref(raw);
469 return -ENOMEM; 453 return -ENOMEM;
470 } 454 }
471 455
472 raw->flash_offset |= REF_PRISTINE; 456 fd->raw = sum_link_node_ref(c, jeb, je32_to_cpu(spd->offset) | REF_PRISTINE,
473 jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spd->totlen)), ic); 457 PAD(je32_to_cpu(spd->totlen)), ic);
474 458
475 fd->raw = raw;
476 fd->next = NULL; 459 fd->next = NULL;
477 fd->version = je32_to_cpu(spd->version); 460 fd->version = je32_to_cpu(spd->version);
478 fd->ino = je32_to_cpu(spd->ino); 461 fd->ino = je32_to_cpu(spd->ino);
@@ -497,15 +480,10 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
497 jeb->offset + je32_to_cpu(spx->offset), 480 jeb->offset + je32_to_cpu(spx->offset),
498 jeb->offset + je32_to_cpu(spx->offset) + je32_to_cpu(spx->totlen), 481 jeb->offset + je32_to_cpu(spx->offset) + je32_to_cpu(spx->totlen),
499 je32_to_cpu(spx->xid), je32_to_cpu(spx->version)); 482 je32_to_cpu(spx->xid), je32_to_cpu(spx->version));
500 raw = alloc_ref_at(c, jeb, je32_to_cpu(spx->offset)); 483
501 if (!raw) {
502 JFFS2_NOTICE("allocation of node reference failed\n");
503 return -ENOMEM;
504 }
505 xd = jffs2_setup_xattr_datum(c, je32_to_cpu(spx->xid), 484 xd = jffs2_setup_xattr_datum(c, je32_to_cpu(spx->xid),
506 je32_to_cpu(spx->version)); 485 je32_to_cpu(spx->version));
507 if (IS_ERR(xd)) { 486 if (IS_ERR(xd)) {
508 jffs2_free_raw_node_ref(raw);
509 if (PTR_ERR(xd) == -EEXIST) { 487 if (PTR_ERR(xd) == -EEXIST) {
510 /* a newer version of xd exists */ 488 /* a newer version of xd exists */
511 if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(spx->totlen)))) 489 if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(spx->totlen))))
@@ -516,12 +494,10 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
516 JFFS2_NOTICE("allocation of xattr_datum failed\n"); 494 JFFS2_NOTICE("allocation of xattr_datum failed\n");
517 return PTR_ERR(xd); 495 return PTR_ERR(xd);
518 } 496 }
519 xd->node = raw;
520 497
521 raw->flash_offset |= REF_UNCHECKED; 498 xd->node = sum_link_node_ref(c, jeb, je32_to_cpu(spx->offset) | REF_UNCHECKED,
522 499 PAD(je32_to_cpu(spx->totlen)), NULL);
523 jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(spx->totlen)), NULL); 500 /* FIXME */ xd->node->next_in_ino = (void *)xd;
524 /* FIXME */ raw->next_in_ino = (void *)xd;
525 501
526 *pseudo_random += je32_to_cpu(spx->xid); 502 *pseudo_random += je32_to_cpu(spx->xid);
527 sp += JFFS2_SUMMARY_XATTR_SIZE; 503 sp += JFFS2_SUMMARY_XATTR_SIZE;
@@ -537,29 +513,21 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
537 jeb->offset + je32_to_cpu(spr->offset), 513 jeb->offset + je32_to_cpu(spr->offset),
538 jeb->offset + je32_to_cpu(spr->offset) + PAD(sizeof(struct jffs2_raw_xref))); 514 jeb->offset + je32_to_cpu(spr->offset) + PAD(sizeof(struct jffs2_raw_xref)));
539 515
540 raw = alloc_ref_at(c, jeb, je32_to_cpu(spr->offset));
541 if (!raw) {
542 JFFS2_NOTICE("allocation of node reference failed\n");
543 return -ENOMEM;
544 }
545 ref = jffs2_alloc_xattr_ref(); 516 ref = jffs2_alloc_xattr_ref();
546 if (!ref) { 517 if (!ref) {
547 JFFS2_NOTICE("allocation of xattr_datum failed\n"); 518 JFFS2_NOTICE("allocation of xattr_datum failed\n");
548 jffs2_free_raw_node_ref(raw);
549 return -ENOMEM; 519 return -ENOMEM;
550 } 520 }
551 ref->ino = 0xfffffffe; 521 ref->ino = 0xfffffffe;
552 ref->xid = 0xfffffffd; 522 ref->xid = 0xfffffffd;
553 ref->node = raw;
554 ref->next = c->xref_temp; 523 ref->next = c->xref_temp;
555 c->xref_temp = ref; 524 c->xref_temp = ref;
556 525
557 raw->flash_offset |= REF_UNCHECKED; 526 ref->node = sum_link_node_ref(c, jeb, je32_to_cpu(spr->offset) | REF_UNCHECKED,
527 PAD(sizeof(struct jffs2_raw_xref)), NULL);
528 /* FIXME */ ref->node->next_in_ino = (void *)ref;
558 529
559 jffs2_link_node_ref(c, jeb, raw, PAD(sizeof(struct jffs2_raw_xref)), NULL); 530 *pseudo_random += ref->node->flash_offset;
560 /* FIXME */ raw->next_in_ino = (void *)ref;
561
562 *pseudo_random += raw->flash_offset;
563 sp += JFFS2_SUMMARY_XREF_SIZE; 531 sp += JFFS2_SUMMARY_XREF_SIZE;
564 532
565 break; 533 break;
@@ -584,7 +552,6 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
584 } 552 }
585 } 553 }
586 } 554 }
587
588 return 0; 555 return 0;
589} 556}
590 557
@@ -594,7 +561,6 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
594 uint32_t *pseudo_random) 561 uint32_t *pseudo_random)
595{ 562{
596 struct jffs2_unknown_node crcnode; 563 struct jffs2_unknown_node crcnode;
597 struct jffs2_raw_node_ref *cache_ref;
598 int ret, ofs; 564 int ret, ofs;
599 uint32_t crc; 565 uint32_t crc;
600 int err; 566 int err;
@@ -650,16 +616,8 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
650 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(summary->cln_mkr))))) 616 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(summary->cln_mkr)))))
651 return err; 617 return err;
652 } else { 618 } else {
653 struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref(); 619 jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL,
654 620 je32_to_cpu(summary->cln_mkr), NULL);
655 if (!marker_ref) {
656 JFFS2_NOTICE("Failed to allocate node ref for clean marker\n");
657 return -ENOMEM;
658 }
659
660 marker_ref->flash_offset = jeb->offset | REF_NORMAL;
661
662 jffs2_link_node_ref(c, jeb, marker_ref, je32_to_cpu(summary->cln_mkr), NULL);
663 } 621 }
664 } 622 }
665 623
@@ -672,16 +630,11 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
672 return ret; /* real error */ 630 return ret; /* real error */
673 631
674 /* for PARANOIA_CHECK */ 632 /* for PARANOIA_CHECK */
675 cache_ref = alloc_ref_at(c, jeb, ofs); 633 ret = jffs2_prealloc_raw_node_refs(c, 1);
676 634 if (ret)
677 if (!cache_ref) { 635 return ret;
678 JFFS2_NOTICE("Failed to allocate node ref for cache\n");
679 return -ENOMEM;
680 }
681
682 cache_ref->flash_offset |= REF_NORMAL;
683 636
684 jffs2_link_node_ref(c, jeb, cache_ref, sumsize, NULL); 637 jffs2_link_node_ref(c, jeb, (jeb->offset + ofs) | REF_NORMAL, sumsize, NULL);
685 638
686 if (unlikely(jeb->free_size)) { 639 if (unlikely(jeb->free_size)) {
687 JFFS2_WARNING("Free size 0x%x bytes in eraseblock @0x%08x with summary?\n", 640 JFFS2_WARNING("Free size 0x%x bytes in eraseblock @0x%08x with summary?\n",
@@ -709,6 +662,7 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
709 union jffs2_sum_mem *temp; 662 union jffs2_sum_mem *temp;
710 struct jffs2_sum_marker *sm; 663 struct jffs2_sum_marker *sm;
711 struct kvec vecs[2]; 664 struct kvec vecs[2];
665 uint32_t sum_ofs;
712 void *wpage; 666 void *wpage;
713 int ret; 667 int ret;
714 size_t retlen; 668 size_t retlen;
@@ -821,36 +775,31 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
821 vecs[1].iov_base = c->summary->sum_buf; 775 vecs[1].iov_base = c->summary->sum_buf;
822 vecs[1].iov_len = datasize; 776 vecs[1].iov_len = datasize;
823 777
778 sum_ofs = jeb->offset + c->sector_size - jeb->free_size;
779
824 dbg_summary("JFFS2: writing out data to flash to pos : 0x%08x\n", 780 dbg_summary("JFFS2: writing out data to flash to pos : 0x%08x\n",
825 jeb->offset + c->sector_size - jeb->free_size); 781 sum_ofs);
826 782
827 spin_unlock(&c->erase_completion_lock); 783 ret = jffs2_flash_writev(c, vecs, 2, sum_ofs, &retlen, 0);
828 ret = jffs2_flash_writev(c, vecs, 2, jeb->offset + c->sector_size -
829 jeb->free_size, &retlen, 0);
830 784
831 if (ret || (retlen != infosize)) { 785 if (ret || (retlen != infosize)) {
832 struct jffs2_raw_node_ref *ref;
833 786
834 JFFS2_WARNING("Write of %u bytes at 0x%08x failed. returned %d, retlen %zd\n", 787 JFFS2_WARNING("Write of %u bytes at 0x%08x failed. returned %d, retlen %zd\n",
835 infosize, jeb->offset + c->sector_size - jeb->free_size, ret, retlen); 788 infosize, sum_ofs, ret, retlen);
836 789
837 /* Waste remaining space */ 790 /* Waste remaining space */
838 ref = jffs2_alloc_raw_node_ref(); 791 spin_lock(&c->erase_completion_lock);
839 if (ref) { 792 jffs2_link_node_ref(c, jeb, sum_ofs | REF_OBSOLETE, infosize, NULL);
840 spin_lock(&c->erase_completion_lock); 793 spin_unlock(&c->erase_completion_lock);
841
842 ref->flash_offset = jeb->offset + c->sector_size - jeb->free_size;
843 ref->flash_offset |= REF_OBSOLETE;
844
845 jffs2_link_node_ref(c, jeb, ref, c->sector_size - jeb->free_size, NULL);
846 }
847 794
848 c->summary->sum_size = JFFS2_SUMMARY_NOSUM_SIZE; 795 c->summary->sum_size = JFFS2_SUMMARY_NOSUM_SIZE;
849 796
850 return 1; 797 return 0;
851 } 798 }
852 799
853 spin_lock(&c->erase_completion_lock); 800 spin_lock(&c->erase_completion_lock);
801 jffs2_link_node_ref(c, jeb, sum_ofs | REF_NORMAL, infosize, NULL);
802 spin_unlock(&c->erase_completion_lock);
854 803
855 return 0; 804 return 0;
856} 805}
@@ -859,12 +808,15 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
859 808
860int jffs2_sum_write_sumnode(struct jffs2_sb_info *c) 809int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
861{ 810{
862 struct jffs2_raw_node_ref *summary_ref; 811 int datasize, infosize, padsize;
863 int datasize, infosize, padsize, ret;
864 struct jffs2_eraseblock *jeb; 812 struct jffs2_eraseblock *jeb;
813 int ret;
865 814
866 dbg_summary("called\n"); 815 dbg_summary("called\n");
867 816
817 spin_unlock(&c->erase_completion_lock);
818 jffs2_prealloc_raw_node_refs(c, 1);
819
868 jeb = c->nextblock; 820 jeb = c->nextblock;
869 821
870 if (!c->summary->sum_num || !c->summary->sum_list_head) { 822 if (!c->summary->sum_num || !c->summary->sum_list_head) {
@@ -888,22 +840,6 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
888 } 840 }
889 841
890 ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize); 842 ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize);
891 if (ret)
892 return 0; /* can't write out summary, block is marked as NOSUM_SIZE */
893
894 /* for ACCT_PARANOIA_CHECK */
895 spin_unlock(&c->erase_completion_lock);
896 summary_ref = jffs2_alloc_raw_node_ref();
897
898 if (!summary_ref) {
899 JFFS2_NOTICE("Failed to allocate node ref for summary\n");
900 return -ENOMEM;
901 }
902
903 summary_ref->flash_offset = (jeb->offset + c->sector_size - jeb->free_size) | REF_NORMAL;
904
905 spin_lock(&c->erase_completion_lock); 843 spin_lock(&c->erase_completion_lock);
906 jffs2_link_node_ref(c, jeb, summary_ref, infosize, NULL); 844 return ret;
907
908 return 0;
909} 845}
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 916c87d3393b..0d7abb260489 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -179,6 +179,9 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
179 unsigned char *buf; 179 unsigned char *buf;
180 uint32_t start, end, ofs, len; 180 uint32_t start, end, ofs, len;
181 181
182 if (jffs2_prealloc_raw_node_refs(c, c->reserved_refs + 1))
183 return;
184
182 spin_lock(&c->erase_completion_lock); 185 spin_lock(&c->erase_completion_lock);
183 186
184 jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; 187 jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
@@ -306,17 +309,9 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
306 printk(KERN_CRIT "Recovery of wbuf failed due to a second write error\n"); 309 printk(KERN_CRIT "Recovery of wbuf failed due to a second write error\n");
307 kfree(buf); 310 kfree(buf);
308 311
309 if (retlen) { 312 if (retlen)
310 struct jffs2_raw_node_ref *raw2; 313 jffs2_add_physical_node_ref(c, ofs | REF_OBSOLETE, ref_totlen(c, jeb, *first_raw), NULL);
311
312 raw2 = jffs2_alloc_raw_node_ref();
313 if (!raw2)
314 return;
315
316 raw2->flash_offset = ofs | REF_OBSOLETE;
317 314
318 jffs2_add_physical_node_ref(c, raw2, ref_totlen(c, jeb, *first_raw), NULL);
319 }
320 return; 315 return;
321 } 316 }
322 printk(KERN_NOTICE "Recovery of wbuf succeeded to %08x\n", ofs); 317 printk(KERN_NOTICE "Recovery of wbuf succeeded to %08x\n", ofs);
@@ -428,6 +423,9 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
428 if (!c->wbuf_len) /* already checked c->wbuf above */ 423 if (!c->wbuf_len) /* already checked c->wbuf above */
429 return 0; 424 return 0;
430 425
426 if (jffs2_prealloc_raw_node_refs(c, c->reserved_refs + 1))
427 return -ENOMEM;
428
431 /* claim remaining space on the page 429 /* claim remaining space on the page
432 this happens, if we have a change to a new block, 430 this happens, if we have a change to a new block,
433 or if fsync forces us to flush the writebuffer. 431 or if fsync forces us to flush the writebuffer.
@@ -485,7 +483,6 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
485 /* Adjust free size of the block if we padded. */ 483 /* Adjust free size of the block if we padded. */
486 if (pad) { 484 if (pad) {
487 struct jffs2_eraseblock *jeb; 485 struct jffs2_eraseblock *jeb;
488 struct jffs2_raw_node_ref *ref;
489 uint32_t waste = c->wbuf_pagesize - c->wbuf_len; 486 uint32_t waste = c->wbuf_pagesize - c->wbuf_len;
490 487
491 jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; 488 jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
@@ -503,15 +500,10 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
503 jeb->offset, jeb->free_size); 500 jeb->offset, jeb->free_size);
504 BUG(); 501 BUG();
505 } 502 }
506 ref = jffs2_alloc_raw_node_ref();
507 if (!ref)
508 return -ENOMEM;
509 ref->flash_offset = c->wbuf_ofs + c->wbuf_len;
510 ref->flash_offset |= REF_OBSOLETE;
511 503
512 spin_lock(&c->erase_completion_lock); 504 spin_lock(&c->erase_completion_lock);
513 505
514 jffs2_link_node_ref(c, jeb, ref, waste, NULL); 506 jffs2_link_node_ref(c, jeb, (c->wbuf_ofs + c->wbuf_len) | REF_OBSOLETE, waste, NULL);
515 /* FIXME: that made it count as dirty. Convert to wasted */ 507 /* FIXME: that made it count as dirty. Convert to wasted */
516 jeb->dirty_size -= waste; 508 jeb->dirty_size -= waste;
517 c->dirty_size -= waste; 509 c->dirty_size -= waste;
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index 0e12b7561b71..67176792e138 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -61,7 +61,6 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
61 uint32_t datalen, int alloc_mode) 61 uint32_t datalen, int alloc_mode)
62 62
63{ 63{
64 struct jffs2_raw_node_ref *raw;
65 struct jffs2_full_dnode *fn; 64 struct jffs2_full_dnode *fn;
66 size_t retlen; 65 size_t retlen;
67 uint32_t flash_ofs; 66 uint32_t flash_ofs;
@@ -83,27 +82,16 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
83 if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) { 82 if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) {
84 printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen); 83 printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen);
85 } 84 }
86 raw = jffs2_alloc_raw_node_ref();
87 if (!raw)
88 return ERR_PTR(-ENOMEM);
89 85
90 fn = jffs2_alloc_full_dnode(); 86 fn = jffs2_alloc_full_dnode();
91 if (!fn) { 87 if (!fn)
92 jffs2_free_raw_node_ref(raw);
93 return ERR_PTR(-ENOMEM); 88 return ERR_PTR(-ENOMEM);
94 }
95
96 fn->ofs = je32_to_cpu(ri->offset);
97 fn->size = je32_to_cpu(ri->dsize);
98 fn->frags = 0;
99 89
100 /* check number of valid vecs */ 90 /* check number of valid vecs */
101 if (!datalen || !data) 91 if (!datalen || !data)
102 cnt = 1; 92 cnt = 1;
103 retry: 93 retry:
104 fn->raw = raw; 94 flash_ofs = write_ofs(c);
105
106 raw->flash_offset = flash_ofs = write_ofs(c);
107 95
108 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len); 96 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
109 97
@@ -130,14 +118,11 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
130 seem corrupted, in which case the scan would skip over 118 seem corrupted, in which case the scan would skip over
131 any node we write before the original intended end of 119 any node we write before the original intended end of
132 this node */ 120 this node */
133 raw->flash_offset |= REF_OBSOLETE; 121 jffs2_add_physical_node_ref(c, flash_ofs | REF_OBSOLETE, PAD(sizeof(*ri)+datalen), NULL);
134 jffs2_add_physical_node_ref(c, raw, PAD(sizeof(*ri)+datalen), NULL);
135 jffs2_mark_node_obsolete(c, raw);
136 } else { 122 } else {
137 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset); 123 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", flash_ofs);
138 jffs2_free_raw_node_ref(raw);
139 } 124 }
140 if (!retried && alloc_mode != ALLOC_NORETRY && (raw = jffs2_alloc_raw_node_ref())) { 125 if (!retried && alloc_mode != ALLOC_NORETRY) {
141 /* Try to reallocate space and retry */ 126 /* Try to reallocate space and retry */
142 uint32_t dummy; 127 uint32_t dummy;
143 struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size]; 128 struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size];
@@ -172,7 +157,6 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
172 goto retry; 157 goto retry;
173 } 158 }
174 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); 159 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
175 jffs2_free_raw_node_ref(raw);
176 } 160 }
177 /* Release the full_dnode which is now useless, and return */ 161 /* Release the full_dnode which is now useless, and return */
178 jffs2_free_full_dnode(fn); 162 jffs2_free_full_dnode(fn);
@@ -186,14 +170,17 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
186 if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) || 170 if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) ||
187 ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) && 171 ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) &&
188 (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) == je32_to_cpu(ri->isize)))) { 172 (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) == je32_to_cpu(ri->isize)))) {
189 raw->flash_offset |= REF_PRISTINE; 173 flash_ofs |= REF_PRISTINE;
190 } else { 174 } else {
191 raw->flash_offset |= REF_NORMAL; 175 flash_ofs |= REF_NORMAL;
192 } 176 }
193 jffs2_add_physical_node_ref(c, raw, PAD(sizeof(*ri)+datalen), f->inocache); 177 fn->raw = jffs2_add_physical_node_ref(c, flash_ofs, PAD(sizeof(*ri)+datalen), f->inocache);
178 fn->ofs = je32_to_cpu(ri->offset);
179 fn->size = je32_to_cpu(ri->dsize);
180 fn->frags = 0;
194 181
195 D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n", 182 D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n",
196 flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize), 183 flash_ofs & ~3, flash_ofs & 3, je32_to_cpu(ri->dsize),
197 je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc), 184 je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc),
198 je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen))); 185 je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen)));
199 186
@@ -208,11 +195,10 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
208 struct jffs2_raw_dirent *rd, const unsigned char *name, 195 struct jffs2_raw_dirent *rd, const unsigned char *name,
209 uint32_t namelen, int alloc_mode) 196 uint32_t namelen, int alloc_mode)
210{ 197{
211 struct jffs2_raw_node_ref *raw;
212 struct jffs2_full_dirent *fd; 198 struct jffs2_full_dirent *fd;
213 size_t retlen; 199 size_t retlen;
214 struct kvec vecs[2]; 200 struct kvec vecs[2];
215 uint32_t flash_ofs = write_ofs(c); 201 uint32_t flash_ofs;
216 int retried = 0; 202 int retried = 0;
217 int ret; 203 int ret;
218 204
@@ -223,26 +209,16 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
223 D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) { 209 D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) {
224 printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n"); 210 printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n");
225 BUG(); 211 BUG();
226 } 212 });
227 );
228 213
229 vecs[0].iov_base = rd; 214 vecs[0].iov_base = rd;
230 vecs[0].iov_len = sizeof(*rd); 215 vecs[0].iov_len = sizeof(*rd);
231 vecs[1].iov_base = (unsigned char *)name; 216 vecs[1].iov_base = (unsigned char *)name;
232 vecs[1].iov_len = namelen; 217 vecs[1].iov_len = namelen;
233 218
234 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
235
236 raw = jffs2_alloc_raw_node_ref();
237
238 if (!raw)
239 return ERR_PTR(-ENOMEM);
240
241 fd = jffs2_alloc_full_dirent(namelen+1); 219 fd = jffs2_alloc_full_dirent(namelen+1);
242 if (!fd) { 220 if (!fd)
243 jffs2_free_raw_node_ref(raw);
244 return ERR_PTR(-ENOMEM); 221 return ERR_PTR(-ENOMEM);
245 }
246 222
247 fd->version = je32_to_cpu(rd->version); 223 fd->version = je32_to_cpu(rd->version);
248 fd->ino = je32_to_cpu(rd->ino); 224 fd->ino = je32_to_cpu(rd->ino);
@@ -252,9 +228,9 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
252 fd->name[namelen]=0; 228 fd->name[namelen]=0;
253 229
254 retry: 230 retry:
255 fd->raw = raw; 231 flash_ofs = write_ofs(c);
256 232
257 raw->flash_offset = flash_ofs; 233 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
258 234
259 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(rd->version) < f->highest_version)) { 235 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(rd->version) < f->highest_version)) {
260 BUG_ON(!retried); 236 BUG_ON(!retried);
@@ -273,14 +249,11 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
273 sizeof(*rd)+namelen, flash_ofs, ret, retlen); 249 sizeof(*rd)+namelen, flash_ofs, ret, retlen);
274 /* Mark the space as dirtied */ 250 /* Mark the space as dirtied */
275 if (retlen) { 251 if (retlen) {
276 raw->flash_offset |= REF_OBSOLETE; 252 jffs2_add_physical_node_ref(c, flash_ofs | REF_OBSOLETE, PAD(sizeof(*rd)+namelen), NULL);
277 jffs2_add_physical_node_ref(c, raw, PAD(sizeof(*rd)+namelen), NULL);
278 jffs2_mark_node_obsolete(c, raw);
279 } else { 253 } else {
280 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset); 254 printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", flash_ofs);
281 jffs2_free_raw_node_ref(raw);
282 } 255 }
283 if (!retried && (raw = jffs2_alloc_raw_node_ref())) { 256 if (!retried) {
284 /* Try to reallocate space and retry */ 257 /* Try to reallocate space and retry */
285 uint32_t dummy; 258 uint32_t dummy;
286 struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size]; 259 struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size];
@@ -313,15 +286,13 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
313 goto retry; 286 goto retry;
314 } 287 }
315 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); 288 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
316 jffs2_free_raw_node_ref(raw);
317 } 289 }
318 /* Release the full_dnode which is now useless, and return */ 290 /* Release the full_dnode which is now useless, and return */
319 jffs2_free_full_dirent(fd); 291 jffs2_free_full_dirent(fd);
320 return ERR_PTR(ret?ret:-EIO); 292 return ERR_PTR(ret?ret:-EIO);
321 } 293 }
322 /* Mark the space used */ 294 /* Mark the space used */
323 raw->flash_offset |= REF_PRISTINE; 295 fd->raw = jffs2_add_physical_node_ref(c, flash_ofs | REF_PRISTINE, PAD(sizeof(*rd)+namelen), f->inocache);
324 jffs2_add_physical_node_ref(c, raw, PAD(sizeof(*rd)+namelen), f->inocache);
325 296
326 if (retried) { 297 if (retried) {
327 jffs2_dbg_acct_sanity_check(c,NULL); 298 jffs2_dbg_acct_sanity_check(c,NULL);
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c
index 008f91b1c171..2255f1367bd5 100644
--- a/fs/jffs2/xattr.c
+++ b/fs/jffs2/xattr.c
@@ -304,8 +304,8 @@ static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x
304static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) 304static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
305{ 305{
306 /* must be called under down_write(xattr_sem) */ 306 /* must be called under down_write(xattr_sem) */
307 struct jffs2_raw_xattr rx;
308 struct jffs2_raw_node_ref *raw; 307 struct jffs2_raw_node_ref *raw;
308 struct jffs2_raw_xattr rx;
309 struct kvec vecs[2]; 309 struct kvec vecs[2];
310 uint32_t length; 310 uint32_t length;
311 int rc, totlen; 311 int rc, totlen;
@@ -319,11 +319,6 @@ static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x
319 vecs[1].iov_len = xd->name_len + 1 + xd->value_len; 319 vecs[1].iov_len = xd->name_len + 1 + xd->value_len;
320 totlen = vecs[0].iov_len + vecs[1].iov_len; 320 totlen = vecs[0].iov_len + vecs[1].iov_len;
321 321
322 raw = jffs2_alloc_raw_node_ref();
323 if (!raw)
324 return -ENOMEM;
325 raw->flash_offset = phys_ofs;
326
327 /* Setup raw-xattr */ 322 /* Setup raw-xattr */
328 rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 323 rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
329 rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR); 324 rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR);
@@ -343,19 +338,14 @@ static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x
343 JFFS2_WARNING("jffs2_flash_writev()=%d, req=%u, wrote=%u, at %#08x\n", 338 JFFS2_WARNING("jffs2_flash_writev()=%d, req=%u, wrote=%u, at %#08x\n",
344 rc, totlen, length, phys_ofs); 339 rc, totlen, length, phys_ofs);
345 rc = rc ? rc : -EIO; 340 rc = rc ? rc : -EIO;
346 if (length) { 341 if (length)
347 raw->flash_offset |= REF_OBSOLETE; 342 jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(totlen), NULL);
348 jffs2_add_physical_node_ref(c, raw, PAD(totlen), NULL); 343
349 jffs2_mark_node_obsolete(c, raw);
350 } else {
351 jffs2_free_raw_node_ref(raw);
352 }
353 return rc; 344 return rc;
354 } 345 }
355 346
356 /* success */ 347 /* success */
357 raw->flash_offset |= REF_PRISTINE; 348 raw = jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(totlen), NULL);
358 jffs2_add_physical_node_ref(c, raw, PAD(totlen), NULL);
359 /* FIXME */ raw->next_in_ino = (void *)xd; 349 /* FIXME */ raw->next_in_ino = (void *)xd;
360 350
361 if (xd->node) 351 if (xd->node)
@@ -563,11 +553,6 @@ static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
563 uint32_t phys_ofs = write_ofs(c); 553 uint32_t phys_ofs = write_ofs(c);
564 int ret; 554 int ret;
565 555
566 raw = jffs2_alloc_raw_node_ref();
567 if (!raw)
568 return -ENOMEM;
569 raw->flash_offset = phys_ofs;
570
571 rr.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 556 rr.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
572 rr.nodetype = cpu_to_je16(JFFS2_NODETYPE_XREF); 557 rr.nodetype = cpu_to_je16(JFFS2_NODETYPE_XREF);
573 rr.totlen = cpu_to_je32(PAD(sizeof(rr))); 558 rr.totlen = cpu_to_je32(PAD(sizeof(rr)));
@@ -582,18 +567,13 @@ static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
582 JFFS2_WARNING("jffs2_flash_write() returned %d, request=%u, retlen=%u, at %#08x\n", 567 JFFS2_WARNING("jffs2_flash_write() returned %d, request=%u, retlen=%u, at %#08x\n",
583 ret, sizeof(rr), length, phys_ofs); 568 ret, sizeof(rr), length, phys_ofs);
584 ret = ret ? ret : -EIO; 569 ret = ret ? ret : -EIO;
585 if (length) { 570 if (length)
586 raw->flash_offset |= REF_OBSOLETE; 571 jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, PAD(sizeof(rr)), NULL);
587 jffs2_add_physical_node_ref(c, raw, PAD(sizeof(rr)), NULL); 572
588 jffs2_mark_node_obsolete(c, raw);
589 } else {
590 jffs2_free_raw_node_ref(raw);
591 }
592 return ret; 573 return ret;
593 } 574 }
594 raw->flash_offset |= REF_PRISTINE;
595 575
596 jffs2_add_physical_node_ref(c, raw, PAD(sizeof(rr)), NULL); 576 raw = jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(sizeof(rr)), NULL);
597 /* FIXME */ raw->next_in_ino = (void *)ref; 577 /* FIXME */ raw->next_in_ino = (void *)ref;
598 if (ref->node) 578 if (ref->node)
599 delete_xattr_ref_node(c, ref); 579 delete_xattr_ref_node(c, ref);