xref: /nrf52832-nimble/rt-thread/components/dfs/filesystems/jffs2/src/readinode.c (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * JFFS2 -- Journalling Flash File System, Version 2.
3  *
4  * Copyright (C) 2001-2003 Red Hat, Inc.
5  *
6  * Created by David Woodhouse <[email protected]>
7  *
8  * For licensing information, see the file 'LICENCE' in this directory.
9  *
10  * $Id: readinode.c,v 1.132 2005/07/28 14:46:40 dedekind Exp $
11  *
12  */
13 
14 #include <linux/kernel.h>
15 #include <linux/sched.h>
16 #include <linux/slab.h>
17 #include <linux/fs.h>
18 #include <linux/crc32.h>
19 #include <linux/pagemap.h>
20 #include <linux/mtd/mtd.h>
21 #include <linux/compiler.h>
22 #include "nodelist.h"
23 
jffs2_truncate_fragtree(struct jffs2_sb_info * c,struct rb_root * list,uint32_t size)24 void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size)
25 {
26 	struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size);
27 
28 	JFFS2_DBG_FRAGTREE("truncating fragtree to 0x%08x bytes\n", size);
29 
30 	/* We know frag->ofs <= size. That's what lookup does for us */
31 	if (frag && frag->ofs != size) {
32 		if (frag->ofs+frag->size >= size) {
33 			JFFS2_DBG_FRAGTREE2("truncating frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size);
34 			frag->size = size - frag->ofs;
35 		}
36 		frag = frag_next(frag);
37 	}
38 	while (frag && frag->ofs >= size) {
39 		struct jffs2_node_frag *next = frag_next(frag);
40 
41 		JFFS2_DBG_FRAGTREE("removing frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size);
42 		frag_erase(frag, list);
43 		jffs2_obsolete_node_frag(c, frag);
44 		frag = next;
45 	}
46 }
47 
48 /*
49  * Put a new tmp_dnode_info into the temporaty RB-tree, keeping the list in
50  * order of increasing version.
51  */
jffs2_add_tn_to_tree(struct jffs2_tmp_dnode_info * tn,struct rb_root * list)52 static void jffs2_add_tn_to_tree(struct jffs2_tmp_dnode_info *tn, struct rb_root *list)
53 {
54 	struct rb_node **p = &list->rb_node;
55 	struct rb_node * parent = NULL;
56 	struct jffs2_tmp_dnode_info *this;
57 
58 	while (*p) {
59 		parent = *p;
60 		this = rb_entry(parent, struct jffs2_tmp_dnode_info, rb);
61 
62 		/* There may actually be a collision here, but it doesn't
63 		   actually matter. As long as the two nodes with the same
64 		   version are together, it's all fine. */
65 		if (tn->version < this->version)
66 			p = &(*p)->rb_left;
67 		else
68 			p = &(*p)->rb_right;
69         }
70 
71 	rb_link_node(&tn->rb, parent, p);
72 	rb_insert_color(&tn->rb, list);
73 }
74 
jffs2_free_tmp_dnode_info_list(struct rb_root * list)75 static void jffs2_free_tmp_dnode_info_list(struct rb_root *list)
76 {
77 	struct rb_node *this;
78 	struct jffs2_tmp_dnode_info *tn;
79 
80 	this = list->rb_node;
81 
82 	/* Now at bottom of tree */
83 	while (this) {
84 		if (this->rb_left)
85 			this = this->rb_left;
86 		else if (this->rb_right)
87 			this = this->rb_right;
88 		else {
89 			tn = rb_entry(this, struct jffs2_tmp_dnode_info, rb);
90 			jffs2_free_full_dnode(tn->fn);
91 			jffs2_free_tmp_dnode_info(tn);
92 
93 			this = this->rb_parent;
94 			if (!this)
95 				break;
96 
97 			if (this->rb_left == &tn->rb)
98 				this->rb_left = NULL;
99 			else if (this->rb_right == &tn->rb)
100 				this->rb_right = NULL;
101 			else BUG();
102 		}
103 	}
104 	list->rb_node = NULL;
105 }
106 
jffs2_free_full_dirent_list(struct jffs2_full_dirent * fd)107 static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
108 {
109 	struct jffs2_full_dirent *next;
110 
111 	while (fd) {
112 		next = fd->next;
113 		jffs2_free_full_dirent(fd);
114 		fd = next;
115 	}
116 }
117 
118 /* Returns first valid node after 'ref'. May return 'ref' */
jffs2_first_valid_node(struct jffs2_raw_node_ref * ref)119 static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_ref *ref)
120 {
121 	while (ref && ref->next_in_ino) {
122 		if (!ref_obsolete(ref))
123 			return ref;
124 		JFFS2_DBG_NODEREF("node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref));
125 		ref = ref->next_in_ino;
126 	}
127 	return NULL;
128 }
129 
130 /*
131  * Helper function for jffs2_get_inode_nodes().
132  * It is called every time an directory entry node is found.
133  *
134  * Returns: 0 on succes;
135  * 	    1 if the node should be marked obsolete;
136  * 	    negative error code on failure.
137  */
138 static inline int
read_direntry(struct jffs2_sb_info * c,struct jffs2_raw_node_ref * ref,struct jffs2_raw_dirent * rd,uint32_t read,struct jffs2_full_dirent ** fdp,int32_t * latest_mctime,uint32_t * mctime_ver)139 read_direntry(struct jffs2_sb_info *c,
140 	      struct jffs2_raw_node_ref *ref,
141 	      struct jffs2_raw_dirent *rd,
142 	      uint32_t read,
143 	      struct jffs2_full_dirent **fdp,
144 	      int32_t *latest_mctime,
145 	      uint32_t *mctime_ver)
146 {
147 	struct jffs2_full_dirent *fd;
148 
149 	/* The direntry nodes are checked during the flash scanning */
150 	BUG_ON(ref_flags(ref) == REF_UNCHECKED);
151 	/* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
152 	BUG_ON(ref_obsolete(ref));
153 
154 	/* Sanity check */
155 	if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) {
156 		JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n",
157 		       ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen));
158 		return 1;
159 	}
160 
161 	fd = jffs2_alloc_full_dirent(rd->nsize + 1);
162 	if (unlikely(!fd))
163 		return -ENOMEM;
164 
165 	fd->raw = ref;
166 	fd->version = je32_to_cpu(rd->version);
167 	fd->ino = je32_to_cpu(rd->ino);
168 	fd->type = rd->type;
169 
170 	/* Pick out the mctime of the latest dirent */
171 	if(fd->version > *mctime_ver) {
172 		*mctime_ver = fd->version;
173 		*latest_mctime = je32_to_cpu(rd->mctime);
174 	}
175 
176 	/*
177 	 * Copy as much of the name as possible from the raw
178 	 * dirent we've already read from the flash.
179 	 */
180 	if (read > sizeof(*rd))
181 		memcpy(&fd->name[0], &rd->name[0],
182 		       min_t(uint32_t, rd->nsize, (read - sizeof(*rd)) ));
183 
184 	/* Do we need to copy any more of the name directly from the flash? */
185 	if (rd->nsize + sizeof(*rd) > read) {
186 		/* FIXME: point() */
187 		int err;
188 		int already = read - sizeof(*rd);
189 
190 		err = jffs2_flash_read(c, (ref_offset(ref)) + read,
191 				rd->nsize - already, (size_t*)&read, &fd->name[already]);
192 		if (unlikely(read != rd->nsize - already) && likely(!err))
193 			return -EIO;
194 
195 		if (unlikely(err)) {
196 			JFFS2_ERROR("read remainder of name: error %d\n", err);
197 			jffs2_free_full_dirent(fd);
198 			return -EIO;
199 		}
200 	}
201 
202 	fd->nhash = full_name_hash(fd->name, rd->nsize);
203 	fd->next = NULL;
204 	fd->name[rd->nsize] = '\0';
205 
206 	/*
207 	 * Wheee. We now have a complete jffs2_full_dirent structure, with
208 	 * the name in it and everything. Link it into the list
209 	 */
210 	jffs2_add_fd_to_list(c, fd, fdp);
211 
212 	return 0;
213 }
214 
215 /*
216  * Helper function for jffs2_get_inode_nodes().
217  * It is called every time an inode node is found.
218  *
219  * Returns: 0 on succes;
220  * 	    1 if the node should be marked obsolete;
221  * 	    negative error code on failure.
222  */
223 static inline int
read_dnode(struct jffs2_sb_info * c,struct jffs2_raw_node_ref * ref,struct jffs2_raw_inode * rd,uint32_t read,struct rb_root * tnp,int32_t * latest_mctime,uint32_t * mctime_ver)224 read_dnode(struct jffs2_sb_info *c,
225 	   struct jffs2_raw_node_ref *ref,
226 	   struct jffs2_raw_inode *rd,
227 	   uint32_t read,
228 	   struct rb_root *tnp,
229 	   int32_t *latest_mctime,
230 	   uint32_t *mctime_ver)
231 {
232 	struct jffs2_eraseblock *jeb;
233 	struct jffs2_tmp_dnode_info *tn;
234 
235 	/* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
236 	BUG_ON(ref_obsolete(ref));
237 
238 	/* If we've never checked the CRCs on this node, check them now */
239 	if (ref_flags(ref) == REF_UNCHECKED) {
240 		uint32_t crc, len;
241 
242 		crc = crc32(0, rd, sizeof(*rd) - 8);
243 		if (unlikely(crc != je32_to_cpu(rd->node_crc))) {
244 			JFFS2_NOTICE("header CRC failed on node at %#08x: read %#08x, calculated %#08x\n",
245 					ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
246 			return 1;
247 		}
248 
249 		/* Sanity checks */
250 		if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) ||
251 		    unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) {
252 				JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref));
253 				jffs2_dbg_dump_node(c, ref_offset(ref));
254 			return 1;
255 		}
256 
257 		if (rd->compr != JFFS2_COMPR_ZERO && je32_to_cpu(rd->csize)) {
258 			unsigned char *buf = NULL;
259 			uint32_t pointed = 0;
260 			int err;
261 #ifndef __ECOS
262 			if (c->mtd->point) {
263 				err = c->mtd->point (c->mtd, ref_offset(ref) + sizeof(*rd), je32_to_cpu(rd->csize),
264 						     &read, &buf);
265 				if (unlikely(read < je32_to_cpu(rd->csize)) && likely(!err)) {
266 					JFFS2_ERROR("MTD point returned len too short: 0x%zx\n", read);
267 					c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(*rd),
268 							je32_to_cpu(rd->csize));
269 				} else if (unlikely(err)){
270 					JFFS2_ERROR("MTD point failed %d\n", err);
271 				} else
272 					pointed = 1; /* succefully pointed to device */
273 			}
274 #endif
275 			if(!pointed){
276 				buf = kmalloc(je32_to_cpu(rd->csize), GFP_KERNEL);
277 				if (!buf)
278 					return -ENOMEM;
279 
280 				err = jffs2_flash_read(c, ref_offset(ref) + sizeof(*rd), je32_to_cpu(rd->csize),
281 							(size_t*)&read, buf);
282 				if (unlikely(read != je32_to_cpu(rd->csize)) && likely(!err))
283 					err = -EIO;
284 				if (err) {
285 					kfree(buf);
286 					return err;
287 				}
288 			}
289 			crc = crc32(0, buf, je32_to_cpu(rd->csize));
290 			if(!pointed)
291 				kfree(buf);
292 #ifndef __ECOS
293 			else
294 				c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(*rd), je32_to_cpu(rd->csize));
295 #endif
296 
297 			if (crc != je32_to_cpu(rd->data_crc)) {
298 				JFFS2_NOTICE("data CRC failed on node at %#08x: read %#08x, calculated %#08x\n",
299 					ref_offset(ref), je32_to_cpu(rd->data_crc), crc);
300 				return 1;
301 			}
302 
303 		}
304 
305 		/* Mark the node as having been checked and fix the accounting accordingly */
306 		jeb = &c->blocks[ref->flash_offset / c->sector_size];
307 		len = ref_totlen(c, jeb, ref);
308 
309 		spin_lock(&c->erase_completion_lock);
310 		jeb->used_size += len;
311 		jeb->unchecked_size -= len;
312 		c->used_size += len;
313 		c->unchecked_size -= len;
314 
315 		/* If node covers at least a whole page, or if it starts at the
316 		   beginning of a page and runs to the end of the file, or if
317 		   it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
318 
319 		   If it's actually overlapped, it'll get made NORMAL (or OBSOLETE)
320 		   when the overlapping node(s) get added to the tree anyway.
321 		*/
322 		if ((je32_to_cpu(rd->dsize) >= PAGE_CACHE_SIZE) ||
323 		    ( ((je32_to_cpu(rd->offset) & (PAGE_CACHE_SIZE-1))==0) &&
324 		      (je32_to_cpu(rd->dsize) + je32_to_cpu(rd->offset) == je32_to_cpu(rd->isize)))) {
325 			JFFS2_DBG_READINODE("marking node at %#08x REF_PRISTINE\n", ref_offset(ref));
326 			ref->flash_offset = ref_offset(ref) | REF_PRISTINE;
327 		} else {
328 			JFFS2_DBG_READINODE("marking node at %#08x REF_NORMAL\n", ref_offset(ref));
329 			ref->flash_offset = ref_offset(ref) | REF_NORMAL;
330 		}
331 		spin_unlock(&c->erase_completion_lock);
332 	}
333 
334 	tn = jffs2_alloc_tmp_dnode_info();
335 	if (!tn) {
336 		JFFS2_ERROR("alloc tn failed\n");
337 		return -ENOMEM;
338 	}
339 
340 	tn->fn = jffs2_alloc_full_dnode();
341 	if (!tn->fn) {
342 		JFFS2_ERROR("alloc fn failed\n");
343 		jffs2_free_tmp_dnode_info(tn);
344 		return -ENOMEM;
345 	}
346 
347 	tn->version = je32_to_cpu(rd->version);
348 	tn->fn->ofs = je32_to_cpu(rd->offset);
349 	tn->fn->raw = ref;
350 
351 	/* There was a bug where we wrote hole nodes out with
352 	   csize/dsize swapped. Deal with it */
353 	if (rd->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(rd->dsize) && je32_to_cpu(rd->csize))
354 		tn->fn->size = je32_to_cpu(rd->csize);
355 	else // normal case...
356 		tn->fn->size = je32_to_cpu(rd->dsize);
357 
358 	JFFS2_DBG_READINODE("dnode @%08x: ver %u, offset %#04x, dsize %#04x\n",
359 		  ref_offset(ref), je32_to_cpu(rd->version), je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize));
360 
361 	jffs2_add_tn_to_tree(tn, tnp);
362 
363 	return 0;
364 }
365 
366 /*
367  * Helper function for jffs2_get_inode_nodes().
368  * It is called every time an unknown node is found.
369  *
370  * Returns: 0 on succes;
371  * 	    1 if the node should be marked obsolete;
372  * 	    negative error code on failure.
373  */
374 static inline int
read_unknown(struct jffs2_sb_info * c,struct jffs2_raw_node_ref * ref,struct jffs2_unknown_node * un,uint32_t read)375 read_unknown(struct jffs2_sb_info *c,
376 	     struct jffs2_raw_node_ref *ref,
377 	     struct jffs2_unknown_node *un,
378 	     uint32_t read)
379 {
380 	/* We don't mark unknown nodes as REF_UNCHECKED */
381 	BUG_ON(ref_flags(ref) == REF_UNCHECKED);
382 
383 	un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype));
384 
385 	if (crc32(0, un, sizeof(struct jffs2_unknown_node) - 4) != je32_to_cpu(un->hdr_crc)) {
386 		/* Hmmm. This should have been caught at scan time. */
387 		JFFS2_NOTICE("node header CRC failed at %#08x. But it must have been OK earlier.\n", ref_offset(ref));
388 		jffs2_dbg_dump_node(c, ref_offset(ref));
389 		return 1;
390 	} else {
391 		switch(je16_to_cpu(un->nodetype) & JFFS2_COMPAT_MASK) {
392 
393 		case JFFS2_FEATURE_INCOMPAT:
394 			JFFS2_ERROR("unknown INCOMPAT nodetype %#04X at %#08x\n",
395 				je16_to_cpu(un->nodetype), ref_offset(ref));
396 			/* EEP */
397 			BUG();
398 			break;
399 
400 		case JFFS2_FEATURE_ROCOMPAT:
401 			JFFS2_ERROR("unknown ROCOMPAT nodetype %#04X at %#08x\n",
402 					je16_to_cpu(un->nodetype), ref_offset(ref));
403 			BUG_ON(!(c->flags & JFFS2_SB_FLAG_RO));
404 			break;
405 
406 		case JFFS2_FEATURE_RWCOMPAT_COPY:
407 			JFFS2_NOTICE("unknown RWCOMPAT_COPY nodetype %#04X at %#08x\n",
408 					je16_to_cpu(un->nodetype), ref_offset(ref));
409 			break;
410 
411 		case JFFS2_FEATURE_RWCOMPAT_DELETE:
412 			JFFS2_NOTICE("unknown RWCOMPAT_DELETE nodetype %#04X at %#08x\n",
413 					je16_to_cpu(un->nodetype), ref_offset(ref));
414 			return 1;
415 		}
416 	}
417 
418 	return 0;
419 }
420 
421 /* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated
422    with this ino, returning the former in order of version */
423 
jffs2_get_inode_nodes(struct jffs2_sb_info * c,struct jffs2_inode_info * f,struct rb_root * tnp,struct jffs2_full_dirent ** fdp,uint32_t * highest_version,uint32_t * latest_mctime,uint32_t * mctime_ver)424 static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
425 				 struct rb_root *tnp, struct jffs2_full_dirent **fdp,
426 				 uint32_t *highest_version, uint32_t *latest_mctime,
427 				 uint32_t *mctime_ver)
428 {
429 	struct jffs2_raw_node_ref *ref, *valid_ref;
430 	struct rb_root ret_tn = RB_ROOT;
431 	struct jffs2_full_dirent *ret_fd = NULL;
432 	union jffs2_node_union node;
433 	size_t retlen;
434 	int err;
435 
436 	*mctime_ver = 0;
437 
438 	JFFS2_DBG_READINODE("ino #%u\n", f->inocache->ino);
439 
440 	spin_lock(&c->erase_completion_lock);
441 
442 	valid_ref = jffs2_first_valid_node(f->inocache->nodes);
443 
444 	if (!valid_ref && (f->inocache->ino != 1))
445 		JFFS2_WARNING("no valid nodes for ino #%u\n", f->inocache->ino);
446 
447 	while (valid_ref) {
448 		/* We can hold a pointer to a non-obsolete node without the spinlock,
449 		   but _obsolete_ nodes may disappear at any time, if the block
450 		   they're in gets erased. So if we mark 'ref' obsolete while we're
451 		   not holding the lock, it can go away immediately. For that reason,
452 		   we find the next valid node first, before processing 'ref'.
453 		*/
454 		ref = valid_ref;
455 		valid_ref = jffs2_first_valid_node(ref->next_in_ino);
456 		spin_unlock(&c->erase_completion_lock);
457 
458 		cond_resched();
459 
460 		/* FIXME: point() */
461 		err = jffs2_flash_read(c, (ref_offset(ref)),
462 				       min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node)),
463 				       &retlen, (void *)&node);
464 		if (err) {
465 			JFFS2_ERROR("error %d reading node at 0x%08x in get_inode_nodes()\n", err, ref_offset(ref));
466 			goto free_out;
467 		}
468 
469 		switch (je16_to_cpu(node.u.nodetype)) {
470 
471 		case JFFS2_NODETYPE_DIRENT:
472 			JFFS2_DBG_READINODE("node at %08x (%d) is a dirent node\n", ref_offset(ref), ref_flags(ref));
473 
474 			if (retlen < sizeof(node.d)) {
475 				JFFS2_ERROR("short read dirent at %#08x\n", ref_offset(ref));
476 				err = -EIO;
477 				goto free_out;
478 			}
479 
480 			err = read_direntry(c, ref, &node.d, retlen, &ret_fd, (int32_t *)latest_mctime, mctime_ver);
481 			if (err == 1) {
482 				jffs2_mark_node_obsolete(c, ref);
483 				break;
484 			} else if (unlikely(err))
485 				goto free_out;
486 
487 			if (je32_to_cpu(node.d.version) > *highest_version)
488 				*highest_version = je32_to_cpu(node.d.version);
489 
490 			break;
491 
492 		case JFFS2_NODETYPE_INODE:
493 			JFFS2_DBG_READINODE("node at %08x (%d) is a data node\n", ref_offset(ref), ref_flags(ref));
494 
495 			if (retlen < sizeof(node.i)) {
496 				JFFS2_ERROR("short read dnode at %#08x\n", ref_offset(ref));
497 				err = -EIO;
498 				goto free_out;
499 			}
500 
501 			err = read_dnode(c, ref, &node.i, retlen, &ret_tn, (int32_t *)latest_mctime, mctime_ver);
502 			if (err == 1) {
503 				jffs2_mark_node_obsolete(c, ref);
504 				break;
505 			} else if (unlikely(err))
506 				goto free_out;
507 
508 			if (je32_to_cpu(node.i.version) > *highest_version)
509 				*highest_version = je32_to_cpu(node.i.version);
510 
511 			JFFS2_DBG_READINODE("version %d, highest_version now %d\n",
512 					je32_to_cpu(node.i.version), *highest_version);
513 
514 			break;
515 
516 		default:
517 			/* Check we've managed to read at least the common node header */
518 			if (retlen < sizeof(struct jffs2_unknown_node)) {
519 				JFFS2_ERROR("short read unknown node at %#08x\n", ref_offset(ref));
520 				return -EIO;
521 			}
522 
523 			err = read_unknown(c, ref, &node.u, retlen);
524 			if (err == 1) {
525 				jffs2_mark_node_obsolete(c, ref);
526 				break;
527 			} else if (unlikely(err))
528 				goto free_out;
529 
530 		}
531 		spin_lock(&c->erase_completion_lock);
532 
533 	}
534 	spin_unlock(&c->erase_completion_lock);
535 	*tnp = ret_tn;
536 	*fdp = ret_fd;
537 
538 	return 0;
539 
540  free_out:
541 	jffs2_free_tmp_dnode_info_list(&ret_tn);
542 	jffs2_free_full_dirent_list(ret_fd);
543 	return err;
544 }
545 
jffs2_do_read_inode_internal(struct jffs2_sb_info * c,struct jffs2_inode_info * f,struct jffs2_raw_inode * latest_node)546 static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
547 					struct jffs2_inode_info *f,
548 					struct jffs2_raw_inode *latest_node)
549 {
550 	struct jffs2_tmp_dnode_info *tn = NULL;
551 	struct rb_root tn_list;
552 	struct rb_node *rb, *repl_rb;
553 	struct jffs2_full_dirent *fd_list;
554 	struct jffs2_full_dnode *fn = NULL;
555 	uint32_t crc;
556 	uint32_t latest_mctime, mctime_ver;
557 	uint32_t mdata_ver = 0;
558 	size_t retlen;
559 	int ret;
560 
561 	JFFS2_DBG_READINODE("ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink);
562 
563 	/* Grab all nodes relevant to this ino */
564 	ret = jffs2_get_inode_nodes(c, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver);
565 
566 	if (ret) {
567 		JFFS2_ERROR("cannot read nodes for ino %u, returned error is %d\n", f->inocache->ino, ret);
568 		if (f->inocache->state == INO_STATE_READING)
569 			jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
570 		return ret;
571 	}
572 	f->dents = fd_list;
573 
574 	rb = rb_first(&tn_list);
575 
576 	while (rb) {
577 		tn = rb_entry(rb, struct jffs2_tmp_dnode_info, rb);
578 		fn = tn->fn;
579 
580 		if (f->metadata) {
581 			if (likely(tn->version >= mdata_ver)) {
582 				JFFS2_DBG_READINODE("obsoleting old metadata at 0x%08x\n", ref_offset(f->metadata->raw));
583 				jffs2_mark_node_obsolete(c, f->metadata->raw);
584 				jffs2_free_full_dnode(f->metadata);
585 				f->metadata = NULL;
586 
587 				mdata_ver = 0;
588 			} else {
589 				/* This should never happen. */
590 				JFFS2_ERROR("Er. New metadata at 0x%08x with ver %d is actually older than previous ver %d at 0x%08x\n",
591 					  ref_offset(fn->raw), tn->version, mdata_ver, ref_offset(f->metadata->raw));
592 				jffs2_mark_node_obsolete(c, fn->raw);
593 				jffs2_free_full_dnode(fn);
594 				/* Fill in latest_node from the metadata, not this one we're about to free... */
595 				fn = f->metadata;
596 				goto next_tn;
597 			}
598 		}
599 
600 		if (fn->size) {
601 			jffs2_add_full_dnode_to_inode(c, f, fn);
602 		} else {
603 			/* Zero-sized node at end of version list. Just a metadata update */
604 			JFFS2_DBG_READINODE("metadata @%08x: ver %d\n", ref_offset(fn->raw), tn->version);
605 			f->metadata = fn;
606 			mdata_ver = tn->version;
607 		}
608 	next_tn:
609 		BUG_ON(rb->rb_left);
610 		if (rb->rb_parent && rb->rb_parent->rb_left == rb) {
611 			/* We were then left-hand child of our parent. We need
612 			   to move our own right-hand child into our place. */
613 			repl_rb = rb->rb_right;
614 			if (repl_rb)
615 				repl_rb->rb_parent = rb->rb_parent;
616 		} else
617 			repl_rb = NULL;
618 
619 		rb = rb_next(rb);
620 
621 		/* Remove the spent tn from the tree; don't bother rebalancing
622 		   but put our right-hand child in our own place. */
623 		if (tn->rb.rb_parent) {
624 			if (tn->rb.rb_parent->rb_left == &tn->rb)
625 				tn->rb.rb_parent->rb_left = repl_rb;
626 			else if (tn->rb.rb_parent->rb_right == &tn->rb)
627 				tn->rb.rb_parent->rb_right = repl_rb;
628 			else BUG();
629 		} else if (tn->rb.rb_right)
630 			tn->rb.rb_right->rb_parent = NULL;
631 
632 		jffs2_free_tmp_dnode_info(tn);
633 	}
634 	jffs2_dbg_fragtree_paranoia_check_nolock(f);
635 
636 	if (!fn) {
637 		/* No data nodes for this inode. */
638 		if (f->inocache->ino != 1) {
639 			JFFS2_WARNING("no data nodes found for ino #%u\n", f->inocache->ino);
640 			if (!fd_list) {
641 				if (f->inocache->state == INO_STATE_READING)
642 					jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
643 				return -EIO;
644 			}
645 			JFFS2_NOTICE("but it has children so we fake some modes for it\n");
646 		}
647 		latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO);
648 		latest_node->version = cpu_to_je32(0);
649 		latest_node->atime = latest_node->ctime = latest_node->mtime = cpu_to_je32(0);
650 		latest_node->isize = cpu_to_je32(0);
651 		latest_node->gid = cpu_to_je16(0);
652 		latest_node->uid = cpu_to_je16(0);
653 		if (f->inocache->state == INO_STATE_READING)
654 			jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
655 		return 0;
656 	}
657 
658 	ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(*latest_node), &retlen, (void *)latest_node);
659 	if (ret || retlen != sizeof(*latest_node)) {
660 		JFFS2_ERROR("failed to read from flash: error %d, %zd of %zd bytes read\n",
661 			ret, retlen, sizeof(*latest_node));
662 		/* FIXME: If this fails, there seems to be a memory leak. Find it. */
663 		up(&f->sem);
664 		jffs2_do_clear_inode(c, f);
665 		return ret?ret:-EIO;
666 	}
667 
668 	crc = crc32(0, latest_node, sizeof(*latest_node)-8);
669 	if (crc != je32_to_cpu(latest_node->node_crc)) {
670 		JFFS2_ERROR("CRC failed for read_inode of inode %u at physical location 0x%x\n",
671 			f->inocache->ino, ref_offset(fn->raw));
672 		up(&f->sem);
673 		jffs2_do_clear_inode(c, f);
674 		return -EIO;
675 	}
676 
677 	switch(jemode_to_cpu(latest_node->mode) & S_IFMT) {
678 	case S_IFDIR:
679 		if (mctime_ver > je32_to_cpu(latest_node->version)) {
680 			/* The times in the latest_node are actually older than
681 			   mctime in the latest dirent. Cheat. */
682 			latest_node->ctime = latest_node->mtime = cpu_to_je32(latest_mctime);
683 		}
684 		break;
685 
686 
687 	case S_IFREG:
688 		/* If it was a regular file, truncate it to the latest node's isize */
689 		jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize));
690 		break;
691 
692 //	case S_IFLNK:	  prife
693 //		/* Hack to work around broken isize in old symlink code.
694 //		   Remove this when dwmw2 comes to his senses and stops
695 //		   symlinks from being an entirely gratuitous special
696 //		   case. */
697 //		if (!je32_to_cpu(latest_node->isize))
698 //			latest_node->isize = latest_node->dsize;
699 //
700 //		if (f->inocache->state != INO_STATE_CHECKING) {
701 //			/* Symlink's inode data is the target path. Read it and
702 //			 * keep in RAM to facilitate quick follow symlink
703 //			 * operation. */
704 //			f->target = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL);
705 //			if (!f->target) {
706 //				JFFS2_ERROR("can't allocate %d bytes of memory for the symlink target path cache\n", je32_to_cpu(latest_node->csize));
707 //				up(&f->sem);
708 //				jffs2_do_clear_inode(c, f);
709 //				return -ENOMEM;
710 //			}
711 //
712 //			ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node),
713 //						je32_to_cpu(latest_node->csize), &retlen, (char *)f->target);
714 //
715 //			if (ret  || retlen != je32_to_cpu(latest_node->csize)) {
716 //				if (retlen != je32_to_cpu(latest_node->csize))
717 //					ret = -EIO;
718 //				kfree(f->target);
719 //				f->target = NULL;
720 //				up(&f->sem);
721 //				jffs2_do_clear_inode(c, f);
722 //				return -ret;
723 //			}
724 //
725 //			f->target[je32_to_cpu(latest_node->csize)] = '\0';
726 //			JFFS2_DBG_READINODE("symlink's target '%s' cached\n", f->target);
727 //		}
728 //
729 //		/* fall through... */
730 
731 	case S_IFBLK:
732 	case S_IFCHR:
733 		/* Certain inode types should have only one data node, and it's
734 		   kept as the metadata node */
735 		if (f->metadata) {
736 			JFFS2_ERROR("Argh. Special inode #%u with mode 0%o had metadata node\n",
737 			       f->inocache->ino, jemode_to_cpu(latest_node->mode));
738 			up(&f->sem);
739 			jffs2_do_clear_inode(c, f);
740 			return -EIO;
741 		}
742 		if (!frag_first(&f->fragtree)) {
743 			JFFS2_ERROR("Argh. Special inode #%u with mode 0%o has no fragments\n",
744 			       f->inocache->ino, jemode_to_cpu(latest_node->mode));
745 			up(&f->sem);
746 			jffs2_do_clear_inode(c, f);
747 			return -EIO;
748 		}
749 		/* ASSERT: f->fraglist != NULL */
750 		if (frag_next(frag_first(&f->fragtree))) {
751 			JFFS2_ERROR("Argh. Special inode #%u with mode 0x%x had more than one node\n",
752 			       f->inocache->ino, jemode_to_cpu(latest_node->mode));
753 			/* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
754 			up(&f->sem);
755 			jffs2_do_clear_inode(c, f);
756 			return -EIO;
757 		}
758 		/* OK. We're happy */
759 		f->metadata = frag_first(&f->fragtree)->node;
760 		jffs2_free_node_frag(frag_first(&f->fragtree));
761 		f->fragtree.rb_node = NULL;//f->fragtree = RB_ROOT; // modify it for vs
762 		break;
763 	}
764 	if (f->inocache->state == INO_STATE_READING)
765 		jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
766 
767 	return 0;
768 }
769 
770 /* Scan the list of all nodes present for this ino, build map of versions, etc. */
jffs2_do_read_inode(struct jffs2_sb_info * c,struct jffs2_inode_info * f,uint32_t ino,struct jffs2_raw_inode * latest_node)771 int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
772 			uint32_t ino, struct jffs2_raw_inode *latest_node)
773 {
774 	JFFS2_DBG_READINODE("read inode #%u\n", ino);
775 
776  retry_inocache:
777 	spin_lock(&c->inocache_lock);
778 	f->inocache = jffs2_get_ino_cache(c, ino);
779 
780 	if (f->inocache) {
781 		/* Check its state. We may need to wait before we can use it */
782 		switch(f->inocache->state) {
783 		case INO_STATE_UNCHECKED:
784 		case INO_STATE_CHECKEDABSENT:
785 			f->inocache->state = INO_STATE_READING;
786 			break;
787 
788 		case INO_STATE_CHECKING:
789 		case INO_STATE_GC:
790 			/* If it's in either of these states, we need
791 			   to wait for whoever's got it to finish and
792 			   put it back. */
793 			JFFS2_DBG_READINODE("waiting for ino #%u in state %d\n", ino, f->inocache->state);
794 			sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
795 			goto retry_inocache;
796 
797 		case INO_STATE_READING:
798 		case INO_STATE_PRESENT:
799 			/* Eep. This should never happen. It can
800 			happen if Linux calls read_inode() again
801 			before clear_inode() has finished though. */
802 			JFFS2_ERROR("Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state);
803 			/* Fail. That's probably better than allowing it to succeed */
804 			f->inocache = NULL;
805 			break;
806 
807 		default:
808 			BUG();
809 		}
810 	}
811 	spin_unlock(&c->inocache_lock);
812 
813 	if (!f->inocache && ino == 1) {
814 		/* Special case - no root inode on medium */
815 		f->inocache = jffs2_alloc_inode_cache();
816 		if (!f->inocache) {
817 			JFFS2_ERROR("cannot allocate inocache for root inode\n");
818 			return -ENOMEM;
819 		}
820 		JFFS2_DBG_READINODE("creating inocache for root inode\n");
821 		memset(f->inocache, 0, sizeof(struct jffs2_inode_cache));
822 		f->inocache->ino = f->inocache->nlink = 1;
823 		f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
824 		f->inocache->state = INO_STATE_READING;
825 		jffs2_add_ino_cache(c, f->inocache);
826 	}
827 	if (!f->inocache) {
828 		JFFS2_ERROR("requestied to read an nonexistent ino %u\n", ino);
829 		return -ENOENT;
830 	}
831 
832 	return jffs2_do_read_inode_internal(c, f, latest_node);
833 }
834 
jffs2_do_crccheck_inode(struct jffs2_sb_info * c,struct jffs2_inode_cache * ic)835 int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
836 {
837 	struct jffs2_raw_inode n;
838 	struct jffs2_inode_info *f = kmalloc(sizeof(*f), GFP_KERNEL);
839 	int ret;
840 
841 	if (!f)
842 		return -ENOMEM;
843 
844 	memset(f, 0, sizeof(*f));
845 	init_MUTEX_LOCKED(&f->sem);
846 	f->inocache = ic;
847 
848 	ret = jffs2_do_read_inode_internal(c, f, &n);
849 	if (!ret) {
850 		up(&f->sem);
851 		jffs2_do_clear_inode(c, f);
852 	}
853 	kfree (f);
854 	return ret;
855 }
856 
jffs2_do_clear_inode(struct jffs2_sb_info * c,struct jffs2_inode_info * f)857 void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
858 {
859 	struct jffs2_full_dirent *fd, *fds;
860 	int deleted;
861 
862 	down(&f->sem);
863 	deleted = f->inocache && !f->inocache->nlink;
864 
865 	if (f->inocache && f->inocache->state != INO_STATE_CHECKING)
866 		jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING);
867 
868 	if (f->metadata) {
869 		if (deleted)
870 			jffs2_mark_node_obsolete(c, f->metadata->raw);
871 		jffs2_free_full_dnode(f->metadata);
872 	}
873 
874 	jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL);
875 
876 	if (f->target) {
877 		kfree(f->target);
878 		f->target = NULL;
879 	}
880 
881 	fds = f->dents;
882 	while(fds) {
883 		fd = fds;
884 		fds = fd->next;
885 		jffs2_free_full_dirent(fd);
886 	}
887 
888 	if (f->inocache && f->inocache->state != INO_STATE_CHECKING) {
889 		jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
890 		if (f->inocache->nodes == (void *)f->inocache)
891 			jffs2_del_ino_cache(c, f->inocache);
892 	}
893 
894 	up(&f->sem);
895 }
896