/*
 * 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_yaffs1.h"
#include "yportenv.h"
#include "yaffs_trace.h"
#include "yaffs_bitmap.h"
#include "yaffs_getblockinfo.h"
#include "yaffs_nand.h"
#include "yaffs_attribs.h"

int yaffs1_scan(struct yaffs_dev *dev)
{
	struct yaffs_ext_tags tags;
	int blk;
	int chunk;
	int c;
	int deleted;
	enum yaffs_block_state state;
	LIST_HEAD(hard_list);
	struct yaffs_block_info *bi;
	u32 seq_number;
	struct yaffs_obj_hdr *oh;
	struct yaffs_obj *in;
	struct yaffs_obj *parent;
	int alloc_failed = 0;
	struct yaffs_shadow_fixer *shadow_fixers = NULL;
	u8 *chunk_data;

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

	chunk_data = yaffs_get_temp_buffer(dev);

	dev->seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER;

	/* 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_BAD_BLOCK)
			bi->block_state = state = YAFFS_BLOCK_STATE_DEAD;

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

		if (state == YAFFS_BLOCK_STATE_DEAD) {
			yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
				"block %d is bad", blk);
		} else if (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;
		}
		bi++;
	}

	/* For each block.... */
	for (blk = dev->internal_start_block;
	     !alloc_failed && blk <= dev->internal_end_block; blk++) {

		cond_resched();

		bi = yaffs_get_block_info(dev, blk);
		state = bi->block_state;

		deleted = 0;

		/* For each chunk in each block that needs scanning.... */
		for (c = 0;
			!alloc_failed && c < dev->param.chunks_per_block &&
			state == YAFFS_BLOCK_STATE_NEEDS_SCAN; c++) {
			/* Read the tags and decide what to do */
			chunk = blk * dev->param.chunks_per_block + c;

			yaffs_rd_chunk_tags_nand(dev, chunk, NULL, &tags);

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

			if (tags.ecc_result == YAFFS_ECC_RESULT_UNFIXED ||
			    tags.is_deleted) {
				/* YAFFS1 only...
				 * A deleted chunk
				 */
				deleted++;
				dev->n_free_chunks++;
			} else if (!tags.chunk_used) {
				/* An unassigned chunk in the block
				 * This means that either the block is empty or
				 * this is the one being allocated from
				 */

				if (c == 0) {
					/* We're looking at the first chunk in
					 *the block so the block is unused */
					state = YAFFS_BLOCK_STATE_EMPTY;
					dev->n_erased_blocks++;
				} else {
					/* this is the block being allocated */
					yaffs_trace(YAFFS_TRACE_SCAN,
						" Allocating from %d %d",
						blk, c);
					state = YAFFS_BLOCK_STATE_ALLOCATING;
					dev->alloc_block = blk;
					dev->alloc_page = c;
					dev->alloc_block_finder = blk;

				}

				dev->n_free_chunks +=
				    (dev->param.chunks_per_block - c);
			} else if (tags.chunk_id > 0) {
				/* chunk_id > 0 so it is a data chunk... */
				unsigned int endpos;

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

				in = yaffs_find_or_create_by_number(dev,
							tags.obj_id,
							YAFFS_OBJECT_TYPE_FILE);
				/* PutChunkIntoFile checks for a clash
				 * (two data chunks with the same chunk_id).
				 */

				if (!in)
					alloc_failed = 1;

				if (in) {
					if (!yaffs_put_chunk_in_file
					    (in, tags.chunk_id, chunk, 1))
						alloc_failed = 1;
				}

				endpos =
				    (tags.chunk_id - 1) *
				    dev->data_bytes_per_chunk +
				    tags.n_bytes;
				if (in &&
				    in->variant_type ==
				     YAFFS_OBJECT_TYPE_FILE &&
				    in->variant.file_variant.scanned_size <
				      endpos) {
					in->variant.file_variant.scanned_size =
					    endpos;
					if (!dev->param.use_header_file_size) {
						in->variant.
						    file_variant.file_size =
						    in->variant.
						    file_variant.scanned_size;
					}

				}
			} else {
				/* chunk_id == 0, so it is an ObjectHeader.
				 * Make the object
				 */
				yaffs_set_chunk_bit(dev, blk, c);
				bi->pages_in_use++;

				yaffs_rd_chunk_tags_nand(dev, chunk,
							 chunk_data, NULL);

				oh = (struct yaffs_obj_hdr *)chunk_data;

				in = yaffs_find_by_number(dev, tags.obj_id);
				if (in && in->variant_type != oh->type) {
					/* This should not happen, but somehow
					 * Wev'e ended up with an obj_id that
					 * has been reused but not yet deleted,
					 * and worse still it has changed type.
					 * Delete the old object.
					 */

					yaffs_del_obj(in);
					in = NULL;
				}

				in = yaffs_find_or_create_by_number(dev,
								tags.obj_id,
								oh->type);

				if (!in)
					alloc_failed = 1;

				if (in && oh->shadows_obj > 0) {

					struct yaffs_shadow_fixer *fixer;
					fixer =
						kmalloc(sizeof
						(struct yaffs_shadow_fixer),
						GFP_NOFS);
					if (fixer) {
						fixer->next = shadow_fixers;
						shadow_fixers = fixer;
						fixer->obj_id = tags.obj_id;
						fixer->shadowed_id =
						    oh->shadows_obj;
						yaffs_trace(YAFFS_TRACE_SCAN,
							" Shadow fixer: %d shadows %d",
							fixer->obj_id,
							fixer->shadowed_id);

					}

				}

				if (in && in->valid) {
					/* We have already filled this one.
					 * We have a duplicate and need to
					 * resolve it. */

					unsigned existing_serial = in->serial;
					unsigned new_serial =
					    tags.serial_number;

					if (((existing_serial + 1) & 3) ==
					    new_serial) {
						/* Use new one - destroy the
						 * exisiting one */
						yaffs_chunk_del(dev,
								in->hdr_chunk,
								1, __LINE__);
						in->valid = 0;
					} else {
						/* Use existing - destroy
						 * this one. */
						yaffs_chunk_del(dev, chunk, 1,
								__LINE__);
					}
				}

				if (in && !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;
					in->variant_type = oh->type;

					in->yst_mode = oh->yst_mode;
					yaffs_load_attribs(in, oh);
					in->hdr_chunk = chunk;
					in->serial = tags.serial_number;

				} else if (in && !in->valid) {
					/* we need to load this info */

					in->valid = 1;
					in->variant_type = oh->type;

					in->yst_mode = oh->yst_mode;
					yaffs_load_attribs(in, oh);
					in->hdr_chunk = chunk;
					in->serial = tags.serial_number;

					yaffs_set_obj_name_from_oh(in, oh);
					in->dirty = 0;

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

					parent =
					    yaffs_find_or_create_by_number
					    (dev, oh->parent_obj_id,
					     YAFFS_OBJECT_TYPE_DIRECTORY);
					if (!parent)
						alloc_failed = 1;
					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, a problem....
						 * We're 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);

					switch (in->variant_type) {
					case YAFFS_OBJECT_TYPE_UNKNOWN:
						/* Todo got a problem */
						break;
					case YAFFS_OBJECT_TYPE_FILE:
						if (dev->param.
						    use_header_file_size)
							in->variant.
							file_variant.file_size
							= yaffs_oh_to_size(oh);
						break;
					case YAFFS_OBJECT_TYPE_HARDLINK:
						in->variant.
						    hardlink_variant.equiv_id =
						    oh->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:
						in->variant.symlink_variant.
						    alias =
						    yaffs_clone_str(oh->alias);
						if (!in->variant.
						    symlink_variant.alias)
							alloc_failed = 1;
						break;
					}
				}
			}
		}

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

		if (state == YAFFS_BLOCK_STATE_ALLOCATING) {
			/* If the block was partially allocated then
			 * treat it as fully allocated. */
			state = YAFFS_BLOCK_STATE_FULL;
			dev->alloc_block = -1;
		}

		bi->block_state = state;

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

	/* Ok, we've done all the scanning.
	 * Fix up the hard link chains.
	 * We should now have scanned all the objects, now it's time to add
	 * these hardlinks.
	 */

	yaffs_link_fixup(dev, &hard_list);

	/*
	 * Fix up any shadowed objects.
	 * There should not be more than one of these.
	 */
	{
		struct yaffs_shadow_fixer *fixer;
		struct yaffs_obj *obj;

		while (shadow_fixers) {
			fixer = shadow_fixers;
			shadow_fixers = fixer->next;
			/* Complete the rename transaction by deleting the
			 * shadowed object then setting the object header
			 to unshadowed.
			 */
			obj = yaffs_find_by_number(dev, fixer->shadowed_id);
			if (obj)
				yaffs_del_obj(obj);

			obj = yaffs_find_by_number(dev, fixer->obj_id);

			if (obj)
				yaffs_update_oh(obj, NULL, 1, 0, 0, NULL);

			kfree(fixer);
		}
	}

	yaffs_release_temp_buffer(dev, chunk_data);

	if (alloc_failed)
		return YAFFS_FAIL;

	yaffs_trace(YAFFS_TRACE_SCAN, "yaffs1_scan ends");

	return YAFFS_OK;
}
