/*
 * JFFS2 -- Journalling Flash File System, Version 2.
 *
 * Copyright (C) 2001-2003 Red Hat, Inc.
 *
 * Created by David Woodhouse <dwmw2@infradead.org>
 *
 * For licensing information, see the file 'LICENCE' in this directory.
 *
 * $Id: nodelist.c,v 1.90 2004/12/08 17:59:20 dwmw2 Exp $
 *
 */

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/mtd/mtd.h>
#include <linux/rbtree.h>
#include <linux/crc32.h>
#include <linux/slab.h>
#include <linux/pagemap.h>
#include "nodelist.h"

void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list)
{
	struct jffs2_full_dirent **prev = list;
	D1(printk(KERN_DEBUG "jffs2_add_fd_to_list( %p, %p (->%p))\n", new, list, *list));

	while ((*prev) && (*prev)->nhash <= new->nhash) {
		if ((*prev)->nhash == new->nhash && !strcmp((*prev)->name, new->name)) {
			/* Duplicate. Free one */
			if (new->version < (*prev)->version) {
				D1(printk(KERN_DEBUG "Eep! Marking new dirent node obsolete\n"));
				D1(printk(KERN_DEBUG "New dirent is \"%s\"->ino #%u. Old is \"%s\"->ino #%u\n", new->name, new->ino, (*prev)->name, (*prev)->ino));
				jffs2_mark_node_obsolete(c, new->raw);
				jffs2_free_full_dirent(new);
			} else {
				D1(printk(KERN_DEBUG "Marking old dirent node (ino #%u) obsolete\n", (*prev)->ino));
				new->next = (*prev)->next;
				jffs2_mark_node_obsolete(c, ((*prev)->raw));
				jffs2_free_full_dirent(*prev);
				*prev = new;
			}
			goto out;
		}
		prev = &((*prev)->next);
	}
	new->next = *prev;
	*prev = new;

 out:
	D2(while(*list) {
		printk(KERN_DEBUG "Dirent \"%s\" (hash 0x%08x, ino #%u\n", (*list)->name, (*list)->nhash, (*list)->ino);
		list = &(*list)->next;
	});
}

/* Put a new tmp_dnode_info into the list, keeping the list in 
   order of increasing version
*/
static void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct jffs2_tmp_dnode_info **list)
{
	struct jffs2_tmp_dnode_info **prev = list;
	
	while ((*prev) && (*prev)->version < tn->version) {
		prev = &((*prev)->next);
	}
	tn->next = (*prev);
        *prev = tn;
}

static void jffs2_free_tmp_dnode_info_list(struct jffs2_tmp_dnode_info *tn)
{
	struct jffs2_tmp_dnode_info *next;

	while (tn) {
		next = tn;
		tn = tn->next;
		jffs2_free_full_dnode(next->fn);
		jffs2_free_tmp_dnode_info(next);
	}
}

static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
{
	struct jffs2_full_dirent *next;

	while (fd) {
		next = fd->next;
		jffs2_free_full_dirent(fd);
		fd = next;
	}
}

/* Returns first valid node after 'ref'. May return 'ref' */
static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_ref *ref)
{
	while (ref && ref->next_in_ino) {
		if (!ref_obsolete(ref))
			return ref;
		D1(printk(KERN_DEBUG "node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref)));
		ref = ref->next_in_ino;
	}
	return NULL;
}

/* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated
   with this ino, returning the former in order of version */

int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
			  struct jffs2_tmp_dnode_info **tnp, struct jffs2_full_dirent **fdp,
			  uint32_t *highest_version, uint32_t *latest_mctime,
			  uint32_t *mctime_ver)
{
	struct jffs2_raw_node_ref *ref, *valid_ref;
	struct jffs2_tmp_dnode_info *tn, *ret_tn = NULL;
	struct jffs2_full_dirent *fd, *ret_fd = NULL;
	union jffs2_node_union node;
	size_t retlen;
	int err;

	*mctime_ver = 0;
	
	D1(printk(KERN_DEBUG "jffs2_get_inode_nodes(): ino #%u\n", f->inocache->ino));

	spin_lock(&c->erase_completion_lock);

	valid_ref = jffs2_first_valid_node(f->inocache->nodes);

	if (!valid_ref)
		printk(KERN_WARNING "Eep. No valid nodes for ino #%u\n", f->inocache->ino);

	while (valid_ref) {
		/* We can hold a pointer to a non-obsolete node without the spinlock,
		   but _obsolete_ nodes may disappear at any time, if the block
		   they're in gets erased. So if we mark 'ref' obsolete while we're
		   not holding the lock, it can go away immediately. For that reason,
		   we find the next valid node first, before processing 'ref'.
		*/
		ref = valid_ref;
		valid_ref = jffs2_first_valid_node(ref->next_in_ino);
		spin_unlock(&c->erase_completion_lock);

		cond_resched();

		/* FIXME: point() */
		err = jffs2_flash_read(c, (ref_offset(ref)), 
				       min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node)),
				       &retlen, (void *)&node);
		if (err) {
			printk(KERN_WARNING "error %d reading node at 0x%08x in get_inode_nodes()\n", err, ref_offset(ref));
			goto free_out;
		}
			

			/* Check we've managed to read at least the common node header */
		if (retlen < min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node.u))) {
			printk(KERN_WARNING "short read in get_inode_nodes()\n");
			err = -EIO;
			goto free_out;
		}
			
		switch (je16_to_cpu(node.u.nodetype)) {
		case JFFS2_NODETYPE_DIRENT:
			D1(printk(KERN_DEBUG "Node at %08x (%d) is a dirent node\n", ref_offset(ref), ref_flags(ref)));
			if (ref_flags(ref) == REF_UNCHECKED) {
				printk(KERN_WARNING "BUG: Dirent node at 0x%08x never got checked? How?\n", ref_offset(ref));
				BUG();
			}
			if (retlen < sizeof(node.d)) {
				printk(KERN_WARNING "short read in get_inode_nodes()\n");
				err = -EIO;
				goto free_out;
			}
			/* sanity check */
			if (PAD((node.d.nsize + sizeof (node.d))) != PAD(je32_to_cpu (node.d.totlen))) {
				printk(KERN_NOTICE "jffs2_get_inode_nodes(): Illegal nsize in node at 0x%08x: nsize 0x%02x, totlen %04x\n",
				       ref_offset(ref), node.d.nsize, je32_to_cpu(node.d.totlen));
				jffs2_mark_node_obsolete(c, ref);
				spin_lock(&c->erase_completion_lock);
				continue;
			}
			if (je32_to_cpu(node.d.version) > *highest_version)
				*highest_version = je32_to_cpu(node.d.version);
			if (ref_obsolete(ref)) {
				/* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
				printk(KERN_ERR "Dirent node at 0x%08x became obsolete while we weren't looking\n",
				       ref_offset(ref));
				BUG();
			}
			
			fd = jffs2_alloc_full_dirent(node.d.nsize+1);
			if (!fd) {
				err = -ENOMEM;
				goto free_out;
			}
			fd->raw = ref;
			fd->version = je32_to_cpu(node.d.version);
			fd->ino = je32_to_cpu(node.d.ino);
			fd->type = node.d.type;

			/* Pick out the mctime of the latest dirent */
			if(fd->version > *mctime_ver) {
				*mctime_ver = fd->version;
				*latest_mctime = je32_to_cpu(node.d.mctime);
			}

			/* memcpy as much of the name as possible from the raw
			   dirent we've already read from the flash
			*/
			if (retlen > sizeof(struct jffs2_raw_dirent))
				memcpy(&fd->name[0], &node.d.name[0], min_t(uint32_t, node.d.nsize, (retlen-sizeof(struct jffs2_raw_dirent))));
				
			/* Do we need to copy any more of the name directly
			   from the flash?
			*/
			if (node.d.nsize + sizeof(struct jffs2_raw_dirent) > retlen) {
				/* FIXME: point() */
				int already = retlen - sizeof(struct jffs2_raw_dirent);
					
				err = jffs2_flash_read(c, (ref_offset(ref)) + retlen, 
						   node.d.nsize - already, &retlen, &fd->name[already]);
				if (!err && retlen != node.d.nsize - already)
					err = -EIO;
					
				if (err) {
					printk(KERN_WARNING "Read remainder of name in jffs2_get_inode_nodes(): error %d\n", err);
					jffs2_free_full_dirent(fd);
					goto free_out;
				}
			}
			fd->nhash = full_name_hash(fd->name, node.d.nsize);
			fd->next = NULL;
			fd->name[node.d.nsize] = '\0';
				/* Wheee. We now have a complete jffs2_full_dirent structure, with
				   the name in it and everything. Link it into the list 
				*/
			D1(printk(KERN_DEBUG "Adding fd \"%s\", ino #%u\n", fd->name, fd->ino));
			jffs2_add_fd_to_list(c, fd, &ret_fd);
			break;

		case JFFS2_NODETYPE_INODE:
			D1(printk(KERN_DEBUG "Node at %08x (%d) is a data node\n", ref_offset(ref), ref_flags(ref)));
			if (retlen < sizeof(node.i)) {
				printk(KERN_WARNING "read too short for dnode\n");
				err = -EIO;
				goto free_out;
			}
			if (je32_to_cpu(node.i.version) > *highest_version)
				*highest_version = je32_to_cpu(node.i.version);
			D1(printk(KERN_DEBUG "version %d, highest_version now %d\n", je32_to_cpu(node.i.version), *highest_version));

			if (ref_obsolete(ref)) {
				/* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
				printk(KERN_ERR "Inode node at 0x%08x became obsolete while we weren't looking\n",
				       ref_offset(ref));
				BUG();
			}

			/* If we've never checked the CRCs on this node, check them now. */
			if (ref_flags(ref) == REF_UNCHECKED) {
				uint32_t crc, len;
				struct jffs2_eraseblock *jeb;

				crc = crc32(0, &node, sizeof(node.i)-8);
				if (crc != je32_to_cpu(node.i.node_crc)) {
					printk(KERN_NOTICE "jffs2_get_inode_nodes(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
					       ref_offset(ref), je32_to_cpu(node.i.node_crc), crc);
					jffs2_mark_node_obsolete(c, ref);
					spin_lock(&c->erase_completion_lock);
					continue;
				}
				
				/* sanity checks */
				if ( je32_to_cpu(node.i.offset) > je32_to_cpu(node.i.isize) ||
				     PAD(je32_to_cpu(node.i.csize) + sizeof (node.i)) != PAD(je32_to_cpu(node.i.totlen))) {
					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",
						ref_offset(ref),  je32_to_cpu(node.i.totlen),  je32_to_cpu(node.i.ino),
						je32_to_cpu(node.i.version),  je32_to_cpu(node.i.isize), 
						je32_to_cpu(node.i.csize), je32_to_cpu(node.i.dsize));
					jffs2_mark_node_obsolete(c, ref);
					spin_lock(&c->erase_completion_lock);
					continue;
				}

				if (node.i.compr != JFFS2_COMPR_ZERO && je32_to_cpu(node.i.csize)) {
					unsigned char *buf=NULL;
					uint32_t pointed = 0;
#ifndef __ECOS
					if (c->mtd->point) {
						err = c->mtd->point (c->mtd, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize),
								     &retlen, &buf);
						if (!err && retlen < je32_to_cpu(node.i.csize)) {
							D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen));
							c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize));
						} else if (err){
							D1(printk(KERN_DEBUG "MTD point failed %d\n", err));
						} else
							pointed = 1; /* succefully pointed to device */
					}
#endif					
					if(!pointed){
						buf = kmalloc(je32_to_cpu(node.i.csize), GFP_KERNEL);
						if (!buf)
							return -ENOMEM;
						
						err = jffs2_flash_read(c, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize),
								       &retlen, buf);
						if (!err && retlen != je32_to_cpu(node.i.csize))
							err = -EIO;
						if (err) {
							kfree(buf);
							return err;
						}
					}
					crc = crc32(0, buf, je32_to_cpu(node.i.csize));
					if(!pointed)
						kfree(buf);
#ifndef __ECOS
					else
						c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize));
#endif

					if (crc != je32_to_cpu(node.i.data_crc)) {
						printk(KERN_NOTICE "jffs2_get_inode_nodes(): Data CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
						       ref_offset(ref), je32_to_cpu(node.i.data_crc), crc);
						jffs2_mark_node_obsolete(c, ref);
						spin_lock(&c->erase_completion_lock);
						continue;
					}
					
				}

				/* Mark the node as having been checked and fix the accounting accordingly */
				spin_lock(&c->erase_completion_lock);
				jeb = &c->blocks[ref->flash_offset / c->sector_size];
				len = ref_totlen(c, jeb, ref);

				jeb->used_size += len;
				jeb->unchecked_size -= len;
				c->used_size += len;
				c->unchecked_size -= len;

				/* If node covers at least a whole page, or if it starts at the 
				   beginning of a page and runs to the end of the file, or if 
				   it's a hole node, mark it REF_PRISTINE, else REF_NORMAL. 

				   If it's actually overlapped, it'll get made NORMAL (or OBSOLETE) 
				   when the overlapping node(s) get added to the tree anyway. 
				*/
				if ((je32_to_cpu(node.i.dsize) >= PAGE_CACHE_SIZE) ||
				    ( ((je32_to_cpu(node.i.offset)&(PAGE_CACHE_SIZE-1))==0) &&
				      (je32_to_cpu(node.i.dsize)+je32_to_cpu(node.i.offset) ==  je32_to_cpu(node.i.isize)))) {
					D1(printk(KERN_DEBUG "Marking node at 0x%08x REF_PRISTINE\n", ref_offset(ref)));
					ref->flash_offset = ref_offset(ref) | REF_PRISTINE;
				} else {
					D1(printk(KERN_DEBUG "Marking node at 0x%08x REF_NORMAL\n", ref_offset(ref)));
					ref->flash_offset = ref_offset(ref) | REF_NORMAL;
				}
				spin_unlock(&c->erase_completion_lock);
			}

			tn = jffs2_alloc_tmp_dnode_info();
			if (!tn) {
				D1(printk(KERN_DEBUG "alloc tn failed\n"));
				err = -ENOMEM;
				goto free_out;
			}

			tn->fn = jffs2_alloc_full_dnode();
			if (!tn->fn) {
				D1(printk(KERN_DEBUG "alloc fn failed\n"));
				err = -ENOMEM;
				jffs2_free_tmp_dnode_info(tn);
				goto free_out;
			}
			tn->version = je32_to_cpu(node.i.version);
			tn->fn->ofs = je32_to_cpu(node.i.offset);
			/* There was a bug where we wrote hole nodes out with
			   csize/dsize swapped. Deal with it */
			if (node.i.compr == JFFS2_COMPR_ZERO && !je32_to_cpu(node.i.dsize) && je32_to_cpu(node.i.csize))
				tn->fn->size = je32_to_cpu(node.i.csize);
			else // normal case...
				tn->fn->size = je32_to_cpu(node.i.dsize);
			tn->fn->raw = ref;
			D1(printk(KERN_DEBUG "dnode @%08x: ver %u, offset %04x, dsize %04x\n",
				  ref_offset(ref), je32_to_cpu(node.i.version),
				  je32_to_cpu(node.i.offset), je32_to_cpu(node.i.dsize)));
			jffs2_add_tn_to_list(tn, &ret_tn);
			break;

		default:
			if (ref_flags(ref) == REF_UNCHECKED) {
				struct jffs2_eraseblock *jeb;
				uint32_t len;

				printk(KERN_ERR "Eep. Unknown node type %04x at %08x was marked REF_UNCHECKED\n",
				       je16_to_cpu(node.u.nodetype), ref_offset(ref));

				/* Mark the node as having been checked and fix the accounting accordingly */
				spin_lock(&c->erase_completion_lock);
				jeb = &c->blocks[ref->flash_offset / c->sector_size];
				len = ref_totlen(c, jeb, ref);

				jeb->used_size += len;
				jeb->unchecked_size -= len;
				c->used_size += len;
				c->unchecked_size -= len;

				mark_ref_normal(ref);
				spin_unlock(&c->erase_completion_lock);
			}
			node.u.nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(node.u.nodetype));
			if (crc32(0, &node, sizeof(struct jffs2_unknown_node)-4) != je32_to_cpu(node.u.hdr_crc)) {
				/* Hmmm. This should have been caught at scan time. */
				printk(KERN_ERR "Node header CRC failed at %08x. But it must have been OK earlier.\n",
				       ref_offset(ref));
				printk(KERN_ERR "Node was: { %04x, %04x, %08x, %08x }\n", 
				       je16_to_cpu(node.u.magic), je16_to_cpu(node.u.nodetype), je32_to_cpu(node.u.totlen),
				       je32_to_cpu(node.u.hdr_crc));
				jffs2_mark_node_obsolete(c, ref);
			} else switch(je16_to_cpu(node.u.nodetype) & JFFS2_COMPAT_MASK) {
			case JFFS2_FEATURE_INCOMPAT:
				printk(KERN_NOTICE "Unknown INCOMPAT nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
				/* EEP */
				BUG();
				break;
			case JFFS2_FEATURE_ROCOMPAT:
				printk(KERN_NOTICE "Unknown ROCOMPAT nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
				if (!(c->flags & JFFS2_SB_FLAG_RO))
					BUG();
				break;
			case JFFS2_FEATURE_RWCOMPAT_COPY:
				printk(KERN_NOTICE "Unknown RWCOMPAT_COPY nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
				break;
			case JFFS2_FEATURE_RWCOMPAT_DELETE:
				printk(KERN_NOTICE "Unknown RWCOMPAT_DELETE nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
				jffs2_mark_node_obsolete(c, ref);
				break;
			}

		}
		spin_lock(&c->erase_completion_lock);

	}
	spin_unlock(&c->erase_completion_lock);
	*tnp = ret_tn;
	*fdp = ret_fd;

	return 0;

 free_out:
	jffs2_free_tmp_dnode_info_list(ret_tn);
	jffs2_free_full_dirent_list(ret_fd);
	return err;
}

void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state)
{
	spin_lock(&c->inocache_lock);
	ic->state = state;
	wake_up(&c->inocache_wq);
	spin_unlock(&c->inocache_lock);
}

/* During mount, this needs no locking. During normal operation, its
   callers want to do other stuff while still holding the inocache_lock.
   Rather than introducing special case get_ino_cache functions or 
   callbacks, we just let the caller do the locking itself. */
   
struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino)
{
	struct jffs2_inode_cache *ret;

	D2(printk(KERN_DEBUG "jffs2_get_ino_cache(): ino %u\n", ino));

	ret = c->inocache_list[ino % INOCACHE_HASHSIZE];
	while (ret && ret->ino < ino) {
		ret = ret->next;
	}
	
	if (ret && ret->ino != ino)
		ret = NULL;

	D2(printk(KERN_DEBUG "jffs2_get_ino_cache found %p for ino %u\n", ret, ino));
	return ret;
}

void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new)
{
	struct jffs2_inode_cache **prev;
	D2(printk(KERN_DEBUG "jffs2_add_ino_cache: Add %p (ino #%u)\n", new, new->ino));
	spin_lock(&c->inocache_lock);
	
	prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE];

	while ((*prev) && (*prev)->ino < new->ino) {
		prev = &(*prev)->next;
	}
	new->next = *prev;
	*prev = new;

	spin_unlock(&c->inocache_lock);
}

void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
{
	struct jffs2_inode_cache **prev;
	D2(printk(KERN_DEBUG "jffs2_del_ino_cache: Del %p (ino #%u)\n", old, old->ino));
	spin_lock(&c->inocache_lock);
	
	prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE];
	
	while ((*prev) && (*prev)->ino < old->ino) {
		prev = &(*prev)->next;
	}
	if ((*prev) == old) {
		*prev = old->next;
	}

	spin_unlock(&c->inocache_lock);
}

void jffs2_free_ino_caches(struct jffs2_sb_info *c)
{
	int i;
	struct jffs2_inode_cache *this, *next;
	
	for (i=0; i<INOCACHE_HASHSIZE; i++) {
		this = c->inocache_list[i];
		while (this) {
			next = this->next;
			D2(printk(KERN_DEBUG "jffs2_free_ino_caches: Freeing ino #%u at %p\n", this->ino, this));
			jffs2_free_inode_cache(this);
			this = next;
		}
		c->inocache_list[i] = NULL;
	}
}

void jffs2_free_raw_node_refs(struct jffs2_sb_info *c)
{
	int i;
	struct jffs2_raw_node_ref *this, *next;

	for (i=0; i<c->nr_blocks; i++) {
		this = c->blocks[i].first_node;
		while(this) {
			next = this->next_phys;
			jffs2_free_raw_node_ref(this);
			this = next;
		}
		c->blocks[i].first_node = c->blocks[i].last_node = NULL;
	}
}
	
struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset)
{
	/* The common case in lookup is that there will be a node 
	   which precisely matches. So we go looking for that first */
	struct rb_node *next;
	struct jffs2_node_frag *prev = NULL;
	struct jffs2_node_frag *frag = NULL;

	D2(printk(KERN_DEBUG "jffs2_lookup_node_frag(%p, %d)\n", fragtree, offset));

	next = fragtree->rb_node;

	while(next) {
		frag = rb_entry(next, struct jffs2_node_frag, rb);

		D2(printk(KERN_DEBUG "Considering frag %d-%d (%p). left %p, right %p\n",
			  frag->ofs, frag->ofs+frag->size, frag, frag->rb.rb_left, frag->rb.rb_right));
		if (frag->ofs + frag->size <= offset) {
			D2(printk(KERN_DEBUG "Going right from frag %d-%d, before the region we care about\n",
				  frag->ofs, frag->ofs+frag->size));
			/* Remember the closest smaller match on the way down */
			if (!prev || frag->ofs > prev->ofs)
				prev = frag;
			next = frag->rb.rb_right;
		} else if (frag->ofs > offset) {
			D2(printk(KERN_DEBUG "Going left from frag %d-%d, after the region we care about\n",
				  frag->ofs, frag->ofs+frag->size));
			next = frag->rb.rb_left;
		} else {
			D2(printk(KERN_DEBUG "Returning frag %d,%d, matched\n",
				  frag->ofs, frag->ofs+frag->size));
			return frag;
		}
	}

	/* Exact match not found. Go back up looking at each parent,
	   and return the closest smaller one */

	if (prev)
		D2(printk(KERN_DEBUG "No match. Returning frag %d,%d, closest previous\n",
			  prev->ofs, prev->ofs+prev->size));
	else 
		D2(printk(KERN_DEBUG "Returning NULL, empty fragtree\n"));
	
	return prev;
}

/* Pass 'c' argument to indicate that nodes should be marked obsolete as
   they're killed. */
void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c)
{
	struct jffs2_node_frag *frag;
	struct jffs2_node_frag *parent;

	if (!root->rb_node)
		return;

	frag = (rb_entry(root->rb_node, struct jffs2_node_frag, rb));

	while(frag) {
		if (frag->rb.rb_left) {
			D2(printk(KERN_DEBUG "Going left from frag (%p) %d-%d\n", 
				  frag, frag->ofs, frag->ofs+frag->size));
			frag = frag_left(frag);
			continue;
		}
		if (frag->rb.rb_right) {
			D2(printk(KERN_DEBUG "Going right from frag (%p) %d-%d\n", 
				  frag, frag->ofs, frag->ofs+frag->size));
			frag = frag_right(frag);
			continue;
		}

		D2(printk(KERN_DEBUG "jffs2_kill_fragtree: frag at 0x%x-0x%x: node %p, frags %d--\n",
			  frag->ofs, frag->ofs+frag->size, frag->node,
			  frag->node?frag->node->frags:0));
			
		if (frag->node && !(--frag->node->frags)) {
			/* Not a hole, and it's the final remaining frag 
			   of this node. Free the node */
			if (c)
				jffs2_mark_node_obsolete(c, frag->node->raw);
			
			jffs2_free_full_dnode(frag->node);
		}
		parent = frag_parent(frag);
		if (parent) {
			if (frag_left(parent) == frag)
				parent->rb.rb_left = NULL;
			else 
				parent->rb.rb_right = NULL;
		}

		jffs2_free_node_frag(frag);
		frag = parent;

		cond_resched();
	}
}

void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_node_frag *base)
{
	struct rb_node *parent = &base->rb;
	struct rb_node **link = &parent;

	D2(printk(KERN_DEBUG "jffs2_fragtree_insert(%p; %d-%d, %p)\n", newfrag, 
		  newfrag->ofs, newfrag->ofs+newfrag->size, base));

	while (*link) {
		parent = *link;
		base = rb_entry(parent, struct jffs2_node_frag, rb);
	
		D2(printk(KERN_DEBUG "fragtree_insert considering frag at 0x%x\n", base->ofs));
		if (newfrag->ofs > base->ofs)
			link = &base->rb.rb_right;
		else if (newfrag->ofs < base->ofs)
			link = &base->rb.rb_left;
		else {
			printk(KERN_CRIT "Duplicate frag at %08x (%p,%p)\n", newfrag->ofs, newfrag, base);
			BUG();
		}
	}

	rb_link_node(&newfrag->rb, &base->rb, link);
}
