[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>
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
index d25d491..1e6eabd 100644
--- a/fs/jffs2/nodelist.c
+++ b/fs/jffs2/nodelist.c
@@ -953,13 +953,19 @@
 
 	for (i=0; i<c->nr_blocks; i++) {
 		this = c->blocks[i].first_node;
-		while(this) {
+		while (this) {
 			next = this->next_phys;
-			jffs2_free_raw_node_ref(this);
+			__jffs2_free_raw_node_ref(this);
 			this = next;
 		}
 		c->blocks[i].first_node = c->blocks[i].last_node = NULL;
 	}
+	this = c->refs;
+	while (this) {
+		next = this->next_in_ino;
+		__jffs2_free_raw_node_ref(this);
+		this = next;
+	}
 }
 
 struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset)
@@ -1047,10 +1053,27 @@
 	}
 }
 
-void jffs2_link_node_ref(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-			 struct jffs2_raw_node_ref *ref, uint32_t len,
-			 struct jffs2_inode_cache *ic)
+struct jffs2_raw_node_ref *jffs2_link_node_ref(struct jffs2_sb_info *c,
+					       struct jffs2_eraseblock *jeb,
+					       uint32_t ofs, uint32_t len,
+					       struct jffs2_inode_cache *ic)
 {
+	struct jffs2_raw_node_ref *ref;
+
+	/* These will be preallocated _very_ shortly. */
+	ref = c->refs;
+	if (!c->refs) {
+		JFFS2_WARNING("Using non-preallocated refs!\n");
+		ref = __jffs2_alloc_raw_node_ref();
+		BUG_ON(!ref);
+		WARN_ON(1);
+	} else {
+		c->refs = ref->next_in_ino;
+	}
+
+	ref->next_phys = NULL;
+	ref->flash_offset = ofs;
+
 	if (!jeb->first_node)
 		jeb->first_node = ref;
 	if (jeb->last_node) {
@@ -1093,15 +1116,15 @@
 	c->free_size -= len;
 	jeb->free_size -= len;
 
-	ref->next_phys = NULL;
 #ifdef TEST_TOTLEN
 	/* Set (and test) __totlen field... for now */
 	ref->__totlen = len;
 	ref_totlen(c, jeb, ref);
 #endif
+	return ref;
 }
 
-/* No locking. Do not use on a live file system */
+/* No locking, no reservation of 'ref'. Do not use on a live file system */
 int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
 			   uint32_t size)
 {
@@ -1121,18 +1144,10 @@
 		jeb->dirty_size += size;
 		jeb->free_size -= size;
 	} else {
-		struct jffs2_raw_node_ref *ref;
-		ref = jffs2_alloc_raw_node_ref();
-		if (!ref)
-			return -ENOMEM;
+		uint32_t ofs = jeb->offset + c->sector_size - jeb->free_size;
+		ofs |= REF_OBSOLETE;
 
-		ref->flash_offset = jeb->offset + c->sector_size - jeb->free_size;
-		ref->flash_offset |= REF_OBSOLETE;
-#ifdef TEST_TOTLEN
-		ref->__totlen = size;
-#endif
-
-		jffs2_link_node_ref(c, jeb, ref, size, NULL);
+		jffs2_link_node_ref(c, jeb, ofs, size, NULL);
 	}
 
 	return 0;