/*
 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
 *
 * Copyright (C) 2002-2011 Aleph One Ltd.
 *   for Toby Churchill Ltd and Brightstar Engineering
 *
 * Created by Charles Manning <charles@aleph1.co.uk>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include "yaffs_guts.h"
#include "yaffs_trace.h"
#include "yaffs_yaffs2.h"
#include "yaffs_checkptrw.h"
#include "yaffs_bitmap.h"
#include "yaffs_nand.h"
#include "yaffs_getblockinfo.h"
#include "yaffs_verify.h"
#include "yaffs_attribs.h"
#include "yaffs_summary.h"
#include <dm/devres.h>

/*
 * Checkpoints are really no benefit on very small partitions.
 *
 * To save space on small partitions don't bother with checkpoints unless
 * the partition is at least this big.
 */
#define YAFFS_CHECKPOINT_MIN_BLOCKS 60
#define YAFFS_SMALL_HOLE_THRESHOLD 4

/*
 * Oldest Dirty Sequence Number handling.
 */

/* yaffs_calc_oldest_dirty_seq()
 * yaffs2_find_oldest_dirty_seq()
 * Calculate the oldest dirty sequence number if we don't know it.
 */
void yaffs_calc_oldest_dirty_seq(struct yaffs_dev *dev)
{
	int i;
	unsigned seq;
	unsigned block_no = 0;
	struct yaffs_block_info *b;

	if (!dev->param.is_yaffs2)
		return;

	/* Find the oldest dirty sequence number. */
	seq = dev->seq_number + 1;
	b = dev->block_info;
	for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) {
		if (b->block_state == YAFFS_BLOCK_STATE_FULL &&
		    (b->pages_in_use - b->soft_del_pages) <
		    dev->param.chunks_per_block &&
		    b->seq_number < seq) {
			seq = b->seq_number;
			block_no = i;
		}
		b++;
	}

	if (block_no) {
		dev->oldest_dirty_seq = seq;
		dev->oldest_dirty_block = block_no;
	}
}

void yaffs2_find_oldest_dirty_seq(struct yaffs_dev *dev)
{
	if (!dev->param.is_yaffs2)
		return;

	if (!dev->oldest_dirty_seq)
		yaffs_calc_oldest_dirty_seq(dev);
}

/*
 * yaffs_clear_oldest_dirty_seq()
 * Called when a block is erased or marked bad. (ie. when its seq_number
 * becomes invalid). If the value matches the oldest then we clear
 * dev->oldest_dirty_seq to force its recomputation.
 */
void yaffs2_clear_oldest_dirty_seq(struct yaffs_dev *dev,
				   struct yaffs_block_info *bi)
{

	if (!dev->param.is_yaffs2)
		return;

	if (!bi || bi->seq_number == dev->oldest_dirty_seq) {
		dev->oldest_dirty_seq = 0;
		dev->oldest_dirty_block = 0;
	}
}

/*
 * yaffs2_update_oldest_dirty_seq()
 * Update the oldest dirty sequence number whenever we dirty a block.
 * Only do this if the oldest_dirty_seq is actually being tracked.
 */
void yaffs2_update_oldest_dirty_seq(struct yaffs_dev *dev, unsigned block_no,
				    struct yaffs_block_info *bi)
{
	if (!dev->param.is_yaffs2)
		return;

	if (dev->oldest_dirty_seq) {
		if (dev->oldest_dirty_seq > bi->seq_number) {
			dev->oldest_dirty_seq = bi->seq_number;
			dev->oldest_dirty_block = block_no;
		}
	}
}

int yaffs_block_ok_for_gc(struct yaffs_dev *dev, struct yaffs_block_info *bi)
{

	if (!dev->param.is_yaffs2)
		return 1;	/* disqualification only applies to yaffs2. */

	if (!bi->has_shrink_hdr)
		return 1;	/* can gc */

	yaffs2_find_oldest_dirty_seq(dev);

	/* Can't do gc of this block if there are any blocks older than this
	 * one that have discarded pages.
	 */
	return (bi->seq_number <= dev->oldest_dirty_seq);
}

/*
 * yaffs2_find_refresh_block()
 * periodically finds the oldest full block by sequence number for refreshing.
 * Only for yaffs2.
 */
u32 yaffs2_find_refresh_block(struct yaffs_dev *dev)
{
	u32 b;
	u32 oldest = 0;
	u32 oldest_seq = 0;
	struct yaffs_block_info *bi;

	if (!dev->param.is_yaffs2)
		return oldest;

	/*
	 * If refresh period < 10 then refreshing is disabled.
	 */
	if (dev->param.refresh_period < 10)
		return oldest;

	/*
	 * Fix broken values.
	 */
	if (dev->refresh_skip > dev->param.refresh_period)
		dev->refresh_skip = dev->param.refresh_period;

	if (dev->refresh_skip > 0)
		return oldest;

	/*
	 * Refresh skip is now zero.
	 * We'll do a refresh this time around....
	 * Update the refresh skip and find the oldest block.
	 */
	dev->refresh_skip = dev->param.refresh_period;
	dev->refresh_count++;
	bi = dev->block_info;
	for (b = dev->internal_start_block; b <= dev->internal_end_block; b++) {

		if (bi->block_state == YAFFS_BLOCK_STATE_FULL) {

			if (oldest < 1 || bi->seq_number < oldest_seq) {
				oldest = b;
				oldest_seq = bi->seq_number;
			}
		}
		bi++;
	}

	if (oldest > 0) {
		yaffs_trace(YAFFS_TRACE_GC,
			"GC refresh count %d selected block %d with seq_number %d",
			dev->refresh_count, oldest, oldest_seq);
	}

	return oldest;
}

int yaffs2_checkpt_required(struct yaffs_dev *dev)
{
	int nblocks;

	if (!dev->param.is_yaffs2)
		return 0;

	nblocks = dev->internal_end_block - dev->internal_start_block + 1;

	return !dev->param.skip_checkpt_wr &&
	    !dev->read_only && (nblocks >= YAFFS_CHECKPOINT_MIN_BLOCKS);
}

int yaffs_calc_checkpt_blocks_required(struct yaffs_dev *dev)
{
	int retval;
	int n_bytes = 0;
	int n_blocks;
	int dev_blocks;

	if (!dev->param.is_yaffs2)
		return 0;

	if (!dev->checkpoint_blocks_required && yaffs2_checkpt_required(dev)) {
		/* Not a valid value so recalculate */
		dev_blocks = dev->param.end_block - dev->param.start_block + 1;
		n_bytes += sizeof(struct yaffs_checkpt_validity);
		n_bytes += sizeof(struct yaffs_checkpt_dev);
		n_bytes += dev_blocks * sizeof(struct yaffs_block_info);
		n_bytes += dev_blocks * dev->chunk_bit_stride;
		n_bytes +=
		    (sizeof(struct yaffs_checkpt_obj) + sizeof(u32)) *
		    dev->n_obj;
		n_bytes += (dev->tnode_size + sizeof(u32)) * dev->n_tnodes;
		n_bytes += sizeof(struct yaffs_checkpt_validity);
		n_bytes += sizeof(u32);	/* checksum */

		/* Round up and add 2 blocks to allow for some bad blocks,
		 * so add 3 */

		n_blocks =
		    (n_bytes /
		     (dev->data_bytes_per_chunk *
		      dev->param.chunks_per_block)) + 3;

		dev->checkpoint_blocks_required = n_blocks;
	}

	retval = dev->checkpoint_blocks_required - dev->blocks_in_checkpt;
	if (retval < 0)
		retval = 0;
	return retval;
}

/*--------------------- Checkpointing --------------------*/

static int yaffs2_wr_checkpt_validity_marker(struct yaffs_dev *dev, int head)
{
	struct yaffs_checkpt_validity cp;

	memset(&cp, 0, sizeof(cp));

	cp.struct_type = sizeof(cp);
	cp.magic = YAFFS_MAGIC;
	cp.version = YAFFS_CHECKPOINT_VERSION;
	cp.head = (head) ? 1 : 0;

	return (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp)) ? 1 : 0;
}

static int yaffs2_rd_checkpt_validity_marker(struct yaffs_dev *dev, int head)
{
	struct yaffs_checkpt_validity cp;
	int ok;

	ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));

	if (ok)
		ok = (cp.struct_type == sizeof(cp)) &&
		    (cp.magic == YAFFS_MAGIC) &&
		    (cp.version == YAFFS_CHECKPOINT_VERSION) &&
		    (cp.head == ((head) ? 1 : 0));
	return ok ? 1 : 0;
}

static void yaffs2_dev_to_checkpt_dev(struct yaffs_checkpt_dev *cp,
				      struct yaffs_dev *dev)
{
	cp->n_erased_blocks = dev->n_erased_blocks;
	cp->alloc_block = dev->alloc_block;
	cp->alloc_page = dev->alloc_page;
	cp->n_free_chunks = dev->n_free_chunks;

	cp->n_deleted_files = dev->n_deleted_files;
	cp->n_unlinked_files = dev->n_unlinked_files;
	cp->n_bg_deletions = dev->n_bg_deletions;
	cp->seq_number = dev->seq_number;

}

static void yaffs_checkpt_dev_to_dev(struct yaffs_dev *dev,
				     struct yaffs_checkpt_dev *cp)
{
	dev->n_erased_blocks = cp->n_erased_blocks;
	dev->alloc_block = cp->alloc_block;
	dev->alloc_page = cp->alloc_page;
	dev->n_free_chunks = cp->n_free_chunks;

	dev->n_deleted_files = cp->n_deleted_files;
	dev->n_unlinked_files = cp->n_unlinked_files;
	dev->n_bg_deletions = cp->n_bg_deletions;
	dev->seq_number = cp->seq_number;
}

static int yaffs2_wr_checkpt_dev(struct yaffs_dev *dev)
{
	struct yaffs_checkpt_dev cp;
	u32 n_bytes;
	u32 n_blocks = dev->internal_end_block - dev->internal_start_block + 1;
	int ok;

	/* Write device runtime values */
	yaffs2_dev_to_checkpt_dev(&cp, dev);
	cp.struct_type = sizeof(cp);

	ok = (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp));
	if (!ok)
		return 0;

	/* Write block info */
	n_bytes = n_blocks * sizeof(struct yaffs_block_info);
	ok = (yaffs2_checkpt_wr(dev, dev->block_info, n_bytes) == n_bytes);
	if (!ok)
		return 0;

	/* Write chunk bits */
	n_bytes = n_blocks * dev->chunk_bit_stride;
	ok = (yaffs2_checkpt_wr(dev, dev->chunk_bits, n_bytes) == n_bytes);

	return ok ? 1 : 0;
}

static int yaffs2_rd_checkpt_dev(struct yaffs_dev *dev)
{
	struct yaffs_checkpt_dev cp;
	u32 n_bytes;
	u32 n_blocks =
	    (dev->internal_end_block - dev->internal_start_block + 1);
	int ok;

	ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));
	if (!ok)
		return 0;

	if (cp.struct_type != sizeof(cp))
		return 0;

	yaffs_checkpt_dev_to_dev(dev, &cp);

	n_bytes = n_blocks * sizeof(struct yaffs_block_info);

	ok = (yaffs2_checkpt_rd(dev, dev->block_info, n_bytes) == n_bytes);

	if (!ok)
		return 0;

	n_bytes = n_blocks * dev->chunk_bit_stride;

	ok = (yaffs2_checkpt_rd(dev, dev->chunk_bits, n_bytes) == n_bytes);

	return ok ? 1 : 0;
}

static void yaffs2_obj_checkpt_obj(struct yaffs_checkpt_obj *cp,
				   struct yaffs_obj *obj)
{
	cp->obj_id = obj->obj_id;
	cp->parent_id = (obj->parent) ? obj->parent->obj_id : 0;
	cp->hdr_chunk = obj->hdr_chunk;
	cp->variant_type = obj->variant_type;
	cp->deleted = obj->deleted;
	cp->soft_del = obj->soft_del;
	cp->unlinked = obj->unlinked;
	cp->fake = obj->fake;
	cp->rename_allowed = obj->rename_allowed;
	cp->unlink_allowed = obj->unlink_allowed;
	cp->serial = obj->serial;
	cp->n_data_chunks = obj->n_data_chunks;

	if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE)
		cp->size_or_equiv_obj = obj->variant.file_variant.file_size;
	else if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK)
		cp->size_or_equiv_obj = obj->variant.hardlink_variant.equiv_id;
}

static int yaffs2_checkpt_obj_to_obj(struct yaffs_obj *obj,
				     struct yaffs_checkpt_obj *cp)
{
	struct yaffs_obj *parent;

	if (obj->variant_type != cp->variant_type) {
		yaffs_trace(YAFFS_TRACE_ERROR,
			"Checkpoint read object %d type %d chunk %d does not match existing object type %d",
			cp->obj_id, cp->variant_type, cp->hdr_chunk,
			obj->variant_type);
		return 0;
	}

	obj->obj_id = cp->obj_id;

	if (cp->parent_id)
		parent = yaffs_find_or_create_by_number(obj->my_dev,
						cp->parent_id,
						YAFFS_OBJECT_TYPE_DIRECTORY);
	else
		parent = NULL;

	if (parent) {
		if (parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
			yaffs_trace(YAFFS_TRACE_ALWAYS,
				"Checkpoint read object %d parent %d type %d chunk %d Parent type, %d, not directory",
				cp->obj_id, cp->parent_id,
				cp->variant_type, cp->hdr_chunk,
				parent->variant_type);
			return 0;
		}
		yaffs_add_obj_to_dir(parent, obj);
	}

	obj->hdr_chunk = cp->hdr_chunk;
	obj->variant_type = cp->variant_type;
	obj->deleted = cp->deleted;
	obj->soft_del = cp->soft_del;
	obj->unlinked = cp->unlinked;
	obj->fake = cp->fake;
	obj->rename_allowed = cp->rename_allowed;
	obj->unlink_allowed = cp->unlink_allowed;
	obj->serial = cp->serial;
	obj->n_data_chunks = cp->n_data_chunks;

	if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE)
		obj->variant.file_variant.file_size = cp->size_or_equiv_obj;
	else if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK)
		obj->variant.hardlink_variant.equiv_id = cp->size_or_equiv_obj;

	if (obj->hdr_chunk > 0)
		obj->lazy_loaded = 1;
	return 1;
}

static int yaffs2_checkpt_tnode_worker(struct yaffs_obj *in,
				       struct yaffs_tnode *tn, u32 level,
				       int chunk_offset)
{
	int i;
	struct yaffs_dev *dev = in->my_dev;
	int ok = 1;
	u32 base_offset;

	if (!tn)
		return 1;

	if (level > 0) {
		for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++) {
			if (!tn->internal[i])
				continue;
			ok = yaffs2_checkpt_tnode_worker(in,
				 tn->internal[i],
				 level - 1,
				 (chunk_offset <<
				  YAFFS_TNODES_INTERNAL_BITS) + i);
		}
		return ok;
	}

	/* Level 0 tnode */
	base_offset = chunk_offset << YAFFS_TNODES_LEVEL0_BITS;
	ok = (yaffs2_checkpt_wr(dev, &base_offset, sizeof(base_offset)) ==
			sizeof(base_offset));
	if (ok)
		ok = (yaffs2_checkpt_wr(dev, tn, dev->tnode_size) ==
			dev->tnode_size);

	return ok;
}

static int yaffs2_wr_checkpt_tnodes(struct yaffs_obj *obj)
{
	u32 end_marker = ~0;
	int ok = 1;

	if (obj->variant_type != YAFFS_OBJECT_TYPE_FILE)
		return ok;

	ok = yaffs2_checkpt_tnode_worker(obj,
					 obj->variant.file_variant.top,
					 obj->variant.file_variant.
					 top_level, 0);
	if (ok)
		ok = (yaffs2_checkpt_wr(obj->my_dev, &end_marker,
				sizeof(end_marker)) == sizeof(end_marker));

	return ok ? 1 : 0;
}

static int yaffs2_rd_checkpt_tnodes(struct yaffs_obj *obj)
{
	u32 base_chunk;
	int ok = 1;
	struct yaffs_dev *dev = obj->my_dev;
	struct yaffs_file_var *file_stuct_ptr = &obj->variant.file_variant;
	struct yaffs_tnode *tn;
	int nread = 0;

	ok = (yaffs2_checkpt_rd(dev, &base_chunk, sizeof(base_chunk)) ==
	      sizeof(base_chunk));

	while (ok && (~base_chunk)) {
		nread++;
		/* Read level 0 tnode */

		tn = yaffs_get_tnode(dev);
		if (tn)
			ok = (yaffs2_checkpt_rd(dev, tn, dev->tnode_size) ==
				dev->tnode_size);
		else
			ok = 0;

		if (tn && ok)
			ok = yaffs_add_find_tnode_0(dev,
						    file_stuct_ptr,
						    base_chunk, tn) ? 1 : 0;

		if (ok)
			ok = (yaffs2_checkpt_rd
			      (dev, &base_chunk,
			       sizeof(base_chunk)) == sizeof(base_chunk));
	}

	yaffs_trace(YAFFS_TRACE_CHECKPOINT,
		"Checkpoint read tnodes %d records, last %d. ok %d",
		nread, base_chunk, ok);

	return ok ? 1 : 0;
}

static int yaffs2_wr_checkpt_objs(struct yaffs_dev *dev)
{
	struct yaffs_obj *obj;
	struct yaffs_checkpt_obj cp;
	int i;
	int ok = 1;
	struct list_head *lh;

	/* Iterate through the objects in each hash entry,
	 * dumping them to the checkpointing stream.
	 */

	for (i = 0; ok && i < YAFFS_NOBJECT_BUCKETS; i++) {
		list_for_each(lh, &dev->obj_bucket[i].list) {
			obj = list_entry(lh, struct yaffs_obj, hash_link);
			if (!obj->defered_free) {
				yaffs2_obj_checkpt_obj(&cp, obj);
				cp.struct_type = sizeof(cp);

				yaffs_trace(YAFFS_TRACE_CHECKPOINT,
					"Checkpoint write object %d parent %d type %d chunk %d obj addr %p",
					cp.obj_id, cp.parent_id,
					cp.variant_type, cp.hdr_chunk, obj);

				ok = (yaffs2_checkpt_wr(dev, &cp,
						sizeof(cp)) == sizeof(cp));

				if (ok &&
					obj->variant_type ==
					YAFFS_OBJECT_TYPE_FILE)
					ok = yaffs2_wr_checkpt_tnodes(obj);
			}
		}
	}

	/* Dump end of list */
	memset(&cp, 0xff, sizeof(struct yaffs_checkpt_obj));
	cp.struct_type = sizeof(cp);

	if (ok)
		ok = (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp));

	return ok ? 1 : 0;
}

static int yaffs2_rd_checkpt_objs(struct yaffs_dev *dev)
{
	struct yaffs_obj *obj;
	struct yaffs_checkpt_obj cp;
	int ok = 1;
	int done = 0;
	LIST_HEAD(hard_list);

	while (ok && !done) {
		ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));
		if (cp.struct_type != sizeof(cp)) {
			yaffs_trace(YAFFS_TRACE_CHECKPOINT,
				"struct size %d instead of %d ok %d",
				cp.struct_type, (int)sizeof(cp), ok);
			ok = 0;
		}

		yaffs_trace(YAFFS_TRACE_CHECKPOINT,
			"Checkpoint read object %d parent %d type %d chunk %d ",
			cp.obj_id, cp.parent_id, cp.variant_type,
			cp.hdr_chunk);

		if (ok && cp.obj_id == ~0) {
			done = 1;
		} else if (ok) {
			obj =
			    yaffs_find_or_create_by_number(dev, cp.obj_id,
							   cp.variant_type);
			if (obj) {
				ok = yaffs2_checkpt_obj_to_obj(obj, &cp);
				if (!ok)
					break;
				if (obj->variant_type ==
					YAFFS_OBJECT_TYPE_FILE) {
					ok = yaffs2_rd_checkpt_tnodes(obj);
				} else if (obj->variant_type ==
					YAFFS_OBJECT_TYPE_HARDLINK) {
					list_add(&obj->hard_links, &hard_list);
				}
			} else {
				ok = 0;
			}
		}
	}

	if (ok)
		yaffs_link_fixup(dev, &hard_list);

	return ok ? 1 : 0;
}

static int yaffs2_wr_checkpt_sum(struct yaffs_dev *dev)
{
	u32 checkpt_sum;
	int ok;

	yaffs2_get_checkpt_sum(dev, &checkpt_sum);

	ok = (yaffs2_checkpt_wr(dev, &checkpt_sum, sizeof(checkpt_sum)) ==
		sizeof(checkpt_sum));

	if (!ok)
		return 0;

	return 1;
}

static int yaffs2_rd_checkpt_sum(struct yaffs_dev *dev)
{
	u32 checkpt_sum0;
	u32 checkpt_sum1;
	int ok;

	yaffs2_get_checkpt_sum(dev, &checkpt_sum0);

	ok = (yaffs2_checkpt_rd(dev, &checkpt_sum1, sizeof(checkpt_sum1)) ==
		sizeof(checkpt_sum1));

	if (!ok)
		return 0;

	if (checkpt_sum0 != checkpt_sum1)
		return 0;

	return 1;
}

static int yaffs2_wr_checkpt_data(struct yaffs_dev *dev)
{
	int ok = 1;

	if (!yaffs2_checkpt_required(dev)) {
		yaffs_trace(YAFFS_TRACE_CHECKPOINT,
			"skipping checkpoint write");
		ok = 0;
	}

	if (ok)
		ok = yaffs2_checkpt_open(dev, 1);

	if (ok) {
		yaffs_trace(YAFFS_TRACE_CHECKPOINT,
			"write checkpoint validity");
		ok = yaffs2_wr_checkpt_validity_marker(dev, 1);
	}
	if (ok) {
		yaffs_trace(YAFFS_TRACE_CHECKPOINT,
			"write checkpoint device");
		ok = yaffs2_wr_checkpt_dev(dev);
	}
	if (ok) {
		yaffs_trace(YAFFS_TRACE_CHECKPOINT,
			"write checkpoint objects");
		ok = yaffs2_wr_checkpt_objs(dev);
	}
	if (ok) {
		yaffs_trace(YAFFS_TRACE_CHECKPOINT,
			"write checkpoint validity");
		ok = yaffs2_wr_checkpt_validity_marker(dev, 0);
	}

	if (ok)
		ok = yaffs2_wr_checkpt_sum(dev);

	if (!yaffs_checkpt_close(dev))
		ok = 0;

	if (ok)
		dev->is_checkpointed = 1;
	else
		dev->is_checkpointed = 0;

	return dev->is_checkpointed;
}

static int yaffs2_rd_checkpt_data(struct yaffs_dev *dev)
{
	int ok = 1;

	if (!dev->param.is_yaffs2)
		ok = 0;

	if (ok && dev->param.skip_checkpt_rd) {
		yaffs_trace(YAFFS_TRACE_CHECKPOINT,
			"skipping checkpoint read");
		ok = 0;
	}

	if (ok)
		ok = yaffs2_checkpt_open(dev, 0); /* open for read */

	if (ok) {
		yaffs_trace(YAFFS_TRACE_CHECKPOINT,
			"read checkpoint validity");
		ok = yaffs2_rd_checkpt_validity_marker(dev, 1);
	}
	if (ok) {
		yaffs_trace(YAFFS_TRACE_CHECKPOINT,
			"read checkpoint device");
		ok = yaffs2_rd_checkpt_dev(dev);
	}
	if (ok) {
		yaffs_trace(YAFFS_TRACE_CHECKPOINT,
			"read checkpoint objects");
		ok = yaffs2_rd_checkpt_objs(dev);
	}
	if (ok) {
		yaffs_trace(YAFFS_TRACE_CHECKPOINT,
			"read checkpoint validity");
		ok = yaffs2_rd_checkpt_validity_marker(dev, 0);
	}

	if (ok) {
		ok = yaffs2_rd_checkpt_sum(dev);
		yaffs_trace(YAFFS_TRACE_CHECKPOINT,
			"read checkpoint checksum %d", ok);
	}

	if (!yaffs_checkpt_close(dev))
		ok = 0;

	if (ok)
		dev->is_checkpointed = 1;
	else
		dev->is_checkpointed = 0;

	return ok ? 1 : 0;
}

void yaffs2_checkpt_invalidate(struct yaffs_dev *dev)
{
	if (dev->is_checkpointed || dev->blocks_in_checkpt > 0) {
		dev->is_checkpointed = 0;
		yaffs2_checkpt_invalidate_stream(dev);
	}
	if (dev->param.sb_dirty_fn)
		dev->param.sb_dirty_fn(dev);
}

int yaffs_checkpoint_save(struct yaffs_dev *dev)
{
	yaffs_trace(YAFFS_TRACE_CHECKPOINT,
		"save entry: is_checkpointed %d",
		dev->is_checkpointed);

	yaffs_verify_objects(dev);
	yaffs_verify_blocks(dev);
	yaffs_verify_free_chunks(dev);

	if (!dev->is_checkpointed) {
		yaffs2_checkpt_invalidate(dev);
		yaffs2_wr_checkpt_data(dev);
	}

	yaffs_trace(YAFFS_TRACE_CHECKPOINT | YAFFS_TRACE_MOUNT,
		"save exit: is_checkpointed %d",
		dev->is_checkpointed);

	return dev->is_checkpointed;
}

int yaffs2_checkpt_restore(struct yaffs_dev *dev)
{
	int retval;

	yaffs_trace(YAFFS_TRACE_CHECKPOINT,
		"restore entry: is_checkpointed %d",
		dev->is_checkpointed);

	retval = yaffs2_rd_checkpt_data(dev);

	if (dev->is_checkpointed) {
		yaffs_verify_objects(dev);
		yaffs_verify_blocks(dev);
		yaffs_verify_free_chunks(dev);
	}

	yaffs_trace(YAFFS_TRACE_CHECKPOINT,
		"restore exit: is_checkpointed %d",
		dev->is_checkpointed);

	return retval;
}

int yaffs2_handle_hole(struct yaffs_obj *obj, loff_t new_size)
{
	/* if new_size > old_file_size.
	 * We're going to be writing a hole.
	 * If the hole is small then write zeros otherwise write a start
	 * of hole marker.
	 */
	loff_t old_file_size;
	loff_t increase;
	int small_hole;
	int result = YAFFS_OK;
	struct yaffs_dev *dev = NULL;
	u8 *local_buffer = NULL;
	int small_increase_ok = 0;

	if (!obj)
		return YAFFS_FAIL;

	if (obj->variant_type != YAFFS_OBJECT_TYPE_FILE)
		return YAFFS_FAIL;

	dev = obj->my_dev;

	/* Bail out if not yaffs2 mode */
	if (!dev->param.is_yaffs2)
		return YAFFS_OK;

	old_file_size = obj->variant.file_variant.file_size;

	if (new_size <= old_file_size)
		return YAFFS_OK;

	increase = new_size - old_file_size;

	if (increase < YAFFS_SMALL_HOLE_THRESHOLD * dev->data_bytes_per_chunk &&
	    yaffs_check_alloc_available(dev, YAFFS_SMALL_HOLE_THRESHOLD + 1))
		small_hole = 1;
	else
		small_hole = 0;

	if (small_hole)
		local_buffer = yaffs_get_temp_buffer(dev);

	if (local_buffer) {
		/* fill hole with zero bytes */
		loff_t pos = old_file_size;
		int this_write;
		int written;
		memset(local_buffer, 0, dev->data_bytes_per_chunk);
		small_increase_ok = 1;

		while (increase > 0 && small_increase_ok) {
			this_write = increase;
			if (this_write > dev->data_bytes_per_chunk)
				this_write = dev->data_bytes_per_chunk;
			written =
			    yaffs_do_file_wr(obj, local_buffer, pos, this_write,
					     0);
			if (written == this_write) {
				pos += this_write;
				increase -= this_write;
			} else {
				small_increase_ok = 0;
			}
		}

		yaffs_release_temp_buffer(dev, local_buffer);

		/* If out of space then reverse any chunks we've added */
		if (!small_increase_ok)
			yaffs_resize_file_down(obj, old_file_size);
	}

	if (!small_increase_ok &&
	    obj->parent &&
	    obj->parent->obj_id != YAFFS_OBJECTID_UNLINKED &&
	    obj->parent->obj_id != YAFFS_OBJECTID_DELETED) {
		/* Write a hole start header with the old file size */
		yaffs_update_oh(obj, NULL, 0, 1, 0, NULL);
	}

	return result;
}

struct yaffs_block_index {
	int seq;
	int block;
};

static int yaffs2_ybicmp(const void *a, const void *b)
{
	int aseq = ((struct yaffs_block_index *)a)->seq;
	int bseq = ((struct yaffs_block_index *)b)->seq;
	int ablock = ((struct yaffs_block_index *)a)->block;
	int bblock = ((struct yaffs_block_index *)b)->block;

	if (aseq == bseq)
		return ablock - bblock;

	return aseq - bseq;
}

static inline int yaffs2_scan_chunk(struct yaffs_dev *dev,
		struct yaffs_block_info *bi,
		int blk, int chunk_in_block,
		int *found_chunks,
		u8 *chunk_data,
		struct list_head *hard_list,
		int summary_available)
{
	struct yaffs_obj_hdr *oh;
	struct yaffs_obj *in;
	struct yaffs_obj *parent;
	int equiv_id;
	loff_t file_size;
	int is_shrink;
	int is_unlinked;
	struct yaffs_ext_tags tags;
	int alloc_failed = 0;
	int chunk = blk * dev->param.chunks_per_block + chunk_in_block;
	struct yaffs_file_var *file_var;
	struct yaffs_hardlink_var *hl_var;
	struct yaffs_symlink_var *sl_var;

	if (summary_available) {
		yaffs_summary_fetch(dev, &tags, chunk_in_block);
		tags.seq_number = bi->seq_number;
	}

	if (!summary_available || tags.obj_id == 0) {
		yaffs_rd_chunk_tags_nand(dev, chunk, NULL, &tags);
		dev->tags_used++;
	} else {
		dev->summary_used++;
	}

	/* Let's have a good look at this chunk... */

	if (!tags.chunk_used) {
		/* An unassigned chunk in the block.
		 * If there are used chunks after this one, then
		 * it is a chunk that was skipped due to failing
		 * the erased check. Just skip it so that it can
		 * be deleted.
		 * But, more typically, We get here when this is
		 * an unallocated chunk and his means that
		 * either the block is empty or this is the one
		 * being allocated from
		 */

		if (*found_chunks) {
			/* This is a chunk that was skipped due
			 * to failing the erased check */
		} else if (chunk_in_block == 0) {
			/* We're looking at the first chunk in
			 * the block so the block is unused */
			bi->block_state = YAFFS_BLOCK_STATE_EMPTY;
			dev->n_erased_blocks++;
		} else {
			if (bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN ||
			    bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING) {
				if (dev->seq_number == bi->seq_number) {
					/* Allocating from this block*/
					yaffs_trace(YAFFS_TRACE_SCAN,
					    " Allocating from %d %d",
					    blk, chunk_in_block);

					bi->block_state =
						YAFFS_BLOCK_STATE_ALLOCATING;
					dev->alloc_block = blk;
					dev->alloc_page = chunk_in_block;
					dev->alloc_block_finder = blk;
				} else {
					/* This is a partially written block
					 * that is not the current
					 * allocation block.
					 */
					yaffs_trace(YAFFS_TRACE_SCAN,
						"Partially written block %d detected. gc will fix this.",
						blk);
				}
			}
		}

		dev->n_free_chunks++;

	} else if (tags.ecc_result ==
		YAFFS_ECC_RESULT_UNFIXED) {
		yaffs_trace(YAFFS_TRACE_SCAN,
			" Unfixed ECC in chunk(%d:%d), chunk ignored",
			blk, chunk_in_block);
			dev->n_free_chunks++;
	} else if (tags.obj_id > YAFFS_MAX_OBJECT_ID ||
		   tags.chunk_id > YAFFS_MAX_CHUNK_ID ||
		   tags.obj_id == YAFFS_OBJECTID_SUMMARY ||
		   (tags.chunk_id > 0 &&
		     tags.n_bytes > dev->data_bytes_per_chunk) ||
		   tags.seq_number != bi->seq_number) {
		yaffs_trace(YAFFS_TRACE_SCAN,
			"Chunk (%d:%d) with bad tags:obj = %d, chunk_id = %d, n_bytes = %d, ignored",
			blk, chunk_in_block, tags.obj_id,
			tags.chunk_id, tags.n_bytes);
		dev->n_free_chunks++;
	} else if (tags.chunk_id > 0) {
		/* chunk_id > 0 so it is a data chunk... */
		loff_t endpos;
		loff_t chunk_base = (tags.chunk_id - 1) *
					dev->data_bytes_per_chunk;

		*found_chunks = 1;

		yaffs_set_chunk_bit(dev, blk, chunk_in_block);
		bi->pages_in_use++;

		in = yaffs_find_or_create_by_number(dev,
					tags.obj_id,
					YAFFS_OBJECT_TYPE_FILE);
		if (!in)
			/* Out of memory */
			alloc_failed = 1;

		if (in &&
		    in->variant_type == YAFFS_OBJECT_TYPE_FILE &&
		    chunk_base < in->variant.file_variant.shrink_size) {
			/* This has not been invalidated by
			 * a resize */
			if (!yaffs_put_chunk_in_file(in, tags.chunk_id,
								chunk, -1))
				alloc_failed = 1;

			/* File size is calculated by looking at
			 * the data chunks if we have not
			 * seen an object header yet.
			 * Stop this practice once we find an
			 * object header.
			 */
			endpos = chunk_base + tags.n_bytes;

			if (!in->valid &&
			    in->variant.file_variant.scanned_size < endpos) {
				in->variant.file_variant.
				    scanned_size = endpos;
				in->variant.file_variant.
				    file_size = endpos;
			}
		} else if (in) {
			/* This chunk has been invalidated by a
			 * resize, or a past file deletion
			 * so delete the chunk*/
			yaffs_chunk_del(dev, chunk, 1, __LINE__);
		}
	} else {
		/* chunk_id == 0, so it is an ObjectHeader.
		 * Thus, we read in the object header and make
		 * the object
		 */
		*found_chunks = 1;

		yaffs_set_chunk_bit(dev, blk, chunk_in_block);
		bi->pages_in_use++;

		oh = NULL;
		in = NULL;

		if (tags.extra_available) {
			in = yaffs_find_or_create_by_number(dev,
					tags.obj_id,
					tags.extra_obj_type);
			if (!in)
				alloc_failed = 1;
		}

		if (!in ||
		    (!in->valid && dev->param.disable_lazy_load) ||
		    tags.extra_shadows ||
		    (!in->valid && (tags.obj_id == YAFFS_OBJECTID_ROOT ||
				 tags.obj_id == YAFFS_OBJECTID_LOSTNFOUND))) {

			/* If we don't have  valid info then we
			 * need to read the chunk
			 * TODO In future we can probably defer
			 * reading the chunk and living with
			 * invalid data until needed.
			 */

			yaffs_rd_chunk_tags_nand(dev, chunk, chunk_data, NULL);

			oh = (struct yaffs_obj_hdr *)chunk_data;

			if (dev->param.inband_tags) {
				/* Fix up the header if they got
				 * corrupted by inband tags */
				oh->shadows_obj =
				    oh->inband_shadowed_obj_id;
				oh->is_shrink =
				    oh->inband_is_shrink;
			}

			if (!in) {
				in = yaffs_find_or_create_by_number(dev,
							tags.obj_id, oh->type);
				if (!in)
					alloc_failed = 1;
			}
		}

		if (!in) {
			/* TODO Hoosterman we have a problem! */
			yaffs_trace(YAFFS_TRACE_ERROR,
				"yaffs tragedy: Could not make object for object  %d at chunk %d during scan",
				tags.obj_id, chunk);
			return YAFFS_FAIL;
		}

		if (in->valid) {
			/* We have already filled this one.
			 * We have a duplicate that will be
			 * discarded, but we first have to suck
			 * out resize info if it is a file.
			 */
			if ((in->variant_type == YAFFS_OBJECT_TYPE_FILE) &&
				((oh && oh->type == YAFFS_OBJECT_TYPE_FILE) ||
				 (tags.extra_available &&
				  tags.extra_obj_type == YAFFS_OBJECT_TYPE_FILE)
				)) {
				loff_t this_size = (oh) ?
					yaffs_oh_to_size(oh) :
					tags.extra_file_size;
				u32 parent_obj_id = (oh) ?
					oh->parent_obj_id :
					tags.extra_parent_id;

				is_shrink = (oh) ?
					oh->is_shrink :
					tags.extra_is_shrink;

				/* If it is deleted (unlinked
				 * at start also means deleted)
				 * we treat the file size as
				 * being zeroed at this point.
				 */
				if (parent_obj_id == YAFFS_OBJECTID_DELETED ||
				    parent_obj_id == YAFFS_OBJECTID_UNLINKED) {
					this_size = 0;
					is_shrink = 1;
				}

				if (is_shrink &&
				    in->variant.file_variant.shrink_size >
				    this_size)
					in->variant.file_variant.shrink_size =
					this_size;

				if (is_shrink)
					bi->has_shrink_hdr = 1;
			}
			/* Use existing - destroy this one. */
			yaffs_chunk_del(dev, chunk, 1, __LINE__);
		}

		if (!in->valid && in->variant_type !=
		    (oh ? oh->type : tags.extra_obj_type))
			yaffs_trace(YAFFS_TRACE_ERROR,
				"yaffs tragedy: Bad object type, %d != %d, for object %d at chunk %d during scan",
				oh ? oh->type : tags.extra_obj_type,
				in->variant_type, tags.obj_id,
				chunk);

		if (!in->valid &&
		    (tags.obj_id == YAFFS_OBJECTID_ROOT ||
		     tags.obj_id == YAFFS_OBJECTID_LOSTNFOUND)) {
			/* We only load some info, don't fiddle
			 * with directory structure */
			in->valid = 1;

			if (oh) {
				in->yst_mode = oh->yst_mode;
				yaffs_load_attribs(in, oh);
				in->lazy_loaded = 0;
			} else {
				in->lazy_loaded = 1;
			}
			in->hdr_chunk = chunk;

		} else if (!in->valid) {
			/* we need to load this info */
			in->valid = 1;
			in->hdr_chunk = chunk;
			if (oh) {
				in->variant_type = oh->type;
				in->yst_mode = oh->yst_mode;
				yaffs_load_attribs(in, oh);

				if (oh->shadows_obj > 0)
					yaffs_handle_shadowed_obj(dev,
					     oh->shadows_obj, 1);

				yaffs_set_obj_name_from_oh(in, oh);
				parent = yaffs_find_or_create_by_number(dev,
						oh->parent_obj_id,
						YAFFS_OBJECT_TYPE_DIRECTORY);
				file_size = yaffs_oh_to_size(oh);
				is_shrink = oh->is_shrink;
				equiv_id = oh->equiv_id;
			} else {
				in->variant_type = tags.extra_obj_type;
				parent = yaffs_find_or_create_by_number(dev,
						tags.extra_parent_id,
						YAFFS_OBJECT_TYPE_DIRECTORY);
				file_size = tags.extra_file_size;
				is_shrink = tags.extra_is_shrink;
				equiv_id = tags.extra_equiv_id;
				in->lazy_loaded = 1;
			}
			in->dirty = 0;

			if (!parent)
				alloc_failed = 1;

			/* directory stuff...
			 * hook up to parent
			 */

			if (parent &&
			    parent->variant_type == YAFFS_OBJECT_TYPE_UNKNOWN) {
				/* Set up as a directory */
				parent->variant_type =
					YAFFS_OBJECT_TYPE_DIRECTORY;
				INIT_LIST_HEAD(&parent->
						variant.dir_variant.children);
			} else if (!parent ||
				   parent->variant_type !=
					YAFFS_OBJECT_TYPE_DIRECTORY) {
				/* Hoosterman, another problem....
				 * Trying to use a non-directory as a directory
				 */

				yaffs_trace(YAFFS_TRACE_ERROR,
					"yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
					);
				parent = dev->lost_n_found;
			}
			yaffs_add_obj_to_dir(parent, in);

			is_unlinked = (parent == dev->del_dir) ||
					(parent == dev->unlinked_dir);

			if (is_shrink)
				/* Mark the block */
				bi->has_shrink_hdr = 1;

			/* Note re hardlinks.
			 * Since we might scan a hardlink before its equivalent
			 * object is scanned we put them all in a list.
			 * After scanning is complete, we should have all the
			 * objects, so we run through this list and fix up all
			 * the chains.
			 */

			switch (in->variant_type) {
			case YAFFS_OBJECT_TYPE_UNKNOWN:
				/* Todo got a problem */
				break;
			case YAFFS_OBJECT_TYPE_FILE:
				file_var = &in->variant.file_variant;
				if (file_var->scanned_size < file_size) {
					/* This covers the case where the file
					 * size is greater than the data held.
					 * This will happen if the file is
					 * resized to be larger than its
					 * current data extents.
					 */
					file_var->file_size = file_size;
					file_var->scanned_size = file_size;
				}

				if (file_var->shrink_size > file_size)
					file_var->shrink_size = file_size;

				break;
			case YAFFS_OBJECT_TYPE_HARDLINK:
				hl_var = &in->variant.hardlink_variant;
				if (!is_unlinked) {
					hl_var->equiv_id = equiv_id;
					list_add(&in->hard_links, hard_list);
				}
				break;
			case YAFFS_OBJECT_TYPE_DIRECTORY:
				/* Do nothing */
				break;
			case YAFFS_OBJECT_TYPE_SPECIAL:
				/* Do nothing */
				break;
			case YAFFS_OBJECT_TYPE_SYMLINK:
				sl_var = &in->variant.symlink_variant;
				if (oh) {
					sl_var->alias =
					    yaffs_clone_str(oh->alias);
					if (!sl_var->alias)
						alloc_failed = 1;
				}
				break;
			}
		}
	}
	return alloc_failed ? YAFFS_FAIL : YAFFS_OK;
}

int yaffs2_scan_backwards(struct yaffs_dev *dev)
{
	int blk;
	int block_iter;
	int start_iter;
	int end_iter;
	int n_to_scan = 0;
	enum yaffs_block_state state;
	int c;
	LIST_HEAD(hard_list);
	struct yaffs_block_info *bi;
	u32 seq_number;
	int n_blocks = dev->internal_end_block - dev->internal_start_block + 1;
	u8 *chunk_data;
	int found_chunks;
	int alloc_failed = 0;
	struct yaffs_block_index *block_index = NULL;
	int alt_block_index = 0;
	int summary_available;

	yaffs_trace(YAFFS_TRACE_SCAN,
		"yaffs2_scan_backwards starts  intstartblk %d intendblk %d...",
		dev->internal_start_block, dev->internal_end_block);

	dev->seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER;

	block_index =
		kmalloc(n_blocks * sizeof(struct yaffs_block_index), GFP_NOFS);

	if (!block_index) {
		block_index =
		    vmalloc(n_blocks * sizeof(struct yaffs_block_index));
		alt_block_index = 1;
	}

	if (!block_index) {
		yaffs_trace(YAFFS_TRACE_SCAN,
			"yaffs2_scan_backwards() could not allocate block index!"
			);
		return YAFFS_FAIL;
	}

	dev->blocks_in_checkpt = 0;

	chunk_data = yaffs_get_temp_buffer(dev);

	/* Scan all the blocks to determine their state */
	bi = dev->block_info;
	for (blk = dev->internal_start_block; blk <= dev->internal_end_block;
	     blk++) {
		yaffs_clear_chunk_bits(dev, blk);
		bi->pages_in_use = 0;
		bi->soft_del_pages = 0;

		yaffs_query_init_block_state(dev, blk, &state, &seq_number);

		bi->block_state = state;
		bi->seq_number = seq_number;

		if (bi->seq_number == YAFFS_SEQUENCE_CHECKPOINT_DATA)
			bi->block_state = YAFFS_BLOCK_STATE_CHECKPOINT;
		if (bi->seq_number == YAFFS_SEQUENCE_BAD_BLOCK)
			bi->block_state = YAFFS_BLOCK_STATE_DEAD;

		yaffs_trace(YAFFS_TRACE_SCAN_DEBUG,
			"Block scanning block %d state %d seq %d",
			blk, bi->block_state, seq_number);

		if (bi->block_state == YAFFS_BLOCK_STATE_CHECKPOINT) {
			dev->blocks_in_checkpt++;

		} else if (bi->block_state == YAFFS_BLOCK_STATE_DEAD) {
			yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
				"block %d is bad", blk);
		} else if (bi->block_state == YAFFS_BLOCK_STATE_EMPTY) {
			yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "Block empty ");
			dev->n_erased_blocks++;
			dev->n_free_chunks += dev->param.chunks_per_block;
		} else if (bi->block_state ==
				YAFFS_BLOCK_STATE_NEEDS_SCAN) {
			/* Determine the highest sequence number */
			if (seq_number >= YAFFS_LOWEST_SEQUENCE_NUMBER &&
			    seq_number < YAFFS_HIGHEST_SEQUENCE_NUMBER) {
				block_index[n_to_scan].seq = seq_number;
				block_index[n_to_scan].block = blk;
				n_to_scan++;
				if (seq_number >= dev->seq_number)
					dev->seq_number = seq_number;
			} else {
				/* TODO: Nasty sequence number! */
				yaffs_trace(YAFFS_TRACE_SCAN,
					"Block scanning block %d has bad sequence number %d",
					blk, seq_number);
			}
		}
		bi++;
	}

	yaffs_trace(YAFFS_TRACE_SCAN, "%d blocks to be sorted...", n_to_scan);

	cond_resched();

	/* Sort the blocks by sequence number */
	sort(block_index, n_to_scan, sizeof(struct yaffs_block_index),
		   yaffs2_ybicmp, NULL);

	cond_resched();

	yaffs_trace(YAFFS_TRACE_SCAN, "...done");

	/* Now scan the blocks looking at the data. */
	start_iter = 0;
	end_iter = n_to_scan - 1;
	yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "%d blocks to scan", n_to_scan);

	/* For each block.... backwards */
	for (block_iter = end_iter;
	     !alloc_failed && block_iter >= start_iter;
	     block_iter--) {
		/* Cooperative multitasking! This loop can run for so
		   long that watchdog timers expire. */
		cond_resched();

		/* get the block to scan in the correct order */
		blk = block_index[block_iter].block;
		bi = yaffs_get_block_info(dev, blk);

		summary_available = yaffs_summary_read(dev, dev->sum_tags, blk);

		/* For each chunk in each block that needs scanning.... */
		found_chunks = 0;
		if (summary_available)
			c = dev->chunks_per_summary - 1;
		else
			c = dev->param.chunks_per_block - 1;

		for (/* c is already initialised */;
		     !alloc_failed && c >= 0 &&
		     (bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN ||
		      bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING);
		      c--) {
			/* Scan backwards...
			 * Read the tags and decide what to do
			 */
			if (yaffs2_scan_chunk(dev, bi, blk, c,
					&found_chunks, chunk_data,
					&hard_list, summary_available) ==
					YAFFS_FAIL)
				alloc_failed = 1;
		}

		if (bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN) {
			/* If we got this far while scanning, then the block
			 * is fully allocated. */
			bi->block_state = YAFFS_BLOCK_STATE_FULL;
		}

		/* Now let's see if it was dirty */
		if (bi->pages_in_use == 0 &&
		    !bi->has_shrink_hdr &&
		    bi->block_state == YAFFS_BLOCK_STATE_FULL) {
			yaffs_block_became_dirty(dev, blk);
		}
	}

	yaffs_skip_rest_of_block(dev);

	if (alt_block_index)
		vfree(block_index);
	else
		kfree(block_index);

	/* Ok, we've done all the scanning.
	 * Fix up the hard link chains.
	 * We have scanned all the objects, now it's time to add these
	 * hardlinks.
	 */
	yaffs_link_fixup(dev, &hard_list);

	yaffs_release_temp_buffer(dev, chunk_data);

	if (alloc_failed)
		return YAFFS_FAIL;

	yaffs_trace(YAFFS_TRACE_SCAN, "yaffs2_scan_backwards ends");

	return YAFFS_OK;
}
