/*
 * 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 result;
	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) {
		result = yaffs_summary_fetch(dev, &tags, chunk_in_block);
		tags.seq_number = bi->seq_number;
	}

	if (!summary_available || tags.obj_id == 0) {
		result = 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.
			 */

			result = 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;
	int deleted;
	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);
		deleted = 0;

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