/*
 * 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"

/*
 * 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;
}
