xref: /openbmc/linux/fs/jffs2/nodelist.c (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1 /*
2  * JFFS2 -- Journalling Flash File System, Version 2.
3  *
4  * Copyright (C) 2001-2003 Red Hat, Inc.
5  *
6  * Created by David Woodhouse <dwmw2@infradead.org>
7  *
8  * For licensing information, see the file 'LICENCE' in this directory.
9  *
10  * $Id: nodelist.c,v 1.90 2004/12/08 17:59:20 dwmw2 Exp $
11  *
12  */
13 
14 #include <linux/kernel.h>
15 #include <linux/sched.h>
16 #include <linux/fs.h>
17 #include <linux/mtd/mtd.h>
18 #include <linux/rbtree.h>
19 #include <linux/crc32.h>
20 #include <linux/slab.h>
21 #include <linux/pagemap.h>
22 #include "nodelist.h"
23 
24 void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list)
25 {
26 	struct jffs2_full_dirent **prev = list;
27 	D1(printk(KERN_DEBUG "jffs2_add_fd_to_list( %p, %p (->%p))\n", new, list, *list));
28 
29 	while ((*prev) && (*prev)->nhash <= new->nhash) {
30 		if ((*prev)->nhash == new->nhash && !strcmp((*prev)->name, new->name)) {
31 			/* Duplicate. Free one */
32 			if (new->version < (*prev)->version) {
33 				D1(printk(KERN_DEBUG "Eep! Marking new dirent node obsolete\n"));
34 				D1(printk(KERN_DEBUG "New dirent is \"%s\"->ino #%u. Old is \"%s\"->ino #%u\n", new->name, new->ino, (*prev)->name, (*prev)->ino));
35 				jffs2_mark_node_obsolete(c, new->raw);
36 				jffs2_free_full_dirent(new);
37 			} else {
38 				D1(printk(KERN_DEBUG "Marking old dirent node (ino #%u) obsolete\n", (*prev)->ino));
39 				new->next = (*prev)->next;
40 				jffs2_mark_node_obsolete(c, ((*prev)->raw));
41 				jffs2_free_full_dirent(*prev);
42 				*prev = new;
43 			}
44 			goto out;
45 		}
46 		prev = &((*prev)->next);
47 	}
48 	new->next = *prev;
49 	*prev = new;
50 
51  out:
52 	D2(while(*list) {
53 		printk(KERN_DEBUG "Dirent \"%s\" (hash 0x%08x, ino #%u\n", (*list)->name, (*list)->nhash, (*list)->ino);
54 		list = &(*list)->next;
55 	});
56 }
57 
58 /* Put a new tmp_dnode_info into the list, keeping the list in
59    order of increasing version
60 */
61 static void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct jffs2_tmp_dnode_info **list)
62 {
63 	struct jffs2_tmp_dnode_info **prev = list;
64 
65 	while ((*prev) && (*prev)->version < tn->version) {
66 		prev = &((*prev)->next);
67 	}
68 	tn->next = (*prev);
69         *prev = tn;
70 }
71 
72 static void jffs2_free_tmp_dnode_info_list(struct jffs2_tmp_dnode_info *tn)
73 {
74 	struct jffs2_tmp_dnode_info *next;
75 
76 	while (tn) {
77 		next = tn;
78 		tn = tn->next;
79 		jffs2_free_full_dnode(next->fn);
80 		jffs2_free_tmp_dnode_info(next);
81 	}
82 }
83 
84 static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
85 {
86 	struct jffs2_full_dirent *next;
87 
88 	while (fd) {
89 		next = fd->next;
90 		jffs2_free_full_dirent(fd);
91 		fd = next;
92 	}
93 }
94 
95 /* Returns first valid node after 'ref'. May return 'ref' */
96 static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_ref *ref)
97 {
98 	while (ref && ref->next_in_ino) {
99 		if (!ref_obsolete(ref))
100 			return ref;
101 		D1(printk(KERN_DEBUG "node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref)));
102 		ref = ref->next_in_ino;
103 	}
104 	return NULL;
105 }
106 
107 /* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated
108    with this ino, returning the former in order of version */
109 
110 int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
111 			  struct jffs2_tmp_dnode_info **tnp, struct jffs2_full_dirent **fdp,
112 			  uint32_t *highest_version, uint32_t *latest_mctime,
113 			  uint32_t *mctime_ver)
114 {
115 	struct jffs2_raw_node_ref *ref, *valid_ref;
116 	struct jffs2_tmp_dnode_info *tn, *ret_tn = NULL;
117 	struct jffs2_full_dirent *fd, *ret_fd = NULL;
118 	union jffs2_node_union node;
119 	size_t retlen;
120 	int err;
121 
122 	*mctime_ver = 0;
123 
124 	D1(printk(KERN_DEBUG "jffs2_get_inode_nodes(): ino #%u\n", f->inocache->ino));
125 
126 	spin_lock(&c->erase_completion_lock);
127 
128 	valid_ref = jffs2_first_valid_node(f->inocache->nodes);
129 
130 	if (!valid_ref)
131 		printk(KERN_WARNING "Eep. No valid nodes for ino #%u\n", f->inocache->ino);
132 
133 	while (valid_ref) {
134 		/* We can hold a pointer to a non-obsolete node without the spinlock,
135 		   but _obsolete_ nodes may disappear at any time, if the block
136 		   they're in gets erased. So if we mark 'ref' obsolete while we're
137 		   not holding the lock, it can go away immediately. For that reason,
138 		   we find the next valid node first, before processing 'ref'.
139 		*/
140 		ref = valid_ref;
141 		valid_ref = jffs2_first_valid_node(ref->next_in_ino);
142 		spin_unlock(&c->erase_completion_lock);
143 
144 		cond_resched();
145 
146 		/* FIXME: point() */
147 		err = jffs2_flash_read(c, (ref_offset(ref)),
148 				       min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node)),
149 				       &retlen, (void *)&node);
150 		if (err) {
151 			printk(KERN_WARNING "error %d reading node at 0x%08x in get_inode_nodes()\n", err, ref_offset(ref));
152 			goto free_out;
153 		}
154 
155 
156 			/* Check we've managed to read at least the common node header */
157 		if (retlen < min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node.u))) {
158 			printk(KERN_WARNING "short read in get_inode_nodes()\n");
159 			err = -EIO;
160 			goto free_out;
161 		}
162 
163 		switch (je16_to_cpu(node.u.nodetype)) {
164 		case JFFS2_NODETYPE_DIRENT:
165 			D1(printk(KERN_DEBUG "Node at %08x (%d) is a dirent node\n", ref_offset(ref), ref_flags(ref)));
166 			if (ref_flags(ref) == REF_UNCHECKED) {
167 				printk(KERN_WARNING "BUG: Dirent node at 0x%08x never got checked? How?\n", ref_offset(ref));
168 				BUG();
169 			}
170 			if (retlen < sizeof(node.d)) {
171 				printk(KERN_WARNING "short read in get_inode_nodes()\n");
172 				err = -EIO;
173 				goto free_out;
174 			}
175 			/* sanity check */
176 			if (PAD((node.d.nsize + sizeof (node.d))) != PAD(je32_to_cpu (node.d.totlen))) {
177 				printk(KERN_NOTICE "jffs2_get_inode_nodes(): Illegal nsize in node at 0x%08x: nsize 0x%02x, totlen %04x\n",
178 				       ref_offset(ref), node.d.nsize, je32_to_cpu(node.d.totlen));
179 				jffs2_mark_node_obsolete(c, ref);
180 				spin_lock(&c->erase_completion_lock);
181 				continue;
182 			}
183 			if (je32_to_cpu(node.d.version) > *highest_version)
184 				*highest_version = je32_to_cpu(node.d.version);
185 			if (ref_obsolete(ref)) {
186 				/* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
187 				printk(KERN_ERR "Dirent node at 0x%08x became obsolete while we weren't looking\n",
188 				       ref_offset(ref));
189 				BUG();
190 			}
191 
192 			fd = jffs2_alloc_full_dirent(node.d.nsize+1);
193 			if (!fd) {
194 				err = -ENOMEM;
195 				goto free_out;
196 			}
197 			fd->raw = ref;
198 			fd->version = je32_to_cpu(node.d.version);
199 			fd->ino = je32_to_cpu(node.d.ino);
200 			fd->type = node.d.type;
201 
202 			/* Pick out the mctime of the latest dirent */
203 			if(fd->version > *mctime_ver) {
204 				*mctime_ver = fd->version;
205 				*latest_mctime = je32_to_cpu(node.d.mctime);
206 			}
207 
208 			/* memcpy as much of the name as possible from the raw
209 			   dirent we've already read from the flash
210 			*/
211 			if (retlen > sizeof(struct jffs2_raw_dirent))
212 				memcpy(&fd->name[0], &node.d.name[0], min_t(uint32_t, node.d.nsize, (retlen-sizeof(struct jffs2_raw_dirent))));
213 
214 			/* Do we need to copy any more of the name directly
215 			   from the flash?
216 			*/
217 			if (node.d.nsize + sizeof(struct jffs2_raw_dirent) > retlen) {
218 				/* FIXME: point() */
219 				int already = retlen - sizeof(struct jffs2_raw_dirent);
220 
221 				err = jffs2_flash_read(c, (ref_offset(ref)) + retlen,
222 						   node.d.nsize - already, &retlen, &fd->name[already]);
223 				if (!err && retlen != node.d.nsize - already)
224 					err = -EIO;
225 
226 				if (err) {
227 					printk(KERN_WARNING "Read remainder of name in jffs2_get_inode_nodes(): error %d\n", err);
228 					jffs2_free_full_dirent(fd);
229 					goto free_out;
230 				}
231 			}
232 			fd->nhash = full_name_hash(fd->name, node.d.nsize);
233 			fd->next = NULL;
234 			fd->name[node.d.nsize] = '\0';
235 				/* Wheee. We now have a complete jffs2_full_dirent structure, with
236 				   the name in it and everything. Link it into the list
237 				*/
238 			D1(printk(KERN_DEBUG "Adding fd \"%s\", ino #%u\n", fd->name, fd->ino));
239 			jffs2_add_fd_to_list(c, fd, &ret_fd);
240 			break;
241 
242 		case JFFS2_NODETYPE_INODE:
243 			D1(printk(KERN_DEBUG "Node at %08x (%d) is a data node\n", ref_offset(ref), ref_flags(ref)));
244 			if (retlen < sizeof(node.i)) {
245 				printk(KERN_WARNING "read too short for dnode\n");
246 				err = -EIO;
247 				goto free_out;
248 			}
249 			if (je32_to_cpu(node.i.version) > *highest_version)
250 				*highest_version = je32_to_cpu(node.i.version);
251 			D1(printk(KERN_DEBUG "version %d, highest_version now %d\n", je32_to_cpu(node.i.version), *highest_version));
252 
253 			if (ref_obsolete(ref)) {
254 				/* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
255 				printk(KERN_ERR "Inode node at 0x%08x became obsolete while we weren't looking\n",
256 				       ref_offset(ref));
257 				BUG();
258 			}
259 
260 			/* If we've never checked the CRCs on this node, check them now. */
261 			if (ref_flags(ref) == REF_UNCHECKED) {
262 				uint32_t crc, len;
263 				struct jffs2_eraseblock *jeb;
264 
265 				crc = crc32(0, &node, sizeof(node.i)-8);
266 				if (crc != je32_to_cpu(node.i.node_crc)) {
267 					printk(KERN_NOTICE "jffs2_get_inode_nodes(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
268 					       ref_offset(ref), je32_to_cpu(node.i.node_crc), crc);
269 					jffs2_mark_node_obsolete(c, ref);
270 					spin_lock(&c->erase_completion_lock);
271 					continue;
272 				}
273 
274 				/* sanity checks */
275 				if ( je32_to_cpu(node.i.offset) > je32_to_cpu(node.i.isize) ||
276 				     PAD(je32_to_cpu(node.i.csize) + sizeof (node.i)) != PAD(je32_to_cpu(node.i.totlen))) {
277 					printk(KERN_NOTICE "jffs2_get_inode_nodes(): Inode corrupted at 0x%08x, totlen %d, #ino  %d, version %d, isize %d, csize %d, dsize %d \n",
278 						ref_offset(ref),  je32_to_cpu(node.i.totlen),  je32_to_cpu(node.i.ino),
279 						je32_to_cpu(node.i.version),  je32_to_cpu(node.i.isize),
280 						je32_to_cpu(node.i.csize), je32_to_cpu(node.i.dsize));
281 					jffs2_mark_node_obsolete(c, ref);
282 					spin_lock(&c->erase_completion_lock);
283 					continue;
284 				}
285 
286 				if (node.i.compr != JFFS2_COMPR_ZERO && je32_to_cpu(node.i.csize)) {
287 					unsigned char *buf=NULL;
288 					uint32_t pointed = 0;
289 #ifndef __ECOS
290 					if (c->mtd->point) {
291 						err = c->mtd->point (c->mtd, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize),
292 								     &retlen, &buf);
293 						if (!err && retlen < je32_to_cpu(node.i.csize)) {
294 							D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen));
295 							c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize));
296 						} else if (err){
297 							D1(printk(KERN_DEBUG "MTD point failed %d\n", err));
298 						} else
299 							pointed = 1; /* succefully pointed to device */
300 					}
301 #endif
302 					if(!pointed){
303 						buf = kmalloc(je32_to_cpu(node.i.csize), GFP_KERNEL);
304 						if (!buf)
305 							return -ENOMEM;
306 
307 						err = jffs2_flash_read(c, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize),
308 								       &retlen, buf);
309 						if (!err && retlen != je32_to_cpu(node.i.csize))
310 							err = -EIO;
311 						if (err) {
312 							kfree(buf);
313 							return err;
314 						}
315 					}
316 					crc = crc32(0, buf, je32_to_cpu(node.i.csize));
317 					if(!pointed)
318 						kfree(buf);
319 #ifndef __ECOS
320 					else
321 						c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize));
322 #endif
323 
324 					if (crc != je32_to_cpu(node.i.data_crc)) {
325 						printk(KERN_NOTICE "jffs2_get_inode_nodes(): Data CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
326 						       ref_offset(ref), je32_to_cpu(node.i.data_crc), crc);
327 						jffs2_mark_node_obsolete(c, ref);
328 						spin_lock(&c->erase_completion_lock);
329 						continue;
330 					}
331 
332 				}
333 
334 				/* Mark the node as having been checked and fix the accounting accordingly */
335 				spin_lock(&c->erase_completion_lock);
336 				jeb = &c->blocks[ref->flash_offset / c->sector_size];
337 				len = ref_totlen(c, jeb, ref);
338 
339 				jeb->used_size += len;
340 				jeb->unchecked_size -= len;
341 				c->used_size += len;
342 				c->unchecked_size -= len;
343 
344 				/* If node covers at least a whole page, or if it starts at the
345 				   beginning of a page and runs to the end of the file, or if
346 				   it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
347 
348 				   If it's actually overlapped, it'll get made NORMAL (or OBSOLETE)
349 				   when the overlapping node(s) get added to the tree anyway.
350 				*/
351 				if ((je32_to_cpu(node.i.dsize) >= PAGE_CACHE_SIZE) ||
352 				    ( ((je32_to_cpu(node.i.offset)&(PAGE_CACHE_SIZE-1))==0) &&
353 				      (je32_to_cpu(node.i.dsize)+je32_to_cpu(node.i.offset) ==  je32_to_cpu(node.i.isize)))) {
354 					D1(printk(KERN_DEBUG "Marking node at 0x%08x REF_PRISTINE\n", ref_offset(ref)));
355 					ref->flash_offset = ref_offset(ref) | REF_PRISTINE;
356 				} else {
357 					D1(printk(KERN_DEBUG "Marking node at 0x%08x REF_NORMAL\n", ref_offset(ref)));
358 					ref->flash_offset = ref_offset(ref) | REF_NORMAL;
359 				}
360 				spin_unlock(&c->erase_completion_lock);
361 			}
362 
363 			tn = jffs2_alloc_tmp_dnode_info();
364 			if (!tn) {
365 				D1(printk(KERN_DEBUG "alloc tn failed\n"));
366 				err = -ENOMEM;
367 				goto free_out;
368 			}
369 
370 			tn->fn = jffs2_alloc_full_dnode();
371 			if (!tn->fn) {
372 				D1(printk(KERN_DEBUG "alloc fn failed\n"));
373 				err = -ENOMEM;
374 				jffs2_free_tmp_dnode_info(tn);
375 				goto free_out;
376 			}
377 			tn->version = je32_to_cpu(node.i.version);
378 			tn->fn->ofs = je32_to_cpu(node.i.offset);
379 			/* There was a bug where we wrote hole nodes out with
380 			   csize/dsize swapped. Deal with it */
381 			if (node.i.compr == JFFS2_COMPR_ZERO && !je32_to_cpu(node.i.dsize) && je32_to_cpu(node.i.csize))
382 				tn->fn->size = je32_to_cpu(node.i.csize);
383 			else // normal case...
384 				tn->fn->size = je32_to_cpu(node.i.dsize);
385 			tn->fn->raw = ref;
386 			D1(printk(KERN_DEBUG "dnode @%08x: ver %u, offset %04x, dsize %04x\n",
387 				  ref_offset(ref), je32_to_cpu(node.i.version),
388 				  je32_to_cpu(node.i.offset), je32_to_cpu(node.i.dsize)));
389 			jffs2_add_tn_to_list(tn, &ret_tn);
390 			break;
391 
392 		default:
393 			if (ref_flags(ref) == REF_UNCHECKED) {
394 				struct jffs2_eraseblock *jeb;
395 				uint32_t len;
396 
397 				printk(KERN_ERR "Eep. Unknown node type %04x at %08x was marked REF_UNCHECKED\n",
398 				       je16_to_cpu(node.u.nodetype), ref_offset(ref));
399 
400 				/* Mark the node as having been checked and fix the accounting accordingly */
401 				spin_lock(&c->erase_completion_lock);
402 				jeb = &c->blocks[ref->flash_offset / c->sector_size];
403 				len = ref_totlen(c, jeb, ref);
404 
405 				jeb->used_size += len;
406 				jeb->unchecked_size -= len;
407 				c->used_size += len;
408 				c->unchecked_size -= len;
409 
410 				mark_ref_normal(ref);
411 				spin_unlock(&c->erase_completion_lock);
412 			}
413 			node.u.nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(node.u.nodetype));
414 			if (crc32(0, &node, sizeof(struct jffs2_unknown_node)-4) != je32_to_cpu(node.u.hdr_crc)) {
415 				/* Hmmm. This should have been caught at scan time. */
416 				printk(KERN_ERR "Node header CRC failed at %08x. But it must have been OK earlier.\n",
417 				       ref_offset(ref));
418 				printk(KERN_ERR "Node was: { %04x, %04x, %08x, %08x }\n",
419 				       je16_to_cpu(node.u.magic), je16_to_cpu(node.u.nodetype), je32_to_cpu(node.u.totlen),
420 				       je32_to_cpu(node.u.hdr_crc));
421 				jffs2_mark_node_obsolete(c, ref);
422 			} else switch(je16_to_cpu(node.u.nodetype) & JFFS2_COMPAT_MASK) {
423 			case JFFS2_FEATURE_INCOMPAT:
424 				printk(KERN_NOTICE "Unknown INCOMPAT nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
425 				/* EEP */
426 				BUG();
427 				break;
428 			case JFFS2_FEATURE_ROCOMPAT:
429 				printk(KERN_NOTICE "Unknown ROCOMPAT nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
430 				if (!(c->flags & JFFS2_SB_FLAG_RO))
431 					BUG();
432 				break;
433 			case JFFS2_FEATURE_RWCOMPAT_COPY:
434 				printk(KERN_NOTICE "Unknown RWCOMPAT_COPY nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
435 				break;
436 			case JFFS2_FEATURE_RWCOMPAT_DELETE:
437 				printk(KERN_NOTICE "Unknown RWCOMPAT_DELETE nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
438 				jffs2_mark_node_obsolete(c, ref);
439 				break;
440 			}
441 
442 		}
443 		spin_lock(&c->erase_completion_lock);
444 
445 	}
446 	spin_unlock(&c->erase_completion_lock);
447 	*tnp = ret_tn;
448 	*fdp = ret_fd;
449 
450 	return 0;
451 
452  free_out:
453 	jffs2_free_tmp_dnode_info_list(ret_tn);
454 	jffs2_free_full_dirent_list(ret_fd);
455 	return err;
456 }
457 
458 void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state)
459 {
460 	spin_lock(&c->inocache_lock);
461 	ic->state = state;
462 	wake_up(&c->inocache_wq);
463 	spin_unlock(&c->inocache_lock);
464 }
465 
466 /* During mount, this needs no locking. During normal operation, its
467    callers want to do other stuff while still holding the inocache_lock.
468    Rather than introducing special case get_ino_cache functions or
469    callbacks, we just let the caller do the locking itself. */
470 
471 struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino)
472 {
473 	struct jffs2_inode_cache *ret;
474 
475 	D2(printk(KERN_DEBUG "jffs2_get_ino_cache(): ino %u\n", ino));
476 
477 	ret = c->inocache_list[ino % INOCACHE_HASHSIZE];
478 	while (ret && ret->ino < ino) {
479 		ret = ret->next;
480 	}
481 
482 	if (ret && ret->ino != ino)
483 		ret = NULL;
484 
485 	D2(printk(KERN_DEBUG "jffs2_get_ino_cache found %p for ino %u\n", ret, ino));
486 	return ret;
487 }
488 
489 void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new)
490 {
491 	struct jffs2_inode_cache **prev;
492 	D2(printk(KERN_DEBUG "jffs2_add_ino_cache: Add %p (ino #%u)\n", new, new->ino));
493 	spin_lock(&c->inocache_lock);
494 
495 	prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE];
496 
497 	while ((*prev) && (*prev)->ino < new->ino) {
498 		prev = &(*prev)->next;
499 	}
500 	new->next = *prev;
501 	*prev = new;
502 
503 	spin_unlock(&c->inocache_lock);
504 }
505 
506 void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
507 {
508 	struct jffs2_inode_cache **prev;
509 	D2(printk(KERN_DEBUG "jffs2_del_ino_cache: Del %p (ino #%u)\n", old, old->ino));
510 	spin_lock(&c->inocache_lock);
511 
512 	prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE];
513 
514 	while ((*prev) && (*prev)->ino < old->ino) {
515 		prev = &(*prev)->next;
516 	}
517 	if ((*prev) == old) {
518 		*prev = old->next;
519 	}
520 
521 	spin_unlock(&c->inocache_lock);
522 }
523 
524 void jffs2_free_ino_caches(struct jffs2_sb_info *c)
525 {
526 	int i;
527 	struct jffs2_inode_cache *this, *next;
528 
529 	for (i=0; i<INOCACHE_HASHSIZE; i++) {
530 		this = c->inocache_list[i];
531 		while (this) {
532 			next = this->next;
533 			D2(printk(KERN_DEBUG "jffs2_free_ino_caches: Freeing ino #%u at %p\n", this->ino, this));
534 			jffs2_free_inode_cache(this);
535 			this = next;
536 		}
537 		c->inocache_list[i] = NULL;
538 	}
539 }
540 
541 void jffs2_free_raw_node_refs(struct jffs2_sb_info *c)
542 {
543 	int i;
544 	struct jffs2_raw_node_ref *this, *next;
545 
546 	for (i=0; i<c->nr_blocks; i++) {
547 		this = c->blocks[i].first_node;
548 		while(this) {
549 			next = this->next_phys;
550 			jffs2_free_raw_node_ref(this);
551 			this = next;
552 		}
553 		c->blocks[i].first_node = c->blocks[i].last_node = NULL;
554 	}
555 }
556 
557 struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset)
558 {
559 	/* The common case in lookup is that there will be a node
560 	   which precisely matches. So we go looking for that first */
561 	struct rb_node *next;
562 	struct jffs2_node_frag *prev = NULL;
563 	struct jffs2_node_frag *frag = NULL;
564 
565 	D2(printk(KERN_DEBUG "jffs2_lookup_node_frag(%p, %d)\n", fragtree, offset));
566 
567 	next = fragtree->rb_node;
568 
569 	while(next) {
570 		frag = rb_entry(next, struct jffs2_node_frag, rb);
571 
572 		D2(printk(KERN_DEBUG "Considering frag %d-%d (%p). left %p, right %p\n",
573 			  frag->ofs, frag->ofs+frag->size, frag, frag->rb.rb_left, frag->rb.rb_right));
574 		if (frag->ofs + frag->size <= offset) {
575 			D2(printk(KERN_DEBUG "Going right from frag %d-%d, before the region we care about\n",
576 				  frag->ofs, frag->ofs+frag->size));
577 			/* Remember the closest smaller match on the way down */
578 			if (!prev || frag->ofs > prev->ofs)
579 				prev = frag;
580 			next = frag->rb.rb_right;
581 		} else if (frag->ofs > offset) {
582 			D2(printk(KERN_DEBUG "Going left from frag %d-%d, after the region we care about\n",
583 				  frag->ofs, frag->ofs+frag->size));
584 			next = frag->rb.rb_left;
585 		} else {
586 			D2(printk(KERN_DEBUG "Returning frag %d,%d, matched\n",
587 				  frag->ofs, frag->ofs+frag->size));
588 			return frag;
589 		}
590 	}
591 
592 	/* Exact match not found. Go back up looking at each parent,
593 	   and return the closest smaller one */
594 
595 	if (prev)
596 		D2(printk(KERN_DEBUG "No match. Returning frag %d,%d, closest previous\n",
597 			  prev->ofs, prev->ofs+prev->size));
598 	else
599 		D2(printk(KERN_DEBUG "Returning NULL, empty fragtree\n"));
600 
601 	return prev;
602 }
603 
604 /* Pass 'c' argument to indicate that nodes should be marked obsolete as
605    they're killed. */
606 void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c)
607 {
608 	struct jffs2_node_frag *frag;
609 	struct jffs2_node_frag *parent;
610 
611 	if (!root->rb_node)
612 		return;
613 
614 	frag = (rb_entry(root->rb_node, struct jffs2_node_frag, rb));
615 
616 	while(frag) {
617 		if (frag->rb.rb_left) {
618 			D2(printk(KERN_DEBUG "Going left from frag (%p) %d-%d\n",
619 				  frag, frag->ofs, frag->ofs+frag->size));
620 			frag = frag_left(frag);
621 			continue;
622 		}
623 		if (frag->rb.rb_right) {
624 			D2(printk(KERN_DEBUG "Going right from frag (%p) %d-%d\n",
625 				  frag, frag->ofs, frag->ofs+frag->size));
626 			frag = frag_right(frag);
627 			continue;
628 		}
629 
630 		D2(printk(KERN_DEBUG "jffs2_kill_fragtree: frag at 0x%x-0x%x: node %p, frags %d--\n",
631 			  frag->ofs, frag->ofs+frag->size, frag->node,
632 			  frag->node?frag->node->frags:0));
633 
634 		if (frag->node && !(--frag->node->frags)) {
635 			/* Not a hole, and it's the final remaining frag
636 			   of this node. Free the node */
637 			if (c)
638 				jffs2_mark_node_obsolete(c, frag->node->raw);
639 
640 			jffs2_free_full_dnode(frag->node);
641 		}
642 		parent = frag_parent(frag);
643 		if (parent) {
644 			if (frag_left(parent) == frag)
645 				parent->rb.rb_left = NULL;
646 			else
647 				parent->rb.rb_right = NULL;
648 		}
649 
650 		jffs2_free_node_frag(frag);
651 		frag = parent;
652 
653 		cond_resched();
654 	}
655 }
656 
657 void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_node_frag *base)
658 {
659 	struct rb_node *parent = &base->rb;
660 	struct rb_node **link = &parent;
661 
662 	D2(printk(KERN_DEBUG "jffs2_fragtree_insert(%p; %d-%d, %p)\n", newfrag,
663 		  newfrag->ofs, newfrag->ofs+newfrag->size, base));
664 
665 	while (*link) {
666 		parent = *link;
667 		base = rb_entry(parent, struct jffs2_node_frag, rb);
668 
669 		D2(printk(KERN_DEBUG "fragtree_insert considering frag at 0x%x\n", base->ofs));
670 		if (newfrag->ofs > base->ofs)
671 			link = &base->rb.rb_right;
672 		else if (newfrag->ofs < base->ofs)
673 			link = &base->rb.rb_left;
674 		else {
675 			printk(KERN_CRIT "Duplicate frag at %08x (%p,%p)\n", newfrag->ofs, newfrag, base);
676 			BUG();
677 		}
678 	}
679 
680 	rb_link_node(&newfrag->rb, &base->rb, link);
681 }
682