xref: /openbmc/linux/fs/jffs2/readinode.c (revision 14c6381e)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * JFFS2 -- Journalling Flash File System, Version 2.
31da177e4SLinus Torvalds  *
4c00c310eSDavid Woodhouse  * Copyright © 2001-2007 Red Hat, Inc.
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  * Created by David Woodhouse <dwmw2@infradead.org>
71da177e4SLinus Torvalds  *
81da177e4SLinus Torvalds  * For licensing information, see the file 'LICENCE' in this directory.
91da177e4SLinus Torvalds  *
101da177e4SLinus Torvalds  */
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds #include <linux/kernel.h>
13737b7661SAndrew Lunn #include <linux/sched.h>
141da177e4SLinus Torvalds #include <linux/slab.h>
151da177e4SLinus Torvalds #include <linux/fs.h>
161da177e4SLinus Torvalds #include <linux/crc32.h>
171da177e4SLinus Torvalds #include <linux/pagemap.h>
181da177e4SLinus Torvalds #include <linux/mtd/mtd.h>
191da177e4SLinus Torvalds #include <linux/compiler.h>
201da177e4SLinus Torvalds #include "nodelist.h"
211da177e4SLinus Torvalds 
22f97117d1SArtem B. Bityutskiy /*
23df8e96f3SDavid Woodhouse  * Check the data CRC of the node.
24df8e96f3SDavid Woodhouse  *
25df8e96f3SDavid Woodhouse  * Returns: 0 if the data CRC is correct;
26df8e96f3SDavid Woodhouse  * 	    1 - if incorrect;
27df8e96f3SDavid Woodhouse  *	    error code if an error occured.
28f97117d1SArtem B. Bityutskiy  */
29df8e96f3SDavid Woodhouse static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn)
301da177e4SLinus Torvalds {
31df8e96f3SDavid Woodhouse 	struct jffs2_raw_node_ref *ref = tn->fn->raw;
32df8e96f3SDavid Woodhouse 	int err = 0, pointed = 0;
33df8e96f3SDavid Woodhouse 	struct jffs2_eraseblock *jeb;
34df8e96f3SDavid Woodhouse 	unsigned char *buffer;
35df8e96f3SDavid Woodhouse 	uint32_t crc, ofs, len;
36df8e96f3SDavid Woodhouse 	size_t retlen;
371da177e4SLinus Torvalds 
38df8e96f3SDavid Woodhouse 	BUG_ON(tn->csize == 0);
391da177e4SLinus Torvalds 
40df8e96f3SDavid Woodhouse 	if (!jffs2_is_writebuffered(c))
41df8e96f3SDavid Woodhouse 		goto adj_acc;
42df8e96f3SDavid Woodhouse 
43df8e96f3SDavid Woodhouse 	/* Calculate how many bytes were already checked */
44df8e96f3SDavid Woodhouse 	ofs = ref_offset(ref) + sizeof(struct jffs2_raw_inode);
45df8e96f3SDavid Woodhouse 	len = ofs % c->wbuf_pagesize;
46df8e96f3SDavid Woodhouse 	if (likely(len))
47df8e96f3SDavid Woodhouse 		len = c->wbuf_pagesize - len;
48df8e96f3SDavid Woodhouse 
49df8e96f3SDavid Woodhouse 	if (len >= tn->csize) {
50df8e96f3SDavid Woodhouse 		dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n",
51df8e96f3SDavid Woodhouse 			ref_offset(ref), tn->csize, ofs);
52df8e96f3SDavid Woodhouse 		goto adj_acc;
53f97117d1SArtem B. Bityutskiy 	}
541da177e4SLinus Torvalds 
55df8e96f3SDavid Woodhouse 	ofs += len;
56df8e96f3SDavid Woodhouse 	len = tn->csize - len;
57df8e96f3SDavid Woodhouse 
58df8e96f3SDavid Woodhouse 	dbg_readinode("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes.\n",
59df8e96f3SDavid Woodhouse 		ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len);
60df8e96f3SDavid Woodhouse 
61df8e96f3SDavid Woodhouse #ifndef __ECOS
62df8e96f3SDavid Woodhouse 	/* TODO: instead, incapsulate point() stuff to jffs2_flash_read(),
63df8e96f3SDavid Woodhouse 	 * adding and jffs2_flash_read_end() interface. */
64df8e96f3SDavid Woodhouse 	if (c->mtd->point) {
65df8e96f3SDavid Woodhouse 		err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer);
66df8e96f3SDavid Woodhouse 		if (!err && retlen < tn->csize) {
67df8e96f3SDavid Woodhouse 			JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize);
68df8e96f3SDavid Woodhouse 			c->mtd->unpoint(c->mtd, buffer, ofs, len);
69df8e96f3SDavid Woodhouse 		} else if (err)
70df8e96f3SDavid Woodhouse 			JFFS2_WARNING("MTD point failed: error code %d.\n", err);
71df8e96f3SDavid Woodhouse 		else
72df8e96f3SDavid Woodhouse 			pointed = 1; /* succefully pointed to device */
73df8e96f3SDavid Woodhouse 	}
74df8e96f3SDavid Woodhouse #endif
75df8e96f3SDavid Woodhouse 
76df8e96f3SDavid Woodhouse 	if (!pointed) {
77df8e96f3SDavid Woodhouse 		buffer = kmalloc(len, GFP_KERNEL);
78df8e96f3SDavid Woodhouse 		if (unlikely(!buffer))
79df8e96f3SDavid Woodhouse 			return -ENOMEM;
80df8e96f3SDavid Woodhouse 
81df8e96f3SDavid Woodhouse 		/* TODO: this is very frequent pattern, make it a separate
82df8e96f3SDavid Woodhouse 		 * routine */
83df8e96f3SDavid Woodhouse 		err = jffs2_flash_read(c, ofs, len, &retlen, buffer);
84df8e96f3SDavid Woodhouse 		if (err) {
85df8e96f3SDavid Woodhouse 			JFFS2_ERROR("can not read %d bytes from 0x%08x, error code: %d.\n", len, ofs, err);
86df8e96f3SDavid Woodhouse 			goto free_out;
87df8e96f3SDavid Woodhouse 		}
88df8e96f3SDavid Woodhouse 
89df8e96f3SDavid Woodhouse 		if (retlen != len) {
90df8e96f3SDavid Woodhouse 			JFFS2_ERROR("short read at %#08x: %zd instead of %d.\n", ofs, retlen, len);
91df8e96f3SDavid Woodhouse 			err = -EIO;
92df8e96f3SDavid Woodhouse 			goto free_out;
93df8e96f3SDavid Woodhouse 		}
94df8e96f3SDavid Woodhouse 	}
95df8e96f3SDavid Woodhouse 
96df8e96f3SDavid Woodhouse 	/* Continue calculating CRC */
97df8e96f3SDavid Woodhouse 	crc = crc32(tn->partial_crc, buffer, len);
98df8e96f3SDavid Woodhouse 	if(!pointed)
99df8e96f3SDavid Woodhouse 		kfree(buffer);
100df8e96f3SDavid Woodhouse #ifndef __ECOS
101df8e96f3SDavid Woodhouse 	else
102df8e96f3SDavid Woodhouse 		c->mtd->unpoint(c->mtd, buffer, ofs, len);
103df8e96f3SDavid Woodhouse #endif
104df8e96f3SDavid Woodhouse 
105df8e96f3SDavid Woodhouse 	if (crc != tn->data_crc) {
106df8e96f3SDavid Woodhouse 		JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n",
107df8e96f3SDavid Woodhouse 			ofs, tn->data_crc, crc);
108df8e96f3SDavid Woodhouse 		return 1;
109df8e96f3SDavid Woodhouse 	}
110df8e96f3SDavid Woodhouse 
111df8e96f3SDavid Woodhouse adj_acc:
112df8e96f3SDavid Woodhouse 	jeb = &c->blocks[ref->flash_offset / c->sector_size];
113df8e96f3SDavid Woodhouse 	len = ref_totlen(c, jeb, ref);
114df8e96f3SDavid Woodhouse 	/* If it should be REF_NORMAL, it'll get marked as such when
115df8e96f3SDavid Woodhouse 	   we build the fragtree, shortly. No need to worry about GC
116df8e96f3SDavid Woodhouse 	   moving it while it's marked REF_PRISTINE -- GC won't happen
117df8e96f3SDavid Woodhouse 	   till we've finished checking every inode anyway. */
118df8e96f3SDavid Woodhouse 	ref->flash_offset |= REF_PRISTINE;
119df8e96f3SDavid Woodhouse 	/*
120df8e96f3SDavid Woodhouse 	 * Mark the node as having been checked and fix the
121df8e96f3SDavid Woodhouse 	 * accounting accordingly.
122df8e96f3SDavid Woodhouse 	 */
123df8e96f3SDavid Woodhouse 	spin_lock(&c->erase_completion_lock);
124df8e96f3SDavid Woodhouse 	jeb->used_size += len;
125df8e96f3SDavid Woodhouse 	jeb->unchecked_size -= len;
126df8e96f3SDavid Woodhouse 	c->used_size += len;
127df8e96f3SDavid Woodhouse 	c->unchecked_size -= len;
128df8e96f3SDavid Woodhouse 	jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
129df8e96f3SDavid Woodhouse 	spin_unlock(&c->erase_completion_lock);
130df8e96f3SDavid Woodhouse 
131df8e96f3SDavid Woodhouse 	return 0;
132df8e96f3SDavid Woodhouse 
133df8e96f3SDavid Woodhouse free_out:
134df8e96f3SDavid Woodhouse 	if(!pointed)
135df8e96f3SDavid Woodhouse 		kfree(buffer);
136df8e96f3SDavid Woodhouse #ifndef __ECOS
137df8e96f3SDavid Woodhouse 	else
138df8e96f3SDavid Woodhouse 		c->mtd->unpoint(c->mtd, buffer, ofs, len);
139df8e96f3SDavid Woodhouse #endif
140df8e96f3SDavid Woodhouse 	return err;
141df8e96f3SDavid Woodhouse }
142df8e96f3SDavid Woodhouse 
143df8e96f3SDavid Woodhouse /*
144df8e96f3SDavid Woodhouse  * Helper function for jffs2_add_older_frag_to_fragtree().
145df8e96f3SDavid Woodhouse  *
146df8e96f3SDavid Woodhouse  * Checks the node if we are in the checking stage.
147df8e96f3SDavid Woodhouse  */
148df8e96f3SDavid Woodhouse static int check_tn_node(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn)
149df8e96f3SDavid Woodhouse {
150df8e96f3SDavid Woodhouse 	int ret;
151df8e96f3SDavid Woodhouse 
152df8e96f3SDavid Woodhouse 	BUG_ON(ref_obsolete(tn->fn->raw));
153df8e96f3SDavid Woodhouse 
154df8e96f3SDavid Woodhouse 	/* We only check the data CRC of unchecked nodes */
155df8e96f3SDavid Woodhouse 	if (ref_flags(tn->fn->raw) != REF_UNCHECKED)
156df8e96f3SDavid Woodhouse 		return 0;
157df8e96f3SDavid Woodhouse 
158df8e96f3SDavid Woodhouse 	dbg_readinode("check node %#04x-%#04x, phys offs %#08x\n",
159df8e96f3SDavid Woodhouse 		      tn->fn->ofs, tn->fn->ofs + tn->fn->size, ref_offset(tn->fn->raw));
160df8e96f3SDavid Woodhouse 
161df8e96f3SDavid Woodhouse 	ret = check_node_data(c, tn);
162df8e96f3SDavid Woodhouse 	if (unlikely(ret < 0)) {
163df8e96f3SDavid Woodhouse 		JFFS2_ERROR("check_node_data() returned error: %d.\n",
164df8e96f3SDavid Woodhouse 			ret);
165df8e96f3SDavid Woodhouse 	} else if (unlikely(ret > 0)) {
166df8e96f3SDavid Woodhouse 		dbg_readinode("CRC error, mark it obsolete.\n");
167df8e96f3SDavid Woodhouse 		jffs2_mark_node_obsolete(c, tn->fn->raw);
168df8e96f3SDavid Woodhouse 	}
169df8e96f3SDavid Woodhouse 
170df8e96f3SDavid Woodhouse 	return ret;
171df8e96f3SDavid Woodhouse }
172df8e96f3SDavid Woodhouse 
173df8e96f3SDavid Woodhouse static struct jffs2_tmp_dnode_info *jffs2_lookup_tn(struct rb_root *tn_root, uint32_t offset)
174df8e96f3SDavid Woodhouse {
175df8e96f3SDavid Woodhouse 	struct rb_node *next;
176df8e96f3SDavid Woodhouse 	struct jffs2_tmp_dnode_info *tn = NULL;
177df8e96f3SDavid Woodhouse 
178df8e96f3SDavid Woodhouse 	dbg_readinode("root %p, offset %d\n", tn_root, offset);
179df8e96f3SDavid Woodhouse 
180df8e96f3SDavid Woodhouse 	next = tn_root->rb_node;
181df8e96f3SDavid Woodhouse 
182df8e96f3SDavid Woodhouse 	while (next) {
183df8e96f3SDavid Woodhouse 		tn = rb_entry(next, struct jffs2_tmp_dnode_info, rb);
184df8e96f3SDavid Woodhouse 
185df8e96f3SDavid Woodhouse 		if (tn->fn->ofs < offset)
186df8e96f3SDavid Woodhouse 			next = tn->rb.rb_right;
187df8e96f3SDavid Woodhouse 		else if (tn->fn->ofs >= offset)
188df8e96f3SDavid Woodhouse 			next = tn->rb.rb_left;
189df8e96f3SDavid Woodhouse 		else
190df8e96f3SDavid Woodhouse 			break;
191df8e96f3SDavid Woodhouse 	}
192df8e96f3SDavid Woodhouse 
193df8e96f3SDavid Woodhouse 	return tn;
194df8e96f3SDavid Woodhouse }
195df8e96f3SDavid Woodhouse 
196df8e96f3SDavid Woodhouse 
197df8e96f3SDavid Woodhouse static void jffs2_kill_tn(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn)
198df8e96f3SDavid Woodhouse {
199df8e96f3SDavid Woodhouse 	jffs2_mark_node_obsolete(c, tn->fn->raw);
200df8e96f3SDavid Woodhouse 	jffs2_free_full_dnode(tn->fn);
201df8e96f3SDavid Woodhouse 	jffs2_free_tmp_dnode_info(tn);
202df8e96f3SDavid Woodhouse }
203df8e96f3SDavid Woodhouse /*
204df8e96f3SDavid Woodhouse  * This function is used when we read an inode. Data nodes arrive in
205df8e96f3SDavid Woodhouse  * arbitrary order -- they may be older or newer than the nodes which
206df8e96f3SDavid Woodhouse  * are already in the tree. Where overlaps occur, the older node can
207df8e96f3SDavid Woodhouse  * be discarded as long as the newer passes the CRC check. We don't
208df8e96f3SDavid Woodhouse  * bother to keep track of holes in this rbtree, and neither do we deal
209df8e96f3SDavid Woodhouse  * with frags -- we can have multiple entries starting at the same
210df8e96f3SDavid Woodhouse  * offset, and the one with the smallest length will come first in the
211df8e96f3SDavid Woodhouse  * ordering.
212df8e96f3SDavid Woodhouse  *
21314c6381eSDavid Woodhouse  * Returns 0 if the node was handled (including marking it obsolete)
214df8e96f3SDavid Woodhouse  *         < 0 an if error occurred
215df8e96f3SDavid Woodhouse  */
216df8e96f3SDavid Woodhouse static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c,
217df8e96f3SDavid Woodhouse 				struct jffs2_readinode_info *rii,
218df8e96f3SDavid Woodhouse 				struct jffs2_tmp_dnode_info *tn)
219df8e96f3SDavid Woodhouse {
220df8e96f3SDavid Woodhouse 	uint32_t fn_end = tn->fn->ofs + tn->fn->size;
22196dd8d25SDavid Woodhouse 	struct jffs2_tmp_dnode_info *this;
222df8e96f3SDavid Woodhouse 
223fcf3cafbSDavid Woodhouse 	dbg_readinode("insert fragment %#04x-%#04x, ver %u at %08x\n", tn->fn->ofs, fn_end, tn->version, ref_offset(tn->fn->raw));
224df8e96f3SDavid Woodhouse 
225df8e96f3SDavid Woodhouse 	/* If a node has zero dsize, we only have to keep if it if it might be the
226df8e96f3SDavid Woodhouse 	   node with highest version -- i.e. the one which will end up as f->metadata.
227df8e96f3SDavid Woodhouse 	   Note that such nodes won't be REF_UNCHECKED since there are no data to
228df8e96f3SDavid Woodhouse 	   check anyway. */
229df8e96f3SDavid Woodhouse 	if (!tn->fn->size) {
230df8e96f3SDavid Woodhouse 		if (rii->mdata_tn) {
2310477d24eSDavid Woodhouse 			if (rii->mdata_tn->version < tn->version) {
232df8e96f3SDavid Woodhouse 				/* We had a candidate mdata node already */
233df8e96f3SDavid Woodhouse 				dbg_readinode("kill old mdata with ver %d\n", rii->mdata_tn->version);
234df8e96f3SDavid Woodhouse 				jffs2_kill_tn(c, rii->mdata_tn);
2350477d24eSDavid Woodhouse 			} else {
2360477d24eSDavid Woodhouse 				dbg_readinode("kill new mdata with ver %d (older than existing %d\n",
2370477d24eSDavid Woodhouse 					      tn->version, rii->mdata_tn->version);
2380477d24eSDavid Woodhouse 				jffs2_kill_tn(c, tn);
2390477d24eSDavid Woodhouse 				return 0;
2400477d24eSDavid Woodhouse 			}
241df8e96f3SDavid Woodhouse 		}
242df8e96f3SDavid Woodhouse 		rii->mdata_tn = tn;
243df8e96f3SDavid Woodhouse 		dbg_readinode("keep new mdata with ver %d\n", tn->version);
244df8e96f3SDavid Woodhouse 		return 0;
245df8e96f3SDavid Woodhouse 	}
246df8e96f3SDavid Woodhouse 
247df8e96f3SDavid Woodhouse 	/* Find the earliest node which _may_ be relevant to this one */
248df8e96f3SDavid Woodhouse 	this = jffs2_lookup_tn(&rii->tn_root, tn->fn->ofs);
2491c979645SDavid Woodhouse 	if (this) {
250df8e96f3SDavid Woodhouse 		/* If the node is coincident with another at a lower address,
251df8e96f3SDavid Woodhouse 		   back up until the other node is found. It may be relevant */
2521c979645SDavid Woodhouse 		while (this->overlapped)
2531c979645SDavid Woodhouse 			this = tn_prev(this);
254df8e96f3SDavid Woodhouse 
2551c979645SDavid Woodhouse 		/* First node should never be marked overlapped */
2561c979645SDavid Woodhouse 		BUG_ON(!this);
257df8e96f3SDavid Woodhouse 		dbg_readinode("'this' found %#04x-%#04x (%s)\n", this->fn->ofs, this->fn->ofs + this->fn->size, this->fn ? "data" : "hole");
2581c979645SDavid Woodhouse 	}
259df8e96f3SDavid Woodhouse 
260df8e96f3SDavid Woodhouse 	while (this) {
261df8e96f3SDavid Woodhouse 		if (this->fn->ofs > fn_end)
262df8e96f3SDavid Woodhouse 			break;
263df8e96f3SDavid Woodhouse 		dbg_readinode("Ponder this ver %d, 0x%x-0x%x\n",
264df8e96f3SDavid Woodhouse 			      this->version, this->fn->ofs, this->fn->size);
265df8e96f3SDavid Woodhouse 
266df8e96f3SDavid Woodhouse 		if (this->version == tn->version) {
267df8e96f3SDavid Woodhouse 			/* Version number collision means REF_PRISTINE GC. Accept either of them
268df8e96f3SDavid Woodhouse 			   as long as the CRC is correct. Check the one we have already...  */
269df8e96f3SDavid Woodhouse 			if (!check_tn_node(c, this)) {
270df8e96f3SDavid Woodhouse 				/* The one we already had was OK. Keep it and throw away the new one */
271df8e96f3SDavid Woodhouse 				dbg_readinode("Like old node. Throw away new\n");
272df8e96f3SDavid Woodhouse 				jffs2_kill_tn(c, tn);
273df8e96f3SDavid Woodhouse 				return 0;
274df8e96f3SDavid Woodhouse 			} else {
275df8e96f3SDavid Woodhouse 				/* Who cares if the new one is good; keep it for now anyway. */
276df8e96f3SDavid Woodhouse 				dbg_readinode("Like new node. Throw away old\n");
277fcf3cafbSDavid Woodhouse 				rb_replace_node(&this->rb, &tn->rb, &rii->tn_root);
278fcf3cafbSDavid Woodhouse 				jffs2_kill_tn(c, this);
279fcf3cafbSDavid Woodhouse 				/* Same overlapping from in front and behind */
280fcf3cafbSDavid Woodhouse 				return 0;
281df8e96f3SDavid Woodhouse 			}
282df8e96f3SDavid Woodhouse 		}
283df8e96f3SDavid Woodhouse 		if (this->version < tn->version &&
284df8e96f3SDavid Woodhouse 		    this->fn->ofs >= tn->fn->ofs &&
285df8e96f3SDavid Woodhouse 		    this->fn->ofs + this->fn->size <= fn_end) {
286df8e96f3SDavid Woodhouse 			/* New node entirely overlaps 'this' */
287df8e96f3SDavid Woodhouse 			if (check_tn_node(c, tn)) {
288df8e96f3SDavid Woodhouse 				dbg_readinode("new node bad CRC\n");
289df8e96f3SDavid Woodhouse 				jffs2_kill_tn(c, tn);
290df8e96f3SDavid Woodhouse 				return 0;
291df8e96f3SDavid Woodhouse 			}
292fcf3cafbSDavid Woodhouse 			/* ... and is good. Kill 'this' and any subsequent nodes which are also overlapped */
2931c979645SDavid Woodhouse 			while (this && this->fn->ofs + this->fn->size <= fn_end) {
294df8e96f3SDavid Woodhouse 				struct jffs2_tmp_dnode_info *next = tn_next(this);
295df8e96f3SDavid Woodhouse 				if (this->version < tn->version) {
296df8e96f3SDavid Woodhouse 					tn_erase(this, &rii->tn_root);
297df8e96f3SDavid Woodhouse 					dbg_readinode("Kill overlapped ver %d, 0x%x-0x%x\n",
298df8e96f3SDavid Woodhouse 						      this->version, this->fn->ofs,
299df8e96f3SDavid Woodhouse 						      this->fn->ofs+this->fn->size);
300df8e96f3SDavid Woodhouse 					jffs2_kill_tn(c, this);
301df8e96f3SDavid Woodhouse 				}
302df8e96f3SDavid Woodhouse 				this = next;
303df8e96f3SDavid Woodhouse 			}
304fcf3cafbSDavid Woodhouse 			dbg_readinode("Done killing overlapped nodes\n");
3051c979645SDavid Woodhouse 			continue;
306df8e96f3SDavid Woodhouse 		}
307df8e96f3SDavid Woodhouse 		if (this->version > tn->version &&
308df8e96f3SDavid Woodhouse 		    this->fn->ofs <= tn->fn->ofs &&
309df8e96f3SDavid Woodhouse 		    this->fn->ofs+this->fn->size >= fn_end) {
310df8e96f3SDavid Woodhouse 			/* New node entirely overlapped by 'this' */
311df8e96f3SDavid Woodhouse 			if (!check_tn_node(c, this)) {
312df8e96f3SDavid Woodhouse 				dbg_readinode("Good CRC on old node. Kill new\n");
313df8e96f3SDavid Woodhouse 				jffs2_kill_tn(c, tn);
314df8e96f3SDavid Woodhouse 				return 0;
315df8e96f3SDavid Woodhouse 			}
316df8e96f3SDavid Woodhouse 			/* ... but 'this' was bad. Replace it... */
317df8e96f3SDavid Woodhouse 			dbg_readinode("Bad CRC on old overlapping node. Kill it\n");
318fcf3cafbSDavid Woodhouse 			tn_erase(this, &rii->tn_root);
319df8e96f3SDavid Woodhouse 			jffs2_kill_tn(c, this);
320fcf3cafbSDavid Woodhouse 			break;
321df8e96f3SDavid Woodhouse 		}
322df8e96f3SDavid Woodhouse 
323df8e96f3SDavid Woodhouse 		this = tn_next(this);
324df8e96f3SDavid Woodhouse 	}
32596dd8d25SDavid Woodhouse 
326df8e96f3SDavid Woodhouse 	/* We neither completely obsoleted nor were completely
32796dd8d25SDavid Woodhouse 	   obsoleted by an earlier node. Insert into the tree */
328df8e96f3SDavid Woodhouse 	{
32996dd8d25SDavid Woodhouse 		struct rb_node *parent;
33096dd8d25SDavid Woodhouse 		struct rb_node **link = &rii->tn_root.rb_node;
3311c979645SDavid Woodhouse 		struct jffs2_tmp_dnode_info *insert_point = NULL;
332df8e96f3SDavid Woodhouse 
333df8e96f3SDavid Woodhouse 		while (*link) {
334df8e96f3SDavid Woodhouse 			parent = *link;
335df8e96f3SDavid Woodhouse 			insert_point = rb_entry(parent, struct jffs2_tmp_dnode_info, rb);
336df8e96f3SDavid Woodhouse 			if (tn->fn->ofs > insert_point->fn->ofs)
337df8e96f3SDavid Woodhouse 				link = &insert_point->rb.rb_right;
338df8e96f3SDavid Woodhouse 			else if (tn->fn->ofs < insert_point->fn->ofs ||
339df8e96f3SDavid Woodhouse 				 tn->fn->size < insert_point->fn->size)
340df8e96f3SDavid Woodhouse 				link = &insert_point->rb.rb_left;
341df8e96f3SDavid Woodhouse 			else
342df8e96f3SDavid Woodhouse 				link = &insert_point->rb.rb_right;
343df8e96f3SDavid Woodhouse 		}
344df8e96f3SDavid Woodhouse 		rb_link_node(&tn->rb, &insert_point->rb, link);
345df8e96f3SDavid Woodhouse 		rb_insert_color(&tn->rb, &rii->tn_root);
346df8e96f3SDavid Woodhouse 	}
3471123e2a8SDavid Woodhouse 
348df8e96f3SDavid Woodhouse 	/* If there's anything behind that overlaps us, note it */
349df8e96f3SDavid Woodhouse 	this = tn_prev(tn);
350df8e96f3SDavid Woodhouse 	if (this) {
351df8e96f3SDavid Woodhouse 		while (1) {
352df8e96f3SDavid Woodhouse 			if (this->fn->ofs + this->fn->size > tn->fn->ofs) {
353df8e96f3SDavid Woodhouse 				dbg_readinode("Node is overlapped by %p (v %d, 0x%x-0x%x)\n",
354df8e96f3SDavid Woodhouse 					      this, this->version, this->fn->ofs,
355df8e96f3SDavid Woodhouse 					      this->fn->ofs+this->fn->size);
356df8e96f3SDavid Woodhouse 				tn->overlapped = 1;
357df8e96f3SDavid Woodhouse 				break;
358df8e96f3SDavid Woodhouse 			}
359df8e96f3SDavid Woodhouse 			if (!this->overlapped)
360df8e96f3SDavid Woodhouse 				break;
361df8e96f3SDavid Woodhouse 			this = tn_prev(this);
362df8e96f3SDavid Woodhouse 		}
363df8e96f3SDavid Woodhouse 	}
364df8e96f3SDavid Woodhouse 
365df8e96f3SDavid Woodhouse 	/* If the new node overlaps anything ahead, note it */
366df8e96f3SDavid Woodhouse 	this = tn_next(tn);
367df8e96f3SDavid Woodhouse 	while (this && this->fn->ofs < fn_end) {
368df8e96f3SDavid Woodhouse 		this->overlapped = 1;
369df8e96f3SDavid Woodhouse 		dbg_readinode("Node ver %d, 0x%x-0x%x is overlapped\n",
370df8e96f3SDavid Woodhouse 			      this->version, this->fn->ofs,
371df8e96f3SDavid Woodhouse 			      this->fn->ofs+this->fn->size);
372df8e96f3SDavid Woodhouse 		this = tn_next(this);
373df8e96f3SDavid Woodhouse 	}
374df8e96f3SDavid Woodhouse 	return 0;
375df8e96f3SDavid Woodhouse }
376df8e96f3SDavid Woodhouse 
377df8e96f3SDavid Woodhouse /* Trivial function to remove the last node in the tree. Which by definition
378df8e96f3SDavid Woodhouse    has no right-hand -- so can be removed just by making its only child (if
379df8e96f3SDavid Woodhouse    any) take its place under its parent. */
380df8e96f3SDavid Woodhouse static void eat_last(struct rb_root *root, struct rb_node *node)
381df8e96f3SDavid Woodhouse {
382df8e96f3SDavid Woodhouse 	struct rb_node *parent = rb_parent(node);
383df8e96f3SDavid Woodhouse 	struct rb_node **link;
384df8e96f3SDavid Woodhouse 
385df8e96f3SDavid Woodhouse 	/* LAST! */
386df8e96f3SDavid Woodhouse 	BUG_ON(node->rb_right);
387df8e96f3SDavid Woodhouse 
388df8e96f3SDavid Woodhouse 	if (!parent)
389df8e96f3SDavid Woodhouse 		link = &root->rb_node;
390df8e96f3SDavid Woodhouse 	else if (node == parent->rb_left)
391df8e96f3SDavid Woodhouse 		link = &parent->rb_left;
392df8e96f3SDavid Woodhouse 	else
393df8e96f3SDavid Woodhouse 		link = &parent->rb_right;
394df8e96f3SDavid Woodhouse 
395df8e96f3SDavid Woodhouse 	*link = node->rb_left;
396df8e96f3SDavid Woodhouse 	/* Colour doesn't matter now. Only the parent pointer. */
397df8e96f3SDavid Woodhouse 	if (node->rb_left)
398df8e96f3SDavid Woodhouse 		node->rb_left->rb_parent_color = node->rb_parent_color;
399df8e96f3SDavid Woodhouse }
400df8e96f3SDavid Woodhouse 
401df8e96f3SDavid Woodhouse /* We put this in reverse order, so we can just use eat_last */
402df8e96f3SDavid Woodhouse static void ver_insert(struct rb_root *ver_root, struct jffs2_tmp_dnode_info *tn)
403df8e96f3SDavid Woodhouse {
404df8e96f3SDavid Woodhouse 	struct rb_node **link = &ver_root->rb_node;
405df8e96f3SDavid Woodhouse 	struct rb_node *parent = NULL;
406df8e96f3SDavid Woodhouse 	struct jffs2_tmp_dnode_info *this_tn;
407df8e96f3SDavid Woodhouse 
408df8e96f3SDavid Woodhouse 	while (*link) {
409df8e96f3SDavid Woodhouse 		parent = *link;
410df8e96f3SDavid Woodhouse 		this_tn = rb_entry(parent, struct jffs2_tmp_dnode_info, rb);
411df8e96f3SDavid Woodhouse 
412df8e96f3SDavid Woodhouse 		if (tn->version > this_tn->version)
413df8e96f3SDavid Woodhouse 			link = &parent->rb_left;
414df8e96f3SDavid Woodhouse 		else
415df8e96f3SDavid Woodhouse 			link = &parent->rb_right;
416df8e96f3SDavid Woodhouse 	}
417df8e96f3SDavid Woodhouse 	dbg_readinode("Link new node at %p (root is %p)\n", link, ver_root);
418df8e96f3SDavid Woodhouse 	rb_link_node(&tn->rb, parent, link);
419df8e96f3SDavid Woodhouse 	rb_insert_color(&tn->rb, ver_root);
420df8e96f3SDavid Woodhouse }
421df8e96f3SDavid Woodhouse 
422df8e96f3SDavid Woodhouse /* Build final, normal fragtree from tn tree. It doesn't matter which order
423df8e96f3SDavid Woodhouse    we add nodes to the real fragtree, as long as they don't overlap. And
424df8e96f3SDavid Woodhouse    having thrown away the majority of overlapped nodes as we went, there
425df8e96f3SDavid Woodhouse    really shouldn't be many sets of nodes which do overlap. If we start at
426df8e96f3SDavid Woodhouse    the end, we can use the overlap markers -- we can just eat nodes which
427df8e96f3SDavid Woodhouse    aren't overlapped, and when we encounter nodes which _do_ overlap we
428df8e96f3SDavid Woodhouse    sort them all into a temporary tree in version order before replaying them. */
429df8e96f3SDavid Woodhouse static int jffs2_build_inode_fragtree(struct jffs2_sb_info *c,
430df8e96f3SDavid Woodhouse 				      struct jffs2_inode_info *f,
431df8e96f3SDavid Woodhouse 				      struct jffs2_readinode_info *rii)
432df8e96f3SDavid Woodhouse {
433df8e96f3SDavid Woodhouse 	struct jffs2_tmp_dnode_info *pen, *last, *this;
434df8e96f3SDavid Woodhouse 	struct rb_root ver_root = RB_ROOT;
435df8e96f3SDavid Woodhouse 	uint32_t high_ver = 0;
436df8e96f3SDavid Woodhouse 
437df8e96f3SDavid Woodhouse 	if (rii->mdata_tn) {
438df8e96f3SDavid Woodhouse 		dbg_readinode("potential mdata is ver %d at %p\n", rii->mdata_tn->version, rii->mdata_tn);
439df8e96f3SDavid Woodhouse 		high_ver = rii->mdata_tn->version;
440df8e96f3SDavid Woodhouse 		rii->latest_ref = rii->mdata_tn->fn->raw;
441df8e96f3SDavid Woodhouse 	}
442df8e96f3SDavid Woodhouse #ifdef JFFS2_DBG_READINODE_MESSAGES
443df8e96f3SDavid Woodhouse 	this = tn_last(&rii->tn_root);
444df8e96f3SDavid Woodhouse 	while (this) {
445df8e96f3SDavid Woodhouse 		dbg_readinode("tn %p ver %d range 0x%x-0x%x ov %d\n", this, this->version, this->fn->ofs,
446df8e96f3SDavid Woodhouse 			      this->fn->ofs+this->fn->size, this->overlapped);
447df8e96f3SDavid Woodhouse 		this = tn_prev(this);
448df8e96f3SDavid Woodhouse 	}
449df8e96f3SDavid Woodhouse #endif
450df8e96f3SDavid Woodhouse 	pen = tn_last(&rii->tn_root);
451df8e96f3SDavid Woodhouse 	while ((last = pen)) {
452df8e96f3SDavid Woodhouse 		pen = tn_prev(last);
453df8e96f3SDavid Woodhouse 
454df8e96f3SDavid Woodhouse 		eat_last(&rii->tn_root, &last->rb);
455df8e96f3SDavid Woodhouse 		ver_insert(&ver_root, last);
456df8e96f3SDavid Woodhouse 
457df8e96f3SDavid Woodhouse 		if (unlikely(last->overlapped))
458df8e96f3SDavid Woodhouse 			continue;
459df8e96f3SDavid Woodhouse 
460df8e96f3SDavid Woodhouse 		/* Now we have a bunch of nodes in reverse version
461df8e96f3SDavid Woodhouse 		   order, in the tree at ver_root. Most of the time,
462df8e96f3SDavid Woodhouse 		   there'll actually be only one node in the 'tree',
463df8e96f3SDavid Woodhouse 		   in fact. */
464df8e96f3SDavid Woodhouse 		this = tn_last(&ver_root);
465df8e96f3SDavid Woodhouse 
466df8e96f3SDavid Woodhouse 		while (this) {
467df8e96f3SDavid Woodhouse 			struct jffs2_tmp_dnode_info *vers_next;
468df8e96f3SDavid Woodhouse 			int ret;
469df8e96f3SDavid Woodhouse 			vers_next = tn_prev(this);
470df8e96f3SDavid Woodhouse 			eat_last(&ver_root, &this->rb);
471df8e96f3SDavid Woodhouse 			if (check_tn_node(c, this)) {
4721123e2a8SDavid Woodhouse 				dbg_readinode("node ver %d, 0x%x-0x%x failed CRC\n",
473df8e96f3SDavid Woodhouse 					     this->version, this->fn->ofs,
474df8e96f3SDavid Woodhouse 					     this->fn->ofs+this->fn->size);
475df8e96f3SDavid Woodhouse 				jffs2_kill_tn(c, this);
476df8e96f3SDavid Woodhouse 			} else {
477df8e96f3SDavid Woodhouse 				if (this->version > high_ver) {
478df8e96f3SDavid Woodhouse 					/* Note that this is different from the other
479df8e96f3SDavid Woodhouse 					   highest_version, because this one is only
480df8e96f3SDavid Woodhouse 					   counting _valid_ nodes which could give the
481df8e96f3SDavid Woodhouse 					   latest inode metadata */
482df8e96f3SDavid Woodhouse 					high_ver = this->version;
483df8e96f3SDavid Woodhouse 					rii->latest_ref = this->fn->raw;
484df8e96f3SDavid Woodhouse 				}
4851123e2a8SDavid Woodhouse 				dbg_readinode("Add %p (v %d, 0x%x-0x%x, ov %d) to fragtree\n",
486df8e96f3SDavid Woodhouse 					     this, this->version, this->fn->ofs,
487df8e96f3SDavid Woodhouse 					     this->fn->ofs+this->fn->size, this->overlapped);
488df8e96f3SDavid Woodhouse 
489df8e96f3SDavid Woodhouse 				ret = jffs2_add_full_dnode_to_inode(c, f, this->fn);
490df8e96f3SDavid Woodhouse 				if (ret) {
491df8e96f3SDavid Woodhouse 					/* Free the nodes in vers_root; let the caller
492df8e96f3SDavid Woodhouse 					   deal with the rest */
493df8e96f3SDavid Woodhouse 					JFFS2_ERROR("Add node to tree failed %d\n", ret);
494df8e96f3SDavid Woodhouse 					while (1) {
495df8e96f3SDavid Woodhouse 						vers_next = tn_prev(this);
496df8e96f3SDavid Woodhouse 						if (check_tn_node(c, this))
497df8e96f3SDavid Woodhouse 							jffs2_mark_node_obsolete(c, this->fn->raw);
498df8e96f3SDavid Woodhouse 						jffs2_free_full_dnode(this->fn);
499df8e96f3SDavid Woodhouse 						jffs2_free_tmp_dnode_info(this);
500df8e96f3SDavid Woodhouse 						this = vers_next;
501df8e96f3SDavid Woodhouse 						if (!this)
502df8e96f3SDavid Woodhouse 							break;
503df8e96f3SDavid Woodhouse 						eat_last(&ver_root, &vers_next->rb);
504df8e96f3SDavid Woodhouse 					}
505df8e96f3SDavid Woodhouse 					return ret;
506df8e96f3SDavid Woodhouse 				}
507df8e96f3SDavid Woodhouse 				jffs2_free_tmp_dnode_info(this);
508df8e96f3SDavid Woodhouse 			}
509df8e96f3SDavid Woodhouse 			this = vers_next;
510df8e96f3SDavid Woodhouse 		}
511df8e96f3SDavid Woodhouse 	}
512df8e96f3SDavid Woodhouse 	return 0;
513f97117d1SArtem B. Bityutskiy }
514f97117d1SArtem B. Bityutskiy 
515f97117d1SArtem B. Bityutskiy static void jffs2_free_tmp_dnode_info_list(struct rb_root *list)
516f97117d1SArtem B. Bityutskiy {
517f97117d1SArtem B. Bityutskiy 	struct rb_node *this;
518f97117d1SArtem B. Bityutskiy 	struct jffs2_tmp_dnode_info *tn;
519f97117d1SArtem B. Bityutskiy 
520f97117d1SArtem B. Bityutskiy 	this = list->rb_node;
521f97117d1SArtem B. Bityutskiy 
522f97117d1SArtem B. Bityutskiy 	/* Now at bottom of tree */
523f97117d1SArtem B. Bityutskiy 	while (this) {
524f97117d1SArtem B. Bityutskiy 		if (this->rb_left)
525f97117d1SArtem B. Bityutskiy 			this = this->rb_left;
526f97117d1SArtem B. Bityutskiy 		else if (this->rb_right)
527f97117d1SArtem B. Bityutskiy 			this = this->rb_right;
528f97117d1SArtem B. Bityutskiy 		else {
529f97117d1SArtem B. Bityutskiy 			tn = rb_entry(this, struct jffs2_tmp_dnode_info, rb);
530f97117d1SArtem B. Bityutskiy 			jffs2_free_full_dnode(tn->fn);
531f97117d1SArtem B. Bityutskiy 			jffs2_free_tmp_dnode_info(tn);
532f97117d1SArtem B. Bityutskiy 
53321f1d5fcSDavid Woodhouse 			this = rb_parent(this);
534f97117d1SArtem B. Bityutskiy 			if (!this)
5351da177e4SLinus Torvalds 				break;
5361da177e4SLinus Torvalds 
537f97117d1SArtem B. Bityutskiy 			if (this->rb_left == &tn->rb)
538f97117d1SArtem B. Bityutskiy 				this->rb_left = NULL;
539f97117d1SArtem B. Bityutskiy 			else if (this->rb_right == &tn->rb)
540f97117d1SArtem B. Bityutskiy 				this->rb_right = NULL;
541f97117d1SArtem B. Bityutskiy 			else BUG();
542f97117d1SArtem B. Bityutskiy 		}
543f97117d1SArtem B. Bityutskiy 	}
544f97117d1SArtem B. Bityutskiy 	list->rb_node = NULL;
545f97117d1SArtem B. Bityutskiy }
5461da177e4SLinus Torvalds 
547f97117d1SArtem B. Bityutskiy static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
548f97117d1SArtem B. Bityutskiy {
549f97117d1SArtem B. Bityutskiy 	struct jffs2_full_dirent *next;
550f97117d1SArtem B. Bityutskiy 
551f97117d1SArtem B. Bityutskiy 	while (fd) {
552f97117d1SArtem B. Bityutskiy 		next = fd->next;
553f97117d1SArtem B. Bityutskiy 		jffs2_free_full_dirent(fd);
554f97117d1SArtem B. Bityutskiy 		fd = next;
555f97117d1SArtem B. Bityutskiy 	}
556f97117d1SArtem B. Bityutskiy }
557f97117d1SArtem B. Bityutskiy 
558f97117d1SArtem B. Bityutskiy /* Returns first valid node after 'ref'. May return 'ref' */
559f97117d1SArtem B. Bityutskiy static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_ref *ref)
560f97117d1SArtem B. Bityutskiy {
561f97117d1SArtem B. Bityutskiy 	while (ref && ref->next_in_ino) {
562f97117d1SArtem B. Bityutskiy 		if (!ref_obsolete(ref))
563f97117d1SArtem B. Bityutskiy 			return ref;
564733802d9SArtem B. Bityutskiy 		dbg_noderef("node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref));
565f97117d1SArtem B. Bityutskiy 		ref = ref->next_in_ino;
566f97117d1SArtem B. Bityutskiy 	}
567f97117d1SArtem B. Bityutskiy 	return NULL;
568f97117d1SArtem B. Bityutskiy }
569f97117d1SArtem B. Bityutskiy 
570f97117d1SArtem B. Bityutskiy /*
571f97117d1SArtem B. Bityutskiy  * Helper function for jffs2_get_inode_nodes().
572f97117d1SArtem B. Bityutskiy  * It is called every time an directory entry node is found.
573f97117d1SArtem B. Bityutskiy  *
57414c6381eSDavid Woodhouse  * Returns: 0 on success;
575f97117d1SArtem B. Bityutskiy  * 	    negative error code on failure.
576f97117d1SArtem B. Bityutskiy  */
5771e0da3cbSArtem B. Bityutskiy static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
578df8e96f3SDavid Woodhouse 				struct jffs2_raw_dirent *rd, size_t read,
579df8e96f3SDavid Woodhouse 				struct jffs2_readinode_info *rii)
580f97117d1SArtem B. Bityutskiy {
581f97117d1SArtem B. Bityutskiy 	struct jffs2_full_dirent *fd;
5821046d880SDavid Woodhouse 	uint32_t crc;
583f97117d1SArtem B. Bityutskiy 
584f97117d1SArtem B. Bityutskiy 	/* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
585f97117d1SArtem B. Bityutskiy 	BUG_ON(ref_obsolete(ref));
586f97117d1SArtem B. Bityutskiy 
5871046d880SDavid Woodhouse 	crc = crc32(0, rd, sizeof(*rd) - 8);
5881046d880SDavid Woodhouse 	if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
5891046d880SDavid Woodhouse 		JFFS2_NOTICE("header CRC failed on dirent node at %#08x: read %#08x, calculated %#08x\n",
5901046d880SDavid Woodhouse 			     ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
591df8e96f3SDavid Woodhouse 		jffs2_mark_node_obsolete(c, ref);
592df8e96f3SDavid Woodhouse 		return 0;
5931046d880SDavid Woodhouse 	}
5941046d880SDavid Woodhouse 
5951046d880SDavid Woodhouse 	/* If we've never checked the CRCs on this node, check them now */
5961046d880SDavid Woodhouse 	if (ref_flags(ref) == REF_UNCHECKED) {
5971046d880SDavid Woodhouse 		struct jffs2_eraseblock *jeb;
5981046d880SDavid Woodhouse 		int len;
5991046d880SDavid Woodhouse 
600f97117d1SArtem B. Bityutskiy 		/* Sanity check */
601f97117d1SArtem B. Bityutskiy 		if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) {
602e0d60137SArtem B. Bityutskiy 			JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n",
603f97117d1SArtem B. Bityutskiy 				    ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen));
604df8e96f3SDavid Woodhouse 			jffs2_mark_node_obsolete(c, ref);
605df8e96f3SDavid Woodhouse 			return 0;
606f97117d1SArtem B. Bityutskiy 		}
607f97117d1SArtem B. Bityutskiy 
6081046d880SDavid Woodhouse 		jeb = &c->blocks[ref->flash_offset / c->sector_size];
6091046d880SDavid Woodhouse 		len = ref_totlen(c, jeb, ref);
6101046d880SDavid Woodhouse 
6111046d880SDavid Woodhouse 		spin_lock(&c->erase_completion_lock);
6121046d880SDavid Woodhouse 		jeb->used_size += len;
6131046d880SDavid Woodhouse 		jeb->unchecked_size -= len;
6141046d880SDavid Woodhouse 		c->used_size += len;
6151046d880SDavid Woodhouse 		c->unchecked_size -= len;
61643dfa07fSDavid Woodhouse 		ref->flash_offset = ref_offset(ref) | dirent_node_state(rd);
6171046d880SDavid Woodhouse 		spin_unlock(&c->erase_completion_lock);
6181046d880SDavid Woodhouse 	}
6191046d880SDavid Woodhouse 
620f97117d1SArtem B. Bityutskiy 	fd = jffs2_alloc_full_dirent(rd->nsize + 1);
621f97117d1SArtem B. Bityutskiy 	if (unlikely(!fd))
622f97117d1SArtem B. Bityutskiy 		return -ENOMEM;
623f97117d1SArtem B. Bityutskiy 
624f97117d1SArtem B. Bityutskiy 	fd->raw = ref;
625f97117d1SArtem B. Bityutskiy 	fd->version = je32_to_cpu(rd->version);
626f97117d1SArtem B. Bityutskiy 	fd->ino = je32_to_cpu(rd->ino);
627f97117d1SArtem B. Bityutskiy 	fd->type = rd->type;
628f97117d1SArtem B. Bityutskiy 
629df8e96f3SDavid Woodhouse 	if (fd->version > rii->highest_version)
630df8e96f3SDavid Woodhouse 		rii->highest_version = fd->version;
631df8e96f3SDavid Woodhouse 
632f97117d1SArtem B. Bityutskiy 	/* Pick out the mctime of the latest dirent */
633df8e96f3SDavid Woodhouse 	if(fd->version > rii->mctime_ver && je32_to_cpu(rd->mctime)) {
634df8e96f3SDavid Woodhouse 		rii->mctime_ver = fd->version;
635df8e96f3SDavid Woodhouse 		rii->latest_mctime = je32_to_cpu(rd->mctime);
636f97117d1SArtem B. Bityutskiy 	}
637f97117d1SArtem B. Bityutskiy 
638f97117d1SArtem B. Bityutskiy 	/*
639f97117d1SArtem B. Bityutskiy 	 * Copy as much of the name as possible from the raw
640f97117d1SArtem B. Bityutskiy 	 * dirent we've already read from the flash.
641f97117d1SArtem B. Bityutskiy 	 */
642f97117d1SArtem B. Bityutskiy 	if (read > sizeof(*rd))
643f97117d1SArtem B. Bityutskiy 		memcpy(&fd->name[0], &rd->name[0],
644f97117d1SArtem B. Bityutskiy 		       min_t(uint32_t, rd->nsize, (read - sizeof(*rd)) ));
645f97117d1SArtem B. Bityutskiy 
646f97117d1SArtem B. Bityutskiy 	/* Do we need to copy any more of the name directly from the flash? */
647f97117d1SArtem B. Bityutskiy 	if (rd->nsize + sizeof(*rd) > read) {
648f97117d1SArtem B. Bityutskiy 		/* FIXME: point() */
649f97117d1SArtem B. Bityutskiy 		int err;
650f97117d1SArtem B. Bityutskiy 		int already = read - sizeof(*rd);
651f97117d1SArtem B. Bityutskiy 
652f97117d1SArtem B. Bityutskiy 		err = jffs2_flash_read(c, (ref_offset(ref)) + read,
653f97117d1SArtem B. Bityutskiy 				rd->nsize - already, &read, &fd->name[already]);
654f97117d1SArtem B. Bityutskiy 		if (unlikely(read != rd->nsize - already) && likely(!err))
655f97117d1SArtem B. Bityutskiy 			return -EIO;
656f97117d1SArtem B. Bityutskiy 
657f97117d1SArtem B. Bityutskiy 		if (unlikely(err)) {
658e0d60137SArtem B. Bityutskiy 			JFFS2_ERROR("read remainder of name: error %d\n", err);
659f97117d1SArtem B. Bityutskiy 			jffs2_free_full_dirent(fd);
660f97117d1SArtem B. Bityutskiy 			return -EIO;
661f97117d1SArtem B. Bityutskiy 		}
662f97117d1SArtem B. Bityutskiy 	}
663f97117d1SArtem B. Bityutskiy 
664f97117d1SArtem B. Bityutskiy 	fd->nhash = full_name_hash(fd->name, rd->nsize);
665f97117d1SArtem B. Bityutskiy 	fd->next = NULL;
666f97117d1SArtem B. Bityutskiy 	fd->name[rd->nsize] = '\0';
667f97117d1SArtem B. Bityutskiy 
668f97117d1SArtem B. Bityutskiy 	/*
669f97117d1SArtem B. Bityutskiy 	 * Wheee. We now have a complete jffs2_full_dirent structure, with
670f97117d1SArtem B. Bityutskiy 	 * the name in it and everything. Link it into the list
671f97117d1SArtem B. Bityutskiy 	 */
672df8e96f3SDavid Woodhouse 	jffs2_add_fd_to_list(c, fd, &rii->fds);
673f97117d1SArtem B. Bityutskiy 
674f97117d1SArtem B. Bityutskiy 	return 0;
675f97117d1SArtem B. Bityutskiy }
676f97117d1SArtem B. Bityutskiy 
677f97117d1SArtem B. Bityutskiy /*
678f97117d1SArtem B. Bityutskiy  * Helper function for jffs2_get_inode_nodes().
679f97117d1SArtem B. Bityutskiy  * It is called every time an inode node is found.
680f97117d1SArtem B. Bityutskiy  *
68114c6381eSDavid Woodhouse  * Returns: 0 on success (possibly after marking a bad node obsolete);
682f97117d1SArtem B. Bityutskiy  * 	    negative error code on failure.
683f97117d1SArtem B. Bityutskiy  */
6841e0da3cbSArtem B. Bityutskiy static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
685df8e96f3SDavid Woodhouse 			     struct jffs2_raw_inode *rd, int rdlen,
686df8e96f3SDavid Woodhouse 			     struct jffs2_readinode_info *rii)
687f97117d1SArtem B. Bityutskiy {
688f97117d1SArtem B. Bityutskiy 	struct jffs2_tmp_dnode_info *tn;
6891e0da3cbSArtem B. Bityutskiy 	uint32_t len, csize;
69014c6381eSDavid Woodhouse 	int ret = 0;
6911046d880SDavid Woodhouse 	uint32_t crc;
692f97117d1SArtem B. Bityutskiy 
693f97117d1SArtem B. Bityutskiy 	/* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
694f97117d1SArtem B. Bityutskiy 	BUG_ON(ref_obsolete(ref));
695f97117d1SArtem B. Bityutskiy 
6961046d880SDavid Woodhouse 	crc = crc32(0, rd, sizeof(*rd) - 8);
6971046d880SDavid Woodhouse 	if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
6981046d880SDavid Woodhouse 		JFFS2_NOTICE("node CRC failed on dnode at %#08x: read %#08x, calculated %#08x\n",
6991046d880SDavid Woodhouse 			     ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
700df8e96f3SDavid Woodhouse 		jffs2_mark_node_obsolete(c, ref);
701df8e96f3SDavid Woodhouse 		return 0;
7021046d880SDavid Woodhouse 	}
7031046d880SDavid Woodhouse 
7041e0da3cbSArtem B. Bityutskiy 	tn = jffs2_alloc_tmp_dnode_info();
7051e0da3cbSArtem B. Bityutskiy 	if (!tn) {
706fb6a82c9SRandy Dunlap 		JFFS2_ERROR("failed to allocate tn (%zu bytes).\n", sizeof(*tn));
7071e0da3cbSArtem B. Bityutskiy 		return -ENOMEM;
7081e0da3cbSArtem B. Bityutskiy 	}
7091e0da3cbSArtem B. Bityutskiy 
7101e0da3cbSArtem B. Bityutskiy 	tn->partial_crc = 0;
7111e0da3cbSArtem B. Bityutskiy 	csize = je32_to_cpu(rd->csize);
7121e0da3cbSArtem B. Bityutskiy 
713f97117d1SArtem B. Bityutskiy 	/* If we've never checked the CRCs on this node, check them now */
714f97117d1SArtem B. Bityutskiy 	if (ref_flags(ref) == REF_UNCHECKED) {
715f97117d1SArtem B. Bityutskiy 
716f97117d1SArtem B. Bityutskiy 		/* Sanity checks */
717f97117d1SArtem B. Bityutskiy 		if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) ||
718f97117d1SArtem B. Bityutskiy 		    unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) {
719e0d60137SArtem B. Bityutskiy 			JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref));
720737b7661SAndrew Lunn 			jffs2_dbg_dump_node(c, ref_offset(ref));
72114c6381eSDavid Woodhouse 			jffs2_mark_node_obsolete(c, ref);
7221e0da3cbSArtem B. Bityutskiy 			goto free_out;
723f97117d1SArtem B. Bityutskiy 		}
724f97117d1SArtem B. Bityutskiy 
7251e0da3cbSArtem B. Bityutskiy 		if (jffs2_is_writebuffered(c) && csize != 0) {
7261e0da3cbSArtem B. Bityutskiy 			/* At this point we are supposed to check the data CRC
7271e0da3cbSArtem B. Bityutskiy 			 * of our unchecked node. But thus far, we do not
7281e0da3cbSArtem B. Bityutskiy 			 * know whether the node is valid or obsolete. To
7291e0da3cbSArtem B. Bityutskiy 			 * figure this out, we need to walk all the nodes of
7301e0da3cbSArtem B. Bityutskiy 			 * the inode and build the inode fragtree. We don't
7311e0da3cbSArtem B. Bityutskiy 			 * want to spend time checking data of nodes which may
7321e0da3cbSArtem B. Bityutskiy 			 * later be found to be obsolete. So we put off the full
7331e0da3cbSArtem B. Bityutskiy 			 * data CRC checking until we have read all the inode
7341e0da3cbSArtem B. Bityutskiy 			 * nodes and have started building the fragtree.
7351e0da3cbSArtem B. Bityutskiy 			 *
7361e0da3cbSArtem B. Bityutskiy 			 * The fragtree is being built starting with nodes
7371e0da3cbSArtem B. Bityutskiy 			 * having the highest version number, so we'll be able
7381e0da3cbSArtem B. Bityutskiy 			 * to detect whether a node is valid (i.e., it is not
7391e0da3cbSArtem B. Bityutskiy 			 * overlapped by a node with higher version) or not.
7401e0da3cbSArtem B. Bityutskiy 			 * And we'll be able to check only those nodes, which
7411e0da3cbSArtem B. Bityutskiy 			 * are not obsolete.
7421e0da3cbSArtem B. Bityutskiy 			 *
7431e0da3cbSArtem B. Bityutskiy 			 * Of course, this optimization only makes sense in case
7441e0da3cbSArtem B. Bityutskiy 			 * of NAND flashes (or other flashes whith
7451e0da3cbSArtem B. Bityutskiy 			 * !jffs2_can_mark_obsolete()), since on NOR flashes
7461e0da3cbSArtem B. Bityutskiy 			 * nodes are marked obsolete physically.
7471e0da3cbSArtem B. Bityutskiy 			 *
7481e0da3cbSArtem B. Bityutskiy 			 * Since NAND flashes (or other flashes with
7491e0da3cbSArtem B. Bityutskiy 			 * jffs2_is_writebuffered(c)) are anyway read by
7501e0da3cbSArtem B. Bityutskiy 			 * fractions of c->wbuf_pagesize, and we have just read
7511e0da3cbSArtem B. Bityutskiy 			 * the node header, it is likely that the starting part
7521e0da3cbSArtem B. Bityutskiy 			 * of the node data is also read when we read the
7531e0da3cbSArtem B. Bityutskiy 			 * header. So we don't mind to check the CRC of the
7541e0da3cbSArtem B. Bityutskiy 			 * starting part of the data of the node now, and check
7551e0da3cbSArtem B. Bityutskiy 			 * the second part later (in jffs2_check_node_data()).
7561e0da3cbSArtem B. Bityutskiy 			 * Of course, we will not need to re-read and re-check
7571e0da3cbSArtem B. Bityutskiy 			 * the NAND page which we have just read. This is why we
7581e0da3cbSArtem B. Bityutskiy 			 * read the whole NAND page at jffs2_get_inode_nodes(),
7591e0da3cbSArtem B. Bityutskiy 			 * while we needed only the node header.
7601e0da3cbSArtem B. Bityutskiy 			 */
7611e0da3cbSArtem B. Bityutskiy 			unsigned char *buf;
762f97117d1SArtem B. Bityutskiy 
7631e0da3cbSArtem B. Bityutskiy 			/* 'buf' will point to the start of data */
7641e0da3cbSArtem B. Bityutskiy 			buf = (unsigned char *)rd + sizeof(*rd);
7651e0da3cbSArtem B. Bityutskiy 			/* len will be the read data length */
7661e0da3cbSArtem B. Bityutskiy 			len = min_t(uint32_t, rdlen - sizeof(*rd), csize);
767280562b2SArtem B. Bityutskiy 			tn->partial_crc = crc32(0, buf, len);
768f97117d1SArtem B. Bityutskiy 
769733802d9SArtem B. Bityutskiy 			dbg_readinode("Calculates CRC (%#08x) for %d bytes, csize %d\n", tn->partial_crc, len, csize);
770f97117d1SArtem B. Bityutskiy 
7711e0da3cbSArtem B. Bityutskiy 			/* If we actually calculated the whole data CRC
7721e0da3cbSArtem B. Bityutskiy 			 * and it is wrong, drop the node. */
7733c091337SArtem B. Bityutskiy 			if (len >= csize && unlikely(tn->partial_crc != je32_to_cpu(rd->data_crc))) {
77439243508SArtem B. Bityutskiy 				JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n",
77539243508SArtem B. Bityutskiy 					ref_offset(ref), tn->partial_crc, je32_to_cpu(rd->data_crc));
77614c6381eSDavid Woodhouse 				jffs2_mark_node_obsolete(c, ref);
7771e0da3cbSArtem B. Bityutskiy 				goto free_out;
77839243508SArtem B. Bityutskiy 			}
779f97117d1SArtem B. Bityutskiy 
7801e0da3cbSArtem B. Bityutskiy 		} else if (csize == 0) {
7811e0da3cbSArtem B. Bityutskiy 			/*
7821e0da3cbSArtem B. Bityutskiy 			 * We checked the header CRC. If the node has no data, adjust
7831e0da3cbSArtem B. Bityutskiy 			 * the space accounting now. For other nodes this will be done
7841e0da3cbSArtem B. Bityutskiy 			 * later either when the node is marked obsolete or when its
7851e0da3cbSArtem B. Bityutskiy 			 * data is checked.
7861e0da3cbSArtem B. Bityutskiy 			 */
7871e0da3cbSArtem B. Bityutskiy 			struct jffs2_eraseblock *jeb;
7881e0da3cbSArtem B. Bityutskiy 
789733802d9SArtem B. Bityutskiy 			dbg_readinode("the node has no data.\n");
790f97117d1SArtem B. Bityutskiy 			jeb = &c->blocks[ref->flash_offset / c->sector_size];
791f97117d1SArtem B. Bityutskiy 			len = ref_totlen(c, jeb, ref);
792f97117d1SArtem B. Bityutskiy 
793f97117d1SArtem B. Bityutskiy 			spin_lock(&c->erase_completion_lock);
794f97117d1SArtem B. Bityutskiy 			jeb->used_size += len;
795f97117d1SArtem B. Bityutskiy 			jeb->unchecked_size -= len;
796f97117d1SArtem B. Bityutskiy 			c->used_size += len;
797f97117d1SArtem B. Bityutskiy 			c->unchecked_size -= len;
798f97117d1SArtem B. Bityutskiy 			ref->flash_offset = ref_offset(ref) | REF_NORMAL;
799f97117d1SArtem B. Bityutskiy 			spin_unlock(&c->erase_completion_lock);
800f97117d1SArtem B. Bityutskiy 		}
801f97117d1SArtem B. Bityutskiy 	}
802f97117d1SArtem B. Bityutskiy 
803f97117d1SArtem B. Bityutskiy 	tn->fn = jffs2_alloc_full_dnode();
804f97117d1SArtem B. Bityutskiy 	if (!tn->fn) {
805e0d60137SArtem B. Bityutskiy 		JFFS2_ERROR("alloc fn failed\n");
8061e0da3cbSArtem B. Bityutskiy 		ret = -ENOMEM;
8071e0da3cbSArtem B. Bityutskiy 		goto free_out;
808f97117d1SArtem B. Bityutskiy 	}
809f97117d1SArtem B. Bityutskiy 
810f97117d1SArtem B. Bityutskiy 	tn->version = je32_to_cpu(rd->version);
811f97117d1SArtem B. Bityutskiy 	tn->fn->ofs = je32_to_cpu(rd->offset);
8121e0da3cbSArtem B. Bityutskiy 	tn->data_crc = je32_to_cpu(rd->data_crc);
8131e0da3cbSArtem B. Bityutskiy 	tn->csize = csize;
814f97117d1SArtem B. Bityutskiy 	tn->fn->raw = ref;
815df8e96f3SDavid Woodhouse 	tn->overlapped = 0;
816df8e96f3SDavid Woodhouse 
817df8e96f3SDavid Woodhouse 	if (tn->version > rii->highest_version)
818df8e96f3SDavid Woodhouse 		rii->highest_version = tn->version;
819f97117d1SArtem B. Bityutskiy 
820f97117d1SArtem B. Bityutskiy 	/* There was a bug where we wrote hole nodes out with
821f97117d1SArtem B. Bityutskiy 	   csize/dsize swapped. Deal with it */
8221e0da3cbSArtem B. Bityutskiy 	if (rd->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(rd->dsize) && csize)
8231e0da3cbSArtem B. Bityutskiy 		tn->fn->size = csize;
824f97117d1SArtem B. Bityutskiy 	else // normal case...
825f97117d1SArtem B. Bityutskiy 		tn->fn->size = je32_to_cpu(rd->dsize);
826f97117d1SArtem B. Bityutskiy 
827733802d9SArtem B. Bityutskiy 	dbg_readinode("dnode @%08x: ver %u, offset %#04x, dsize %#04x, csize %#04x\n",
828280562b2SArtem B. Bityutskiy 		  ref_offset(ref), je32_to_cpu(rd->version), je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize), csize);
829f97117d1SArtem B. Bityutskiy 
830df8e96f3SDavid Woodhouse 	ret = jffs2_add_tn_to_tree(c, rii, tn);
831f97117d1SArtem B. Bityutskiy 
832df8e96f3SDavid Woodhouse 	if (ret) {
833df8e96f3SDavid Woodhouse 		jffs2_free_full_dnode(tn->fn);
8341e0da3cbSArtem B. Bityutskiy 	free_out:
8351e0da3cbSArtem B. Bityutskiy 		jffs2_free_tmp_dnode_info(tn);
8361e0da3cbSArtem B. Bityutskiy 		return ret;
837f97117d1SArtem B. Bityutskiy 	}
838df8e96f3SDavid Woodhouse #ifdef JFFS2_DBG_READINODE_MESSAGES
8391123e2a8SDavid Woodhouse 	dbg_readinode("After adding ver %d:\n", je32_to_cpu(rd->version));
840df8e96f3SDavid Woodhouse 	tn = tn_first(&rii->tn_root);
841df8e96f3SDavid Woodhouse 	while (tn) {
842df8e96f3SDavid Woodhouse 		dbg_readinode("%p: v %d r 0x%x-0x%x ov %d\n",
843df8e96f3SDavid Woodhouse 			     tn, tn->version, tn->fn->ofs,
844df8e96f3SDavid Woodhouse 			     tn->fn->ofs+tn->fn->size, tn->overlapped);
845df8e96f3SDavid Woodhouse 		tn = tn_next(tn);
846df8e96f3SDavid Woodhouse 	}
847df8e96f3SDavid Woodhouse #endif
848df8e96f3SDavid Woodhouse 	return 0;
849df8e96f3SDavid Woodhouse }
850f97117d1SArtem B. Bityutskiy 
851f97117d1SArtem B. Bityutskiy /*
852f97117d1SArtem B. Bityutskiy  * Helper function for jffs2_get_inode_nodes().
853f97117d1SArtem B. Bityutskiy  * It is called every time an unknown node is found.
854f97117d1SArtem B. Bityutskiy  *
8553877f0b6SDavid Woodhouse  * Returns: 0 on success;
856f97117d1SArtem B. Bityutskiy  * 	    negative error code on failure.
857f97117d1SArtem B. Bityutskiy  */
8581e0da3cbSArtem B. Bityutskiy static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un)
859f97117d1SArtem B. Bityutskiy {
860f97117d1SArtem B. Bityutskiy 	/* We don't mark unknown nodes as REF_UNCHECKED */
861c7258a44SDavid Woodhouse 	if (ref_flags(ref) == REF_UNCHECKED) {
862c7258a44SDavid Woodhouse 		JFFS2_ERROR("REF_UNCHECKED but unknown node at %#08x\n",
863c7258a44SDavid Woodhouse 			    ref_offset(ref));
864c7258a44SDavid Woodhouse 		JFFS2_ERROR("Node is {%04x,%04x,%08x,%08x}. Please report this error.\n",
865c7258a44SDavid Woodhouse                             je16_to_cpu(un->magic), je16_to_cpu(un->nodetype),
866c7258a44SDavid Woodhouse                             je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc));
867df8e96f3SDavid Woodhouse 		jffs2_mark_node_obsolete(c, ref);
868df8e96f3SDavid Woodhouse 		return 0;
869c7258a44SDavid Woodhouse 	}
870f97117d1SArtem B. Bityutskiy 
871f97117d1SArtem B. Bityutskiy 	un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype));
872f97117d1SArtem B. Bityutskiy 
873f97117d1SArtem B. Bityutskiy 	switch(je16_to_cpu(un->nodetype) & JFFS2_COMPAT_MASK) {
874f97117d1SArtem B. Bityutskiy 
875f97117d1SArtem B. Bityutskiy 	case JFFS2_FEATURE_INCOMPAT:
876e0d60137SArtem B. Bityutskiy 		JFFS2_ERROR("unknown INCOMPAT nodetype %#04X at %#08x\n",
877f97117d1SArtem B. Bityutskiy 			    je16_to_cpu(un->nodetype), ref_offset(ref));
878f97117d1SArtem B. Bityutskiy 		/* EEP */
879f97117d1SArtem B. Bityutskiy 		BUG();
880f97117d1SArtem B. Bityutskiy 		break;
881f97117d1SArtem B. Bityutskiy 
882f97117d1SArtem B. Bityutskiy 	case JFFS2_FEATURE_ROCOMPAT:
883e0d60137SArtem B. Bityutskiy 		JFFS2_ERROR("unknown ROCOMPAT nodetype %#04X at %#08x\n",
884f97117d1SArtem B. Bityutskiy 			    je16_to_cpu(un->nodetype), ref_offset(ref));
885f97117d1SArtem B. Bityutskiy 		BUG_ON(!(c->flags & JFFS2_SB_FLAG_RO));
886f97117d1SArtem B. Bityutskiy 		break;
887f97117d1SArtem B. Bityutskiy 
888f97117d1SArtem B. Bityutskiy 	case JFFS2_FEATURE_RWCOMPAT_COPY:
889e0d60137SArtem B. Bityutskiy 		JFFS2_NOTICE("unknown RWCOMPAT_COPY nodetype %#04X at %#08x\n",
890f97117d1SArtem B. Bityutskiy 			     je16_to_cpu(un->nodetype), ref_offset(ref));
891f97117d1SArtem B. Bityutskiy 		break;
892f97117d1SArtem B. Bityutskiy 
893f97117d1SArtem B. Bityutskiy 	case JFFS2_FEATURE_RWCOMPAT_DELETE:
894e0d60137SArtem B. Bityutskiy 		JFFS2_NOTICE("unknown RWCOMPAT_DELETE nodetype %#04X at %#08x\n",
895f97117d1SArtem B. Bityutskiy 			     je16_to_cpu(un->nodetype), ref_offset(ref));
896df8e96f3SDavid Woodhouse 		jffs2_mark_node_obsolete(c, ref);
897df8e96f3SDavid Woodhouse 		return 0;
898f97117d1SArtem B. Bityutskiy 	}
899f97117d1SArtem B. Bityutskiy 
900f97117d1SArtem B. Bityutskiy 	return 0;
901f97117d1SArtem B. Bityutskiy }
902f97117d1SArtem B. Bityutskiy 
9031e0da3cbSArtem B. Bityutskiy /*
9041e0da3cbSArtem B. Bityutskiy  * Helper function for jffs2_get_inode_nodes().
9051e0da3cbSArtem B. Bityutskiy  * The function detects whether more data should be read and reads it if yes.
9061e0da3cbSArtem B. Bityutskiy  *
9071e0da3cbSArtem B. Bityutskiy  * Returns: 0 on succes;
9081e0da3cbSArtem B. Bityutskiy  * 	    negative error code on failure.
9091e0da3cbSArtem B. Bityutskiy  */
9101e0da3cbSArtem B. Bityutskiy static int read_more(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref,
91110731f83SArtem Bityutskiy 		     int needed_len, int *rdlen, unsigned char *buf)
9121e0da3cbSArtem B. Bityutskiy {
91310731f83SArtem Bityutskiy 	int err, to_read = needed_len - *rdlen;
9141e0da3cbSArtem B. Bityutskiy 	size_t retlen;
9151e0da3cbSArtem B. Bityutskiy 	uint32_t offs;
9161e0da3cbSArtem B. Bityutskiy 
9171e0da3cbSArtem B. Bityutskiy 	if (jffs2_is_writebuffered(c)) {
91810731f83SArtem Bityutskiy 		int rem = to_read % c->wbuf_pagesize;
9191e0da3cbSArtem B. Bityutskiy 
92010731f83SArtem Bityutskiy 		if (rem)
92110731f83SArtem Bityutskiy 			to_read += c->wbuf_pagesize - rem;
92210731f83SArtem Bityutskiy 	}
9231e0da3cbSArtem B. Bityutskiy 
9241e0da3cbSArtem B. Bityutskiy 	/* We need to read more data */
9251e0da3cbSArtem B. Bityutskiy 	offs = ref_offset(ref) + *rdlen;
9261e0da3cbSArtem B. Bityutskiy 
92710731f83SArtem Bityutskiy 	dbg_readinode("read more %d bytes\n", to_read);
9281e0da3cbSArtem B. Bityutskiy 
92910731f83SArtem Bityutskiy 	err = jffs2_flash_read(c, offs, to_read, &retlen, buf + *rdlen);
9301e0da3cbSArtem B. Bityutskiy 	if (err) {
9311e0da3cbSArtem B. Bityutskiy 		JFFS2_ERROR("can not read %d bytes from 0x%08x, "
93210731f83SArtem Bityutskiy 			"error code: %d.\n", to_read, offs, err);
9331e0da3cbSArtem B. Bityutskiy 		return err;
9341e0da3cbSArtem B. Bityutskiy 	}
9351e0da3cbSArtem B. Bityutskiy 
93610731f83SArtem Bityutskiy 	if (retlen < to_read) {
937fb6a82c9SRandy Dunlap 		JFFS2_ERROR("short read at %#08x: %zu instead of %d.\n",
93810731f83SArtem Bityutskiy 				offs, retlen, to_read);
9391e0da3cbSArtem B. Bityutskiy 		return -EIO;
9401e0da3cbSArtem B. Bityutskiy 	}
9411e0da3cbSArtem B. Bityutskiy 
94210731f83SArtem Bityutskiy 	*rdlen += to_read;
9431e0da3cbSArtem B. Bityutskiy 	return 0;
9441e0da3cbSArtem B. Bityutskiy }
9451e0da3cbSArtem B. Bityutskiy 
946f97117d1SArtem B. Bityutskiy /* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated
947df8e96f3SDavid Woodhouse    with this ino. Perform a preliminary ordering on data nodes, throwing away
948df8e96f3SDavid Woodhouse    those which are completely obsoleted by newer ones. The naïve approach we
949df8e96f3SDavid Woodhouse    use to take of just returning them _all_ in version order will cause us to
950df8e96f3SDavid Woodhouse    run out of memory in certain degenerate cases. */
951f97117d1SArtem B. Bityutskiy static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
952df8e96f3SDavid Woodhouse 				 struct jffs2_readinode_info *rii)
953f97117d1SArtem B. Bityutskiy {
954f97117d1SArtem B. Bityutskiy 	struct jffs2_raw_node_ref *ref, *valid_ref;
9551e0da3cbSArtem B. Bityutskiy 	unsigned char *buf = NULL;
9561e0da3cbSArtem B. Bityutskiy 	union jffs2_node_union *node;
957f97117d1SArtem B. Bityutskiy 	size_t retlen;
9581e0da3cbSArtem B. Bityutskiy 	int len, err;
959f97117d1SArtem B. Bityutskiy 
960df8e96f3SDavid Woodhouse 	rii->mctime_ver = 0;
961f97117d1SArtem B. Bityutskiy 
962733802d9SArtem B. Bityutskiy 	dbg_readinode("ino #%u\n", f->inocache->ino);
963f97117d1SArtem B. Bityutskiy 
9641e0da3cbSArtem B. Bityutskiy 	/* FIXME: in case of NOR and available ->point() this
9651e0da3cbSArtem B. Bityutskiy 	 * needs to be fixed. */
96610731f83SArtem Bityutskiy 	len = sizeof(union jffs2_node_union) + c->wbuf_pagesize;
9671e0da3cbSArtem B. Bityutskiy 	buf = kmalloc(len, GFP_KERNEL);
9681e0da3cbSArtem B. Bityutskiy 	if (!buf)
9691e0da3cbSArtem B. Bityutskiy 		return -ENOMEM;
9701e0da3cbSArtem B. Bityutskiy 
971f97117d1SArtem B. Bityutskiy 	spin_lock(&c->erase_completion_lock);
972f97117d1SArtem B. Bityutskiy 	valid_ref = jffs2_first_valid_node(f->inocache->nodes);
9731e0da3cbSArtem B. Bityutskiy 	if (!valid_ref && f->inocache->ino != 1)
9741e0da3cbSArtem B. Bityutskiy 		JFFS2_WARNING("Eep. No valid nodes for ino #%u.\n", f->inocache->ino);
975f97117d1SArtem B. Bityutskiy 	while (valid_ref) {
976f97117d1SArtem B. Bityutskiy 		/* We can hold a pointer to a non-obsolete node without the spinlock,
977f97117d1SArtem B. Bityutskiy 		   but _obsolete_ nodes may disappear at any time, if the block
978f97117d1SArtem B. Bityutskiy 		   they're in gets erased. So if we mark 'ref' obsolete while we're
979f97117d1SArtem B. Bityutskiy 		   not holding the lock, it can go away immediately. For that reason,
980f97117d1SArtem B. Bityutskiy 		   we find the next valid node first, before processing 'ref'.
981f97117d1SArtem B. Bityutskiy 		*/
982f97117d1SArtem B. Bityutskiy 		ref = valid_ref;
983f97117d1SArtem B. Bityutskiy 		valid_ref = jffs2_first_valid_node(ref->next_in_ino);
984f97117d1SArtem B. Bityutskiy 		spin_unlock(&c->erase_completion_lock);
985f97117d1SArtem B. Bityutskiy 
986f97117d1SArtem B. Bityutskiy 		cond_resched();
987f97117d1SArtem B. Bityutskiy 
9881e0da3cbSArtem B. Bityutskiy 		/*
9891e0da3cbSArtem B. Bityutskiy 		 * At this point we don't know the type of the node we're going
9901e0da3cbSArtem B. Bityutskiy 		 * to read, so we do not know the size of its header. In order
99110731f83SArtem Bityutskiy 		 * to minimize the amount of flash IO we assume the header is
99210731f83SArtem Bityutskiy 		 * of size = JFFS2_MIN_NODE_HEADER.
9931e0da3cbSArtem B. Bityutskiy 		 */
9941e0da3cbSArtem B. Bityutskiy 		len = JFFS2_MIN_NODE_HEADER;
99510731f83SArtem Bityutskiy 		if (jffs2_is_writebuffered(c)) {
99610731f83SArtem Bityutskiy 			int end, rem;
99710731f83SArtem Bityutskiy 
99810731f83SArtem Bityutskiy 			/*
99910731f83SArtem Bityutskiy 			 * We are about to read JFFS2_MIN_NODE_HEADER bytes,
100010731f83SArtem Bityutskiy 			 * but this flash has some minimal I/O unit. It is
100110731f83SArtem Bityutskiy 			 * possible that we'll need to read more soon, so read
100210731f83SArtem Bityutskiy 			 * up to the next min. I/O unit, in order not to
100310731f83SArtem Bityutskiy 			 * re-read the same min. I/O unit twice.
100410731f83SArtem Bityutskiy 			 */
100510731f83SArtem Bityutskiy 			end = ref_offset(ref) + len;
100610731f83SArtem Bityutskiy 			rem = end % c->wbuf_pagesize;
100710731f83SArtem Bityutskiy 			if (rem)
100810731f83SArtem Bityutskiy 				end += c->wbuf_pagesize - rem;
100910731f83SArtem Bityutskiy 			len = end - ref_offset(ref);
10101e0da3cbSArtem B. Bityutskiy 		}
10111e0da3cbSArtem B. Bityutskiy 
1012733802d9SArtem B. Bityutskiy 		dbg_readinode("read %d bytes at %#08x(%d).\n", len, ref_offset(ref), ref_flags(ref));
10131e0da3cbSArtem B. Bityutskiy 
1014f97117d1SArtem B. Bityutskiy 		/* FIXME: point() */
101510731f83SArtem Bityutskiy 		err = jffs2_flash_read(c, ref_offset(ref), len, &retlen, buf);
1016f97117d1SArtem B. Bityutskiy 		if (err) {
10171e0da3cbSArtem B. Bityutskiy 			JFFS2_ERROR("can not read %d bytes from 0x%08x, " "error code: %d.\n", len, ref_offset(ref), err);
1018f97117d1SArtem B. Bityutskiy 			goto free_out;
1019f97117d1SArtem B. Bityutskiy 		}
1020f97117d1SArtem B. Bityutskiy 
10211e0da3cbSArtem B. Bityutskiy 		if (retlen < len) {
1022fb6a82c9SRandy Dunlap 			JFFS2_ERROR("short read at %#08x: %zu instead of %d.\n", ref_offset(ref), retlen, len);
1023f97117d1SArtem B. Bityutskiy 			err = -EIO;
1024f97117d1SArtem B. Bityutskiy 			goto free_out;
1025f97117d1SArtem B. Bityutskiy 		}
1026f97117d1SArtem B. Bityutskiy 
102710731f83SArtem Bityutskiy 		node = (union jffs2_node_union *)buf;
10281e0da3cbSArtem B. Bityutskiy 
10293877f0b6SDavid Woodhouse 		/* No need to mask in the valid bit; it shouldn't be invalid */
10303877f0b6SDavid Woodhouse 		if (je32_to_cpu(node->u.hdr_crc) != crc32(0, node, sizeof(node->u)-4)) {
10313877f0b6SDavid Woodhouse 			JFFS2_NOTICE("Node header CRC failed at %#08x. {%04x,%04x,%08x,%08x}\n",
10323877f0b6SDavid Woodhouse 				     ref_offset(ref), je16_to_cpu(node->u.magic),
10333877f0b6SDavid Woodhouse 				     je16_to_cpu(node->u.nodetype),
10343877f0b6SDavid Woodhouse 				     je32_to_cpu(node->u.totlen),
10353877f0b6SDavid Woodhouse 				     je32_to_cpu(node->u.hdr_crc));
10363877f0b6SDavid Woodhouse 			jffs2_dbg_dump_node(c, ref_offset(ref));
10373877f0b6SDavid Woodhouse 			jffs2_mark_node_obsolete(c, ref);
10383877f0b6SDavid Woodhouse 			goto cont;
10393877f0b6SDavid Woodhouse 		}
10400dec4c8bSJoakim Tjernlund 		if (je16_to_cpu(node->u.magic) != JFFS2_MAGIC_BITMASK) {
10410dec4c8bSJoakim Tjernlund 			/* Not a JFFS2 node, whinge and move on */
10420dec4c8bSJoakim Tjernlund 			JFFS2_NOTICE("Wrong magic bitmask 0x%04x in node header at %#08x.\n",
10430dec4c8bSJoakim Tjernlund 				     je16_to_cpu(node->u.magic), ref_offset(ref));
1044c7258a44SDavid Woodhouse 			jffs2_mark_node_obsolete(c, ref);
1045c7258a44SDavid Woodhouse 			goto cont;
1046c7258a44SDavid Woodhouse 		}
10473877f0b6SDavid Woodhouse 
10481e0da3cbSArtem B. Bityutskiy 		switch (je16_to_cpu(node->u.nodetype)) {
10491e0da3cbSArtem B. Bityutskiy 
10501e0da3cbSArtem B. Bityutskiy 		case JFFS2_NODETYPE_DIRENT:
10511e0da3cbSArtem B. Bityutskiy 
1052ea55d307SArtem Bityutskiy 			if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent) &&
1053ea55d307SArtem Bityutskiy 			    len < sizeof(struct jffs2_raw_dirent)) {
105410731f83SArtem Bityutskiy 				err = read_more(c, ref, sizeof(struct jffs2_raw_dirent), &len, buf);
10551e0da3cbSArtem B. Bityutskiy 				if (unlikely(err))
10561e0da3cbSArtem B. Bityutskiy 					goto free_out;
10571e0da3cbSArtem B. Bityutskiy 			}
10581e0da3cbSArtem B. Bityutskiy 
1059df8e96f3SDavid Woodhouse 			err = read_direntry(c, ref, &node->d, retlen, rii);
1060df8e96f3SDavid Woodhouse 			if (unlikely(err))
1061f97117d1SArtem B. Bityutskiy 				goto free_out;
1062f97117d1SArtem B. Bityutskiy 
1063f97117d1SArtem B. Bityutskiy 			break;
1064f97117d1SArtem B. Bityutskiy 
1065f97117d1SArtem B. Bityutskiy 		case JFFS2_NODETYPE_INODE:
1066f97117d1SArtem B. Bityutskiy 
1067ea55d307SArtem Bityutskiy 			if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode) &&
1068ea55d307SArtem Bityutskiy 			    len < sizeof(struct jffs2_raw_inode)) {
106910731f83SArtem Bityutskiy 				err = read_more(c, ref, sizeof(struct jffs2_raw_inode), &len, buf);
10701e0da3cbSArtem B. Bityutskiy 				if (unlikely(err))
1071f97117d1SArtem B. Bityutskiy 					goto free_out;
1072f97117d1SArtem B. Bityutskiy 			}
1073f97117d1SArtem B. Bityutskiy 
1074df8e96f3SDavid Woodhouse 			err = read_dnode(c, ref, &node->i, len, rii);
1075df8e96f3SDavid Woodhouse 			if (unlikely(err))
1076f97117d1SArtem B. Bityutskiy 				goto free_out;
1077f97117d1SArtem B. Bityutskiy 
10781da177e4SLinus Torvalds 			break;
10791da177e4SLinus Torvalds 
10801da177e4SLinus Torvalds 		default:
1081ea55d307SArtem Bityutskiy 			if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_unknown_node) &&
1082ea55d307SArtem Bityutskiy 			    len < sizeof(struct jffs2_unknown_node)) {
108310731f83SArtem Bityutskiy 				err = read_more(c, ref, sizeof(struct jffs2_unknown_node), &len, buf);
10841e0da3cbSArtem B. Bityutskiy 				if (unlikely(err))
10851e0da3cbSArtem B. Bityutskiy 					goto free_out;
10861da177e4SLinus Torvalds 			}
10871da177e4SLinus Torvalds 
10881e0da3cbSArtem B. Bityutskiy 			err = read_unknown(c, ref, &node->u);
108914c6381eSDavid Woodhouse 			if (unlikely(err))
1090f97117d1SArtem B. Bityutskiy 				goto free_out;
1091f97117d1SArtem B. Bityutskiy 
10921da177e4SLinus Torvalds 		}
10933877f0b6SDavid Woodhouse 	cont:
1094f97117d1SArtem B. Bityutskiy 		spin_lock(&c->erase_completion_lock);
10951da177e4SLinus Torvalds 	}
10961e0da3cbSArtem B. Bityutskiy 
1097f97117d1SArtem B. Bityutskiy 	spin_unlock(&c->erase_completion_lock);
10981e0da3cbSArtem B. Bityutskiy 	kfree(buf);
1099f97117d1SArtem B. Bityutskiy 
1100df8e96f3SDavid Woodhouse 	f->highest_version = rii->highest_version;
1101df8e96f3SDavid Woodhouse 
1102733802d9SArtem B. Bityutskiy 	dbg_readinode("nodes of inode #%u were read, the highest version is %u, latest_mctime %u, mctime_ver %u.\n",
1103df8e96f3SDavid Woodhouse 		      f->inocache->ino, rii->highest_version, rii->latest_mctime,
1104df8e96f3SDavid Woodhouse 		      rii->mctime_ver);
1105f97117d1SArtem B. Bityutskiy 	return 0;
1106f97117d1SArtem B. Bityutskiy 
1107f97117d1SArtem B. Bityutskiy  free_out:
1108df8e96f3SDavid Woodhouse 	jffs2_free_tmp_dnode_info_list(&rii->tn_root);
1109df8e96f3SDavid Woodhouse 	jffs2_free_full_dirent_list(rii->fds);
1110df8e96f3SDavid Woodhouse 	rii->fds = NULL;
11111e0da3cbSArtem B. Bityutskiy 	kfree(buf);
1112f97117d1SArtem B. Bityutskiy 	return err;
11131da177e4SLinus Torvalds }
11141da177e4SLinus Torvalds 
11151da177e4SLinus Torvalds static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
11161da177e4SLinus Torvalds 					struct jffs2_inode_info *f,
11171da177e4SLinus Torvalds 					struct jffs2_raw_inode *latest_node)
11181da177e4SLinus Torvalds {
1119df8e96f3SDavid Woodhouse 	struct jffs2_readinode_info rii;
112061c4b237SDavid Woodhouse 	uint32_t crc, new_size;
11211da177e4SLinus Torvalds 	size_t retlen;
11221da177e4SLinus Torvalds 	int ret;
11231da177e4SLinus Torvalds 
1124733802d9SArtem B. Bityutskiy 	dbg_readinode("ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink);
11251da177e4SLinus Torvalds 
1126df8e96f3SDavid Woodhouse 	memset(&rii, 0, sizeof(rii));
1127df8e96f3SDavid Woodhouse 
11281da177e4SLinus Torvalds 	/* Grab all nodes relevant to this ino */
1129df8e96f3SDavid Woodhouse 	ret = jffs2_get_inode_nodes(c, f, &rii);
11301da177e4SLinus Torvalds 
11311da177e4SLinus Torvalds 	if (ret) {
1132e0d60137SArtem B. Bityutskiy 		JFFS2_ERROR("cannot read nodes for ino %u, returned error is %d\n", f->inocache->ino, ret);
11331da177e4SLinus Torvalds 		if (f->inocache->state == INO_STATE_READING)
11341da177e4SLinus Torvalds 			jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
11351da177e4SLinus Torvalds 		return ret;
11361da177e4SLinus Torvalds 	}
11371da177e4SLinus Torvalds 
1138df8e96f3SDavid Woodhouse 	ret = jffs2_build_inode_fragtree(c, f, &rii);
11391e0da3cbSArtem B. Bityutskiy 	if (ret) {
1140df8e96f3SDavid Woodhouse 		JFFS2_ERROR("Failed to build final fragtree for inode #%u: error %d\n",
1141df8e96f3SDavid Woodhouse 			    f->inocache->ino, ret);
1142df8e96f3SDavid Woodhouse 		if (f->inocache->state == INO_STATE_READING)
1143df8e96f3SDavid Woodhouse 			jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
1144df8e96f3SDavid Woodhouse 		jffs2_free_tmp_dnode_info_list(&rii.tn_root);
1145df8e96f3SDavid Woodhouse 		/* FIXME: We could at least crc-check them all */
1146df8e96f3SDavid Woodhouse 		if (rii.mdata_tn) {
1147df8e96f3SDavid Woodhouse 			jffs2_free_full_dnode(rii.mdata_tn->fn);
1148df8e96f3SDavid Woodhouse 			jffs2_free_tmp_dnode_info(rii.mdata_tn);
1149df8e96f3SDavid Woodhouse 			rii.mdata_tn = NULL;
11501e0da3cbSArtem B. Bityutskiy 		}
1151df8e96f3SDavid Woodhouse 		return ret;
11521da177e4SLinus Torvalds 	}
1153df8e96f3SDavid Woodhouse 
1154df8e96f3SDavid Woodhouse 	if (rii.mdata_tn) {
1155df8e96f3SDavid Woodhouse 		if (rii.mdata_tn->fn->raw == rii.latest_ref) {
1156df8e96f3SDavid Woodhouse 			f->metadata = rii.mdata_tn->fn;
1157df8e96f3SDavid Woodhouse 			jffs2_free_tmp_dnode_info(rii.mdata_tn);
1158df8e96f3SDavid Woodhouse 		} else {
1159df8e96f3SDavid Woodhouse 			jffs2_kill_tn(c, rii.mdata_tn);
1160df8e96f3SDavid Woodhouse 		}
1161df8e96f3SDavid Woodhouse 		rii.mdata_tn = NULL;
1162df8e96f3SDavid Woodhouse 	}
1163df8e96f3SDavid Woodhouse 
1164df8e96f3SDavid Woodhouse 	f->dents = rii.fds;
1165df8e96f3SDavid Woodhouse 
1166e0c8e42fSArtem B. Bityutskiy 	jffs2_dbg_fragtree_paranoia_check_nolock(f);
11671da177e4SLinus Torvalds 
1168df8e96f3SDavid Woodhouse 	if (unlikely(!rii.latest_ref)) {
11691da177e4SLinus Torvalds 		/* No data nodes for this inode. */
11701da177e4SLinus Torvalds 		if (f->inocache->ino != 1) {
1171e0d60137SArtem B. Bityutskiy 			JFFS2_WARNING("no data nodes found for ino #%u\n", f->inocache->ino);
1172df8e96f3SDavid Woodhouse 			if (!rii.fds) {
11731da177e4SLinus Torvalds 				if (f->inocache->state == INO_STATE_READING)
11741da177e4SLinus Torvalds 					jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
11751da177e4SLinus Torvalds 				return -EIO;
11761da177e4SLinus Torvalds 			}
1177e0d60137SArtem B. Bityutskiy 			JFFS2_NOTICE("but it has children so we fake some modes for it\n");
11781da177e4SLinus Torvalds 		}
11791da177e4SLinus Torvalds 		latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO);
11801da177e4SLinus Torvalds 		latest_node->version = cpu_to_je32(0);
11811da177e4SLinus Torvalds 		latest_node->atime = latest_node->ctime = latest_node->mtime = cpu_to_je32(0);
11821da177e4SLinus Torvalds 		latest_node->isize = cpu_to_je32(0);
11831da177e4SLinus Torvalds 		latest_node->gid = cpu_to_je16(0);
11841da177e4SLinus Torvalds 		latest_node->uid = cpu_to_je16(0);
11851da177e4SLinus Torvalds 		if (f->inocache->state == INO_STATE_READING)
11861da177e4SLinus Torvalds 			jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
11871da177e4SLinus Torvalds 		return 0;
11881da177e4SLinus Torvalds 	}
11891da177e4SLinus Torvalds 
1190df8e96f3SDavid Woodhouse 	ret = jffs2_flash_read(c, ref_offset(rii.latest_ref), sizeof(*latest_node), &retlen, (void *)latest_node);
11911da177e4SLinus Torvalds 	if (ret || retlen != sizeof(*latest_node)) {
1192e0d60137SArtem B. Bityutskiy 		JFFS2_ERROR("failed to read from flash: error %d, %zd of %zd bytes read\n",
11931da177e4SLinus Torvalds 			ret, retlen, sizeof(*latest_node));
11941da177e4SLinus Torvalds 		/* FIXME: If this fails, there seems to be a memory leak. Find it. */
11951da177e4SLinus Torvalds 		up(&f->sem);
11961da177e4SLinus Torvalds 		jffs2_do_clear_inode(c, f);
11971da177e4SLinus Torvalds 		return ret?ret:-EIO;
11981da177e4SLinus Torvalds 	}
11991da177e4SLinus Torvalds 
12001da177e4SLinus Torvalds 	crc = crc32(0, latest_node, sizeof(*latest_node)-8);
12011da177e4SLinus Torvalds 	if (crc != je32_to_cpu(latest_node->node_crc)) {
1202e0d60137SArtem B. Bityutskiy 		JFFS2_ERROR("CRC failed for read_inode of inode %u at physical location 0x%x\n",
1203df8e96f3SDavid Woodhouse 			f->inocache->ino, ref_offset(rii.latest_ref));
12041da177e4SLinus Torvalds 		up(&f->sem);
12051da177e4SLinus Torvalds 		jffs2_do_clear_inode(c, f);
12061da177e4SLinus Torvalds 		return -EIO;
12071da177e4SLinus Torvalds 	}
12081da177e4SLinus Torvalds 
12091da177e4SLinus Torvalds 	switch(jemode_to_cpu(latest_node->mode) & S_IFMT) {
12101da177e4SLinus Torvalds 	case S_IFDIR:
1211df8e96f3SDavid Woodhouse 		if (rii.mctime_ver > je32_to_cpu(latest_node->version)) {
12121da177e4SLinus Torvalds 			/* The times in the latest_node are actually older than
12131da177e4SLinus Torvalds 			   mctime in the latest dirent. Cheat. */
1214df8e96f3SDavid Woodhouse 			latest_node->ctime = latest_node->mtime = cpu_to_je32(rii.latest_mctime);
12151da177e4SLinus Torvalds 		}
12161da177e4SLinus Torvalds 		break;
12171da177e4SLinus Torvalds 
12181da177e4SLinus Torvalds 
12191da177e4SLinus Torvalds 	case S_IFREG:
12201da177e4SLinus Torvalds 		/* If it was a regular file, truncate it to the latest node's isize */
122161c4b237SDavid Woodhouse 		new_size = jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize));
122261c4b237SDavid Woodhouse 		if (new_size != je32_to_cpu(latest_node->isize)) {
122361c4b237SDavid Woodhouse 			JFFS2_WARNING("Truncating ino #%u to %d bytes failed because it only had %d bytes to start with!\n",
122461c4b237SDavid Woodhouse 				      f->inocache->ino, je32_to_cpu(latest_node->isize), new_size);
122561c4b237SDavid Woodhouse 			latest_node->isize = cpu_to_je32(new_size);
122661c4b237SDavid Woodhouse 		}
12271da177e4SLinus Torvalds 		break;
12281da177e4SLinus Torvalds 
12291da177e4SLinus Torvalds 	case S_IFLNK:
12301da177e4SLinus Torvalds 		/* Hack to work around broken isize in old symlink code.
12311da177e4SLinus Torvalds 		   Remove this when dwmw2 comes to his senses and stops
12321da177e4SLinus Torvalds 		   symlinks from being an entirely gratuitous special
12331da177e4SLinus Torvalds 		   case. */
12341da177e4SLinus Torvalds 		if (!je32_to_cpu(latest_node->isize))
12351da177e4SLinus Torvalds 			latest_node->isize = latest_node->dsize;
123632f1a95dSArtem B. Bityuckiy 
123732f1a95dSArtem B. Bityuckiy 		if (f->inocache->state != INO_STATE_CHECKING) {
123832f1a95dSArtem B. Bityuckiy 			/* Symlink's inode data is the target path. Read it and
12392b79adccSArtem B. Bityutskiy 			 * keep in RAM to facilitate quick follow symlink
12402b79adccSArtem B. Bityutskiy 			 * operation. */
12412b79adccSArtem B. Bityutskiy 			f->target = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL);
12422b79adccSArtem B. Bityutskiy 			if (!f->target) {
1243e0d60137SArtem B. Bityutskiy 				JFFS2_ERROR("can't allocate %d bytes of memory for the symlink target path cache\n", je32_to_cpu(latest_node->csize));
124432f1a95dSArtem B. Bityuckiy 				up(&f->sem);
124532f1a95dSArtem B. Bityuckiy 				jffs2_do_clear_inode(c, f);
124632f1a95dSArtem B. Bityuckiy 				return -ENOMEM;
124732f1a95dSArtem B. Bityuckiy 			}
124832f1a95dSArtem B. Bityuckiy 
1249df8e96f3SDavid Woodhouse 			ret = jffs2_flash_read(c, ref_offset(rii.latest_ref) + sizeof(*latest_node),
12502b79adccSArtem B. Bityutskiy 						je32_to_cpu(latest_node->csize), &retlen, (char *)f->target);
125132f1a95dSArtem B. Bityuckiy 
125232f1a95dSArtem B. Bityuckiy 			if (ret  || retlen != je32_to_cpu(latest_node->csize)) {
125332f1a95dSArtem B. Bityuckiy 				if (retlen != je32_to_cpu(latest_node->csize))
125432f1a95dSArtem B. Bityuckiy 					ret = -EIO;
12552b79adccSArtem B. Bityutskiy 				kfree(f->target);
12562b79adccSArtem B. Bityutskiy 				f->target = NULL;
125732f1a95dSArtem B. Bityuckiy 				up(&f->sem);
125832f1a95dSArtem B. Bityuckiy 				jffs2_do_clear_inode(c, f);
125932f1a95dSArtem B. Bityuckiy 				return -ret;
126032f1a95dSArtem B. Bityuckiy 			}
126132f1a95dSArtem B. Bityuckiy 
12622b79adccSArtem B. Bityutskiy 			f->target[je32_to_cpu(latest_node->csize)] = '\0';
1263733802d9SArtem B. Bityutskiy 			dbg_readinode("symlink's target '%s' cached\n", f->target);
126432f1a95dSArtem B. Bityuckiy 		}
126532f1a95dSArtem B. Bityuckiy 
12661da177e4SLinus Torvalds 		/* fall through... */
12671da177e4SLinus Torvalds 
12681da177e4SLinus Torvalds 	case S_IFBLK:
12691da177e4SLinus Torvalds 	case S_IFCHR:
12701da177e4SLinus Torvalds 		/* Certain inode types should have only one data node, and it's
12711da177e4SLinus Torvalds 		   kept as the metadata node */
12721da177e4SLinus Torvalds 		if (f->metadata) {
1273e0d60137SArtem B. Bityutskiy 			JFFS2_ERROR("Argh. Special inode #%u with mode 0%o had metadata node\n",
12741da177e4SLinus Torvalds 			       f->inocache->ino, jemode_to_cpu(latest_node->mode));
12751da177e4SLinus Torvalds 			up(&f->sem);
12761da177e4SLinus Torvalds 			jffs2_do_clear_inode(c, f);
12771da177e4SLinus Torvalds 			return -EIO;
12781da177e4SLinus Torvalds 		}
12791da177e4SLinus Torvalds 		if (!frag_first(&f->fragtree)) {
1280e0d60137SArtem B. Bityutskiy 			JFFS2_ERROR("Argh. Special inode #%u with mode 0%o has no fragments\n",
12811da177e4SLinus Torvalds 			       f->inocache->ino, jemode_to_cpu(latest_node->mode));
12821da177e4SLinus Torvalds 			up(&f->sem);
12831da177e4SLinus Torvalds 			jffs2_do_clear_inode(c, f);
12841da177e4SLinus Torvalds 			return -EIO;
12851da177e4SLinus Torvalds 		}
12861da177e4SLinus Torvalds 		/* ASSERT: f->fraglist != NULL */
12871da177e4SLinus Torvalds 		if (frag_next(frag_first(&f->fragtree))) {
1288e0d60137SArtem B. Bityutskiy 			JFFS2_ERROR("Argh. Special inode #%u with mode 0x%x had more than one node\n",
12891da177e4SLinus Torvalds 			       f->inocache->ino, jemode_to_cpu(latest_node->mode));
12901da177e4SLinus Torvalds 			/* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
12911da177e4SLinus Torvalds 			up(&f->sem);
12921da177e4SLinus Torvalds 			jffs2_do_clear_inode(c, f);
12931da177e4SLinus Torvalds 			return -EIO;
12941da177e4SLinus Torvalds 		}
12951da177e4SLinus Torvalds 		/* OK. We're happy */
12961da177e4SLinus Torvalds 		f->metadata = frag_first(&f->fragtree)->node;
12971da177e4SLinus Torvalds 		jffs2_free_node_frag(frag_first(&f->fragtree));
12981da177e4SLinus Torvalds 		f->fragtree = RB_ROOT;
12991da177e4SLinus Torvalds 		break;
13001da177e4SLinus Torvalds 	}
13011da177e4SLinus Torvalds 	if (f->inocache->state == INO_STATE_READING)
13021da177e4SLinus Torvalds 		jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
13031da177e4SLinus Torvalds 
13041da177e4SLinus Torvalds 	return 0;
13051da177e4SLinus Torvalds }
13061da177e4SLinus Torvalds 
1307f97117d1SArtem B. Bityutskiy /* Scan the list of all nodes present for this ino, build map of versions, etc. */
1308f97117d1SArtem B. Bityutskiy int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
1309f97117d1SArtem B. Bityutskiy 			uint32_t ino, struct jffs2_raw_inode *latest_node)
1310f97117d1SArtem B. Bityutskiy {
1311733802d9SArtem B. Bityutskiy 	dbg_readinode("read inode #%u\n", ino);
1312f97117d1SArtem B. Bityutskiy 
1313f97117d1SArtem B. Bityutskiy  retry_inocache:
1314f97117d1SArtem B. Bityutskiy 	spin_lock(&c->inocache_lock);
1315f97117d1SArtem B. Bityutskiy 	f->inocache = jffs2_get_ino_cache(c, ino);
1316f97117d1SArtem B. Bityutskiy 
1317f97117d1SArtem B. Bityutskiy 	if (f->inocache) {
1318f97117d1SArtem B. Bityutskiy 		/* Check its state. We may need to wait before we can use it */
1319f97117d1SArtem B. Bityutskiy 		switch(f->inocache->state) {
1320f97117d1SArtem B. Bityutskiy 		case INO_STATE_UNCHECKED:
1321f97117d1SArtem B. Bityutskiy 		case INO_STATE_CHECKEDABSENT:
1322f97117d1SArtem B. Bityutskiy 			f->inocache->state = INO_STATE_READING;
1323f97117d1SArtem B. Bityutskiy 			break;
1324f97117d1SArtem B. Bityutskiy 
1325f97117d1SArtem B. Bityutskiy 		case INO_STATE_CHECKING:
1326f97117d1SArtem B. Bityutskiy 		case INO_STATE_GC:
1327f97117d1SArtem B. Bityutskiy 			/* If it's in either of these states, we need
1328f97117d1SArtem B. Bityutskiy 			   to wait for whoever's got it to finish and
1329f97117d1SArtem B. Bityutskiy 			   put it back. */
1330733802d9SArtem B. Bityutskiy 			dbg_readinode("waiting for ino #%u in state %d\n", ino, f->inocache->state);
1331f97117d1SArtem B. Bityutskiy 			sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
1332f97117d1SArtem B. Bityutskiy 			goto retry_inocache;
1333f97117d1SArtem B. Bityutskiy 
1334f97117d1SArtem B. Bityutskiy 		case INO_STATE_READING:
1335f97117d1SArtem B. Bityutskiy 		case INO_STATE_PRESENT:
1336f97117d1SArtem B. Bityutskiy 			/* Eep. This should never happen. It can
1337f97117d1SArtem B. Bityutskiy 			happen if Linux calls read_inode() again
1338f97117d1SArtem B. Bityutskiy 			before clear_inode() has finished though. */
1339e0d60137SArtem B. Bityutskiy 			JFFS2_ERROR("Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state);
1340f97117d1SArtem B. Bityutskiy 			/* Fail. That's probably better than allowing it to succeed */
1341f97117d1SArtem B. Bityutskiy 			f->inocache = NULL;
1342f97117d1SArtem B. Bityutskiy 			break;
1343f97117d1SArtem B. Bityutskiy 
1344f97117d1SArtem B. Bityutskiy 		default:
1345f97117d1SArtem B. Bityutskiy 			BUG();
1346f97117d1SArtem B. Bityutskiy 		}
1347f97117d1SArtem B. Bityutskiy 	}
1348f97117d1SArtem B. Bityutskiy 	spin_unlock(&c->inocache_lock);
1349f97117d1SArtem B. Bityutskiy 
1350f97117d1SArtem B. Bityutskiy 	if (!f->inocache && ino == 1) {
1351f97117d1SArtem B. Bityutskiy 		/* Special case - no root inode on medium */
1352f97117d1SArtem B. Bityutskiy 		f->inocache = jffs2_alloc_inode_cache();
1353f97117d1SArtem B. Bityutskiy 		if (!f->inocache) {
1354e0d60137SArtem B. Bityutskiy 			JFFS2_ERROR("cannot allocate inocache for root inode\n");
1355f97117d1SArtem B. Bityutskiy 			return -ENOMEM;
1356f97117d1SArtem B. Bityutskiy 		}
1357733802d9SArtem B. Bityutskiy 		dbg_readinode("creating inocache for root inode\n");
1358f97117d1SArtem B. Bityutskiy 		memset(f->inocache, 0, sizeof(struct jffs2_inode_cache));
1359f97117d1SArtem B. Bityutskiy 		f->inocache->ino = f->inocache->nlink = 1;
1360f97117d1SArtem B. Bityutskiy 		f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
1361f97117d1SArtem B. Bityutskiy 		f->inocache->state = INO_STATE_READING;
1362f97117d1SArtem B. Bityutskiy 		jffs2_add_ino_cache(c, f->inocache);
1363f97117d1SArtem B. Bityutskiy 	}
1364f97117d1SArtem B. Bityutskiy 	if (!f->inocache) {
1365e0d60137SArtem B. Bityutskiy 		JFFS2_ERROR("requestied to read an nonexistent ino %u\n", ino);
1366f97117d1SArtem B. Bityutskiy 		return -ENOENT;
1367f97117d1SArtem B. Bityutskiy 	}
1368f97117d1SArtem B. Bityutskiy 
1369f97117d1SArtem B. Bityutskiy 	return jffs2_do_read_inode_internal(c, f, latest_node);
1370f97117d1SArtem B. Bityutskiy }
1371f97117d1SArtem B. Bityutskiy 
1372f97117d1SArtem B. Bityutskiy int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
1373f97117d1SArtem B. Bityutskiy {
1374f97117d1SArtem B. Bityutskiy 	struct jffs2_raw_inode n;
13753d375d9eSYan Burman 	struct jffs2_inode_info *f = kzalloc(sizeof(*f), GFP_KERNEL);
1376f97117d1SArtem B. Bityutskiy 	int ret;
1377f97117d1SArtem B. Bityutskiy 
1378f97117d1SArtem B. Bityutskiy 	if (!f)
1379f97117d1SArtem B. Bityutskiy 		return -ENOMEM;
1380f97117d1SArtem B. Bityutskiy 
1381f97117d1SArtem B. Bityutskiy 	init_MUTEX_LOCKED(&f->sem);
1382f97117d1SArtem B. Bityutskiy 	f->inocache = ic;
1383f97117d1SArtem B. Bityutskiy 
1384f97117d1SArtem B. Bityutskiy 	ret = jffs2_do_read_inode_internal(c, f, &n);
1385f97117d1SArtem B. Bityutskiy 	if (!ret) {
1386f97117d1SArtem B. Bityutskiy 		up(&f->sem);
1387f97117d1SArtem B. Bityutskiy 		jffs2_do_clear_inode(c, f);
1388f97117d1SArtem B. Bityutskiy 	}
1389f97117d1SArtem B. Bityutskiy 	kfree (f);
1390f97117d1SArtem B. Bityutskiy 	return ret;
1391f97117d1SArtem B. Bityutskiy }
1392f97117d1SArtem B. Bityutskiy 
13931da177e4SLinus Torvalds void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
13941da177e4SLinus Torvalds {
13951da177e4SLinus Torvalds 	struct jffs2_full_dirent *fd, *fds;
13961da177e4SLinus Torvalds 	int deleted;
13971da177e4SLinus Torvalds 
1398c7afb0f9SKaiGai Kohei 	jffs2_clear_acl(f);
1399355ed4e1SKaiGai Kohei 	jffs2_xattr_delete_inode(c, f->inocache);
14001da177e4SLinus Torvalds 	down(&f->sem);
14011da177e4SLinus Torvalds 	deleted = f->inocache && !f->inocache->nlink;
14021da177e4SLinus Torvalds 
140367e345d1SDavid Woodhouse 	if (f->inocache && f->inocache->state != INO_STATE_CHECKING)
140467e345d1SDavid Woodhouse 		jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING);
140567e345d1SDavid Woodhouse 
14061da177e4SLinus Torvalds 	if (f->metadata) {
14071da177e4SLinus Torvalds 		if (deleted)
14081da177e4SLinus Torvalds 			jffs2_mark_node_obsolete(c, f->metadata->raw);
14091da177e4SLinus Torvalds 		jffs2_free_full_dnode(f->metadata);
14101da177e4SLinus Torvalds 	}
14111da177e4SLinus Torvalds 
14121da177e4SLinus Torvalds 	jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL);
14131da177e4SLinus Torvalds 
14142b79adccSArtem B. Bityutskiy 	if (f->target) {
14152b79adccSArtem B. Bityutskiy 		kfree(f->target);
14162b79adccSArtem B. Bityutskiy 		f->target = NULL;
141732f1a95dSArtem B. Bityuckiy 	}
14181da177e4SLinus Torvalds 
14192b79adccSArtem B. Bityutskiy 	fds = f->dents;
14201da177e4SLinus Torvalds 	while(fds) {
14211da177e4SLinus Torvalds 		fd = fds;
14221da177e4SLinus Torvalds 		fds = fd->next;
14231da177e4SLinus Torvalds 		jffs2_free_full_dirent(fd);
14241da177e4SLinus Torvalds 	}
14251da177e4SLinus Torvalds 
142667e345d1SDavid Woodhouse 	if (f->inocache && f->inocache->state != INO_STATE_CHECKING) {
14271da177e4SLinus Torvalds 		jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
142867e345d1SDavid Woodhouse 		if (f->inocache->nodes == (void *)f->inocache)
142967e345d1SDavid Woodhouse 			jffs2_del_ino_cache(c, f->inocache);
143067e345d1SDavid Woodhouse 	}
14311da177e4SLinus Torvalds 
14321da177e4SLinus Torvalds 	up(&f->sem);
14331da177e4SLinus Torvalds }
1434