/*
 * 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"
#include <dm/devres.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;
}
