/*
 * 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 <div64.h>
#include "yaffsfs.h"
#include "yaffs_guts.h"
#include "yaffscfg.h"
#include "yportenv.h"
#include "yaffs_trace.h"
#include <dm/devres.h>

#define YAFFSFS_MAX_SYMLINK_DEREFERENCES 5

#ifndef NULL
#define NULL ((void *)0)
#endif

/* YAFFSFS_RW_SIZE must be a power of 2 */
#define YAFFSFS_RW_SHIFT (13)
#define YAFFSFS_RW_SIZE  (1<<YAFFSFS_RW_SHIFT)

/* Some forward references */
static struct yaffs_obj *yaffsfs_FindObject(struct yaffs_obj *relativeDirectory,
					    const YCHAR *path,
					    int symDepth, int getEquiv,
					    struct yaffs_obj **dirOut,
					    int *notDir, int *loop);

static void yaffsfs_RemoveObjectCallback(struct yaffs_obj *obj);

unsigned int yaffs_wr_attempts;

/*
 * Handle management.
 * There are open inodes in struct yaffsfs_Inode.
 * There are open file descriptors in yaffsfs_FileDes.
 * There are open handles in yaffsfs_FileDes.
 *
 * Things are structured this way to be like the Linux VFS model
 * so that interactions with the yaffs guts calls are similar.
 * That means more common code paths and less special code.
 * That means better testing etc.
 *
 * We have 3 layers because:
 * A handle is different than an fd because you can use dup()
 * to create a new handle that accesses the *same* fd. The two
 * handles will use the same offset (part of the fd). We only close
 * down the fd when there are no more handles accessing it.
 *
 * More than one fd can currently access one file, but each fd
 * has its own permsiions and offset.
 */

struct yaffsfs_Inode {
	int count;		/* Number of handles accessing this inode */
	struct yaffs_obj *iObj;
};

struct yaffsfs_FileDes {
	u8 reading:1;
	u8 writing:1;
	u8 append:1;
	u8 shareRead:1;
	u8 shareWrite:1;
	int inodeId:12;		/* Index to corresponding yaffsfs_Inode */
	int handleCount:10;	/* Number of handles for this fd */
	loff_t position;	/* current position in file */
};

struct yaffsfs_Handle {
	short int fdId;
	short int useCount;
};


struct yaffsfs_DirSearchContxt {
	struct yaffs_dirent de;	/* directory entry */
	YCHAR name[NAME_MAX + 1];	/* name of directory being searched */
	struct yaffs_obj *dirObj;	/* ptr to directory being searched */
	struct yaffs_obj *nextReturn;	/* obj  returned by next readddir */
	struct list_head others;
	int offset:20;
	unsigned inUse:1;
};

static struct yaffsfs_DirSearchContxt yaffsfs_dsc[YAFFSFS_N_DSC];
static struct yaffsfs_Inode yaffsfs_inode[YAFFSFS_N_HANDLES];
static struct yaffsfs_FileDes yaffsfs_fd[YAFFSFS_N_HANDLES];
static struct yaffsfs_Handle yaffsfs_handle[YAFFSFS_N_HANDLES];

static int yaffsfs_handlesInitialised;

unsigned yaffs_set_trace(unsigned tm)
{
	yaffs_trace_mask = tm;
	return yaffs_trace_mask;
}

unsigned yaffs_get_trace(void)
{
	return yaffs_trace_mask;
}

/*
 * yaffsfs_InitHandle
 * Inilitalise handle management on start-up.
 */

static void yaffsfs_InitHandles(void)
{
	int i;
	if (yaffsfs_handlesInitialised)
		return;

	memset(yaffsfs_inode, 0, sizeof(yaffsfs_inode));
	memset(yaffsfs_fd, 0, sizeof(yaffsfs_fd));
	memset(yaffsfs_handle, 0, sizeof(yaffsfs_handle));
	memset(yaffsfs_dsc, 0, sizeof(yaffsfs_dsc));

	for (i = 0; i < YAFFSFS_N_HANDLES; i++)
		yaffsfs_fd[i].inodeId = -1;
	for (i = 0; i < YAFFSFS_N_HANDLES; i++)
		yaffsfs_handle[i].fdId = -1;
}

static struct yaffsfs_Handle *yaffsfs_HandleToPointer(int h)
{
	if (h >= 0 && h < YAFFSFS_N_HANDLES)
		return &yaffsfs_handle[h];
	return NULL;
}

static struct yaffsfs_FileDes *yaffsfs_HandleToFileDes(int handle)
{
	struct yaffsfs_Handle *h = yaffsfs_HandleToPointer(handle);

	if (h && h->useCount > 0 && h->fdId >= 0 && h->fdId < YAFFSFS_N_HANDLES)
		return &yaffsfs_fd[h->fdId];

	return NULL;
}

static struct yaffsfs_Inode *yaffsfs_HandleToInode(int handle)
{
	struct yaffsfs_FileDes *fd = yaffsfs_HandleToFileDes(handle);

	if (fd && fd->handleCount > 0 &&
	    fd->inodeId >= 0 && fd->inodeId < YAFFSFS_N_HANDLES)
		return &yaffsfs_inode[fd->inodeId];

	return NULL;
}

static struct yaffs_obj *yaffsfs_HandleToObject(int handle)
{
	struct yaffsfs_Inode *in = yaffsfs_HandleToInode(handle);

	if (in)
		return in->iObj;

	return NULL;
}

/*
 * yaffsfs_FindInodeIdForObject
 * Find the inode entry for an object, if it exists.
 */

static int yaffsfs_FindInodeIdForObject(struct yaffs_obj *obj)
{
	int i;
	int ret = -1;

	if (obj)
		obj = yaffs_get_equivalent_obj(obj);

	/* Look for it in open inode table */
	for (i = 0; i < YAFFSFS_N_HANDLES && ret < 0; i++) {
		if (yaffsfs_inode[i].iObj == obj)
			ret = i;
	}
	return ret;
}

/*
 * yaffsfs_GetInodeIdForObject
 * Grab an inode entry when opening a new inode.
 */
static int yaffsfs_GetInodeIdForObject(struct yaffs_obj *obj)
{
	int i;
	int ret;
	struct yaffsfs_Inode *in = NULL;

	if (obj)
		obj = yaffs_get_equivalent_obj(obj);

	ret = yaffsfs_FindInodeIdForObject(obj);

	for (i = 0; i < YAFFSFS_N_HANDLES && ret < 0; i++) {
		if (!yaffsfs_inode[i].iObj)
			ret = i;
	}

	if (ret >= 0) {
		in = &yaffsfs_inode[ret];
		if (!in->iObj)
			in->count = 0;
		in->iObj = obj;
		in->count++;
	}

	return ret;
}

static int yaffsfs_CountHandles(struct yaffs_obj *obj)
{
	int i = yaffsfs_FindInodeIdForObject(obj);

	if (i >= 0)
		return yaffsfs_inode[i].count;
	else
		return 0;
}

static void yaffsfs_ReleaseInode(struct yaffsfs_Inode *in)
{
	struct yaffs_obj *obj;

	obj = in->iObj;

	if (obj->unlinked)
		yaffs_del_obj(obj);

	obj->my_inode = NULL;
	in->iObj = NULL;

}

static void yaffsfs_PutInode(int inodeId)
{
	if (inodeId >= 0 && inodeId < YAFFSFS_N_HANDLES) {
		struct yaffsfs_Inode *in = &yaffsfs_inode[inodeId];
		in->count--;
		if (in->count <= 0) {
			yaffsfs_ReleaseInode(in);
			in->count = 0;
		}
	}
}

static int yaffsfs_NewHandle(struct yaffsfs_Handle **hptr)
{
	int i;
	struct yaffsfs_Handle *h;

	for (i = 0; i < YAFFSFS_N_HANDLES; i++) {
		h = &yaffsfs_handle[i];
		if (h->useCount < 1) {
			memset(h, 0, sizeof(struct yaffsfs_Handle));
			h->fdId = -1;
			h->useCount = 1;
			if (hptr)
				*hptr = h;
			return i;
		}
	}
	return -1;
}

static int yaffsfs_NewHandleAndFileDes(void)
{
	int i;
	struct yaffsfs_FileDes *fd;
	struct yaffsfs_Handle *h = NULL;
	int handle = yaffsfs_NewHandle(&h);

	if (handle < 0)
		return -1;

	for (i = 0; i < YAFFSFS_N_HANDLES; i++) {
		fd = &yaffsfs_fd[i];
		if (fd->handleCount < 1) {
			memset(fd, 0, sizeof(struct yaffsfs_FileDes));
			fd->inodeId = -1;
			fd->handleCount = 1;
			h->fdId = i;
			return handle;
		}
	}

	/* Dump the handle because we could not get a fd */
	h->useCount = 0;
	return -1;
}

/*
 * yaffs_get_handle
 * Increase use of handle when reading/writing a file
 * Also gets the file descriptor.
 */

static int yaffsfs_GetHandle(int handle)
{
	struct yaffsfs_Handle *h = yaffsfs_HandleToPointer(handle);

	if (h && h->useCount > 0) {
		h->useCount++;
		return 0;
	}
	return -1;
}

/*
 * yaffs_put_handle
 * Let go of a handle when closing a file or aborting an open or
 * ending a read or write.
 */

static int yaffsfs_PutFileDes(int fdId)
{
	struct yaffsfs_FileDes *fd;

	if (fdId >= 0 && fdId < YAFFSFS_N_HANDLES) {
		fd = &yaffsfs_fd[fdId];
		fd->handleCount--;
		if (fd->handleCount < 1) {
			if (fd->inodeId >= 0) {
				yaffsfs_PutInode(fd->inodeId);
				fd->inodeId = -1;
			}
		}
	}
	return 0;
}

static int yaffsfs_PutHandle(int handle)
{
	struct yaffsfs_Handle *h = yaffsfs_HandleToPointer(handle);

	if (h && h->useCount > 0) {
		h->useCount--;
		if (h->useCount < 1) {
			yaffsfs_PutFileDes(h->fdId);
			h->fdId = -1;
		}
	}

	return 0;
}

static void yaffsfs_BreakDeviceHandles(struct yaffs_dev *dev)
{
	struct yaffsfs_FileDes *fd;
	struct yaffsfs_Handle *h;
	struct yaffs_obj *obj;
	int i;
	for (i = 0; i < YAFFSFS_N_HANDLES; i++) {
		h = yaffsfs_HandleToPointer(i);
		fd = yaffsfs_HandleToFileDes(i);
		obj = yaffsfs_HandleToObject(i);
		if (h && h->useCount > 0) {
			h->useCount = 0;
			h->fdId = 0;
		}
		if (fd && fd->handleCount > 0 && obj && obj->my_dev == dev) {
			fd->handleCount = 0;
			yaffsfs_PutInode(fd->inodeId);
			fd->inodeId = -1;
		}
	}
}

/*
 *  Stuff to handle names.
 */
#ifdef CONFIG_YAFFS_CASE_INSENSITIVE

static int yaffs_toupper(YCHAR a)
{
	if (a >= 'a' && a <= 'z')
		return (a - 'a') + 'A';
	else
		return a;
}

int yaffsfs_Match(YCHAR a, YCHAR b)
{
	return (yaffs_toupper(a) == yaffs_toupper(b));
}
#else
int yaffsfs_Match(YCHAR a, YCHAR b)
{
	/* case sensitive */
	return (a == b);
}
#endif

int yaffsfs_IsPathDivider(YCHAR ch)
{
	const YCHAR *str = YAFFS_PATH_DIVIDERS;

	while (*str) {
		if (*str == ch)
			return 1;
		str++;
	}

	return 0;
}

int yaffsfs_CheckNameLength(const char *name)
{
	int retVal = 0;

	int nameLength = yaffs_strnlen(name, YAFFS_MAX_NAME_LENGTH + 1);

	if (nameLength == 0) {
		yaffsfs_SetError(-ENOENT);
		retVal = -1;
	} else if (nameLength > YAFFS_MAX_NAME_LENGTH) {
		yaffsfs_SetError(-ENAMETOOLONG);
		retVal = -1;
	}

	return retVal;
}

static int yaffsfs_alt_dir_path(const YCHAR *path, YCHAR **ret_path)
{
	YCHAR *alt_path = NULL;
	int path_length;
	int i;

	/*
	 * We don't have a definition for max path length.
	 * We will use 3 * max name length instead.
	 */
	*ret_path = NULL;
	path_length = yaffs_strnlen(path, (YAFFS_MAX_NAME_LENGTH + 1) * 3 + 1);

	/* If the last character is a path divider, then we need to
	 * trim it back so that the name look-up works properly.
	 * eg. /foo/new_dir/ -> /foo/newdir
	 * Curveball: Need to handle multiple path dividers:
	 * eg. /foof/sdfse///// -> /foo/sdfse
	 */
	if (path_length > 0 && yaffsfs_IsPathDivider(path[path_length - 1])) {
		alt_path = kmalloc(path_length + 1, 0);
		if (!alt_path)
			return -1;
		yaffs_strcpy(alt_path, path);
		for (i = path_length - 1;
		     i >= 0 && yaffsfs_IsPathDivider(alt_path[i]); i--)
			alt_path[i] = (YCHAR) 0;
	}
	*ret_path = alt_path;
	return 0;
}

LIST_HEAD(yaffsfs_deviceList);

/*
 * yaffsfs_FindDevice
 * yaffsfs_FindRoot
 * Scan the configuration list to find the device
 * Curveballs: Should match paths that end in '/' too
 * Curveball2 Might have "/x/ and "/x/y". Need to return the longest match
 */
static struct yaffs_dev *yaffsfs_FindDevice(const YCHAR *path,
					    YCHAR **restOfPath)
{
	struct list_head *cfg;
	const YCHAR *leftOver;
	const YCHAR *p;
	struct yaffs_dev *retval = NULL;
	struct yaffs_dev *dev = NULL;
	int thisMatchLength;
	int longestMatch = -1;
	int matching;

	/*
	 * Check all configs, choose the one that:
	 * 1) Actually matches a prefix (ie /a amd /abc will not match
	 * 2) Matches the longest.
	 */
	list_for_each(cfg, &yaffsfs_deviceList) {
		dev = list_entry(cfg, struct yaffs_dev, dev_list);
		leftOver = path;
		p = dev->param.name;
		thisMatchLength = 0;
		matching = 1;

		while (matching && *p && *leftOver) {
			/* Skip over any /s */
			while (yaffsfs_IsPathDivider(*p))
				p++;

			/* Skip over any /s */
			while (yaffsfs_IsPathDivider(*leftOver))
				leftOver++;

			/* Now match the text part */
			while (matching &&
			       *p && !yaffsfs_IsPathDivider(*p) &&
			       *leftOver && !yaffsfs_IsPathDivider(*leftOver)) {
				if (yaffsfs_Match(*p, *leftOver)) {
					p++;
					leftOver++;
					thisMatchLength++;
				} else {
					matching = 0;
				}
			}
		}

		/* Skip over any /s in leftOver */
		while (yaffsfs_IsPathDivider(*leftOver))
			leftOver++;

		/*Skip over any /s in p */
		while (yaffsfs_IsPathDivider(*p))
			p++;

		/* p should now be at the end of the string if fully matched */
		if (*p)
			matching = 0;

		if (matching && (thisMatchLength > longestMatch)) {
			/* Matched prefix */
			*restOfPath = (YCHAR *) leftOver;
			retval = dev;
			longestMatch = thisMatchLength;
		}

	}
	return retval;
}

static int yaffsfs_CheckPath(const YCHAR *path)
{
	int n = 0;
	int divs = 0;

	while (*path && n < YAFFS_MAX_NAME_LENGTH && divs < 100) {
		if (yaffsfs_IsPathDivider(*path)) {
			n = 0;
			divs++;
		} else
			n++;
		path++;
	}

	return (*path) ? -1 : 0;
}

/* FindMountPoint only returns a dev entry if the path is a mount point */
static struct yaffs_dev *yaffsfs_FindMountPoint(const YCHAR *path)
{
	struct yaffs_dev *dev;
	YCHAR *restOfPath = NULL;

	dev = yaffsfs_FindDevice(path, &restOfPath);
	if (dev && restOfPath && *restOfPath)
		dev = NULL;
	return dev;
}

static struct yaffs_obj *yaffsfs_FindRoot(const YCHAR *path,
					  YCHAR **restOfPath)
{
	struct yaffs_dev *dev;

	dev = yaffsfs_FindDevice(path, restOfPath);
	if (dev && dev->is_mounted)
		return dev->root_dir;

	return NULL;
}

static struct yaffs_obj *yaffsfs_FollowLink(struct yaffs_obj *obj,
					    int symDepth, int *loop)
{

	if (obj)
		obj = yaffs_get_equivalent_obj(obj);

	while (obj && obj->variant_type == YAFFS_OBJECT_TYPE_SYMLINK) {
		YCHAR *alias = obj->variant.symlink_variant.alias;

		if (yaffsfs_IsPathDivider(*alias))
			/* Starts with a /, need to scan from root up */
			obj = yaffsfs_FindObject(NULL, alias, symDepth++,
						 1, NULL, NULL, loop);
		else
			/*
			 * Relative to here so use the parent of the
			 * symlink as a start
			 */
			obj = yaffsfs_FindObject(obj->parent, alias, symDepth++,
						 1, NULL, NULL, loop);
	}
	return obj;
}

/*
 * yaffsfs_FindDirectory
 * Parse a path to determine the directory and the name within the directory.
 *
 * eg. "/data/xx/ff" --> puts name="ff" and returns the directory "/data/xx"
 */
static struct yaffs_obj *yaffsfs_DoFindDirectory(struct yaffs_obj *startDir,
						 const YCHAR *path,
						 YCHAR **name, int symDepth,
						 int *notDir, int *loop)
{
	struct yaffs_obj *dir;
	YCHAR *restOfPath;
	YCHAR str[YAFFS_MAX_NAME_LENGTH + 1];
	int i;

	if (symDepth > YAFFSFS_MAX_SYMLINK_DEREFERENCES) {
		if (loop)
			*loop = 1;
		return NULL;
	}

	if (startDir) {
		dir = startDir;
		restOfPath = (YCHAR *) path;
	} else
		dir = yaffsfs_FindRoot(path, &restOfPath);

	while (dir) {
		/*
		 * parse off /.
		 * curve ball: also throw away surplus '/'
		 * eg. "/ram/x////ff" gets treated the same as "/ram/x/ff"
		 */
		while (yaffsfs_IsPathDivider(*restOfPath))
			restOfPath++;	/* get rid of '/' */

		*name = restOfPath;
		i = 0;

		while (*restOfPath && !yaffsfs_IsPathDivider(*restOfPath)) {
			if (i < YAFFS_MAX_NAME_LENGTH) {
				str[i] = *restOfPath;
				str[i + 1] = '\0';
				i++;
			}
			restOfPath++;
		}

		if (!*restOfPath)
			/* got to the end of the string */
			return dir;
		else {
			if (yaffs_strcmp(str, _Y(".")) == 0) {
				/* Do nothing */
			} else if (yaffs_strcmp(str, _Y("..")) == 0) {
				dir = dir->parent;
			} else {
				dir = yaffs_find_by_name(dir, str);

				dir = yaffsfs_FollowLink(dir, symDepth, loop);

				if (dir && dir->variant_type !=
				    YAFFS_OBJECT_TYPE_DIRECTORY) {
					if (notDir)
						*notDir = 1;
					dir = NULL;
				}

			}
		}
	}
	/* directory did not exist. */
	return NULL;
}

static struct yaffs_obj *yaffsfs_FindDirectory(struct yaffs_obj *relDir,
					       const YCHAR *path,
					       YCHAR **name,
					       int symDepth,
					       int *notDir, int *loop)
{
	return yaffsfs_DoFindDirectory(relDir, path, name, symDepth, notDir,
						loop);
}

/*
 * yaffsfs_FindObject turns a path for an existing object into the object
 */
static struct yaffs_obj *yaffsfs_FindObject(struct yaffs_obj *relDir,
					    const YCHAR *path, int symDepth,
					    int getEquiv,
					    struct yaffs_obj **dirOut,
					    int *notDir, int *loop)
{
	struct yaffs_obj *dir;
	struct yaffs_obj *obj;
	YCHAR *name;

	dir =
	    yaffsfs_FindDirectory(relDir, path, &name, symDepth, notDir, loop);

	if (dirOut)
		*dirOut = dir;

	if (dir && *name)
		obj = yaffs_find_by_name(dir, name);
	else
		obj = dir;

	if (getEquiv)
		obj = yaffs_get_equivalent_obj(obj);

	return obj;
}

/*************************************************************************
 *	Start of yaffsfs visible functions.
 *************************************************************************/

int yaffs_dup(int handle)
{
	int newHandleNumber = -1;
	struct yaffsfs_FileDes *existingFD = NULL;
	struct yaffsfs_Handle *existingHandle = NULL;
	struct yaffsfs_Handle *newHandle = NULL;

	yaffsfs_Lock();
	existingHandle = yaffsfs_HandleToPointer(handle);
	existingFD = yaffsfs_HandleToFileDes(handle);
	if (existingFD)
		newHandleNumber = yaffsfs_NewHandle(&newHandle);
	if (newHandle) {
		newHandle->fdId = existingHandle->fdId;
		existingFD->handleCount++;
	}

	yaffsfs_Unlock();

	if (!existingFD)
		yaffsfs_SetError(-EBADF);
	else if (!newHandle)
		yaffsfs_SetError(-ENOMEM);

	return newHandleNumber;

}

static int yaffsfs_TooManyObjects(struct yaffs_dev *dev)
{
	int current_objects = dev->n_obj - dev->n_deleted_files;

	if (dev->param.max_objects && current_objects > dev->param.max_objects)
		return 1;
	else
		return 0;
}

int yaffs_open_sharing(const YCHAR *path, int oflag, int mode, int sharing)
{
	struct yaffs_obj *obj = NULL;
	struct yaffs_obj *dir = NULL;
	YCHAR *name;
	int handle = -1;
	struct yaffsfs_FileDes *fd = NULL;
	int openDenied = 0;
	int symDepth = 0;
	int errorReported = 0;
	int rwflags = oflag & (O_RDWR | O_RDONLY | O_WRONLY);
	u8 shareRead = (sharing & YAFFS_SHARE_READ) ? 1 : 0;
	u8 shareWrite = (sharing & YAFFS_SHARE_WRITE) ? 1 : 0;
	u8 sharedReadAllowed;
	u8 sharedWriteAllowed;
	u8 alreadyReading;
	u8 alreadyWriting;
	u8 readRequested;
	u8 writeRequested;
	int notDir = 0;
	int loop = 0;

	if (!path) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	/* O_EXCL only has meaning if O_CREAT is specified */
	if (!(oflag & O_CREAT))
		oflag &= ~(O_EXCL);

	/* O_TRUNC has no meaning if (O_CREAT | O_EXCL) is specified */
	if ((oflag & O_CREAT) & (oflag & O_EXCL))
		oflag &= ~(O_TRUNC);

	/* Todo: Are there any more flag combos to sanitise ? */

	/* Figure out if reading or writing is requested */

	readRequested = (rwflags == O_RDWR || rwflags == O_RDONLY) ? 1 : 0;
	writeRequested = (rwflags == O_RDWR || rwflags == O_WRONLY) ? 1 : 0;

	yaffsfs_Lock();

	handle = yaffsfs_NewHandleAndFileDes();

	if (handle < 0) {
		yaffsfs_SetError(-ENFILE);
		errorReported = 1;
	} else {

		fd = yaffsfs_HandleToFileDes(handle);

		/* try to find the exisiting object */
		obj = yaffsfs_FindObject(NULL, path, 0, 1, NULL, NULL, NULL);

		obj = yaffsfs_FollowLink(obj, symDepth++, &loop);

		if (obj &&
		    obj->variant_type != YAFFS_OBJECT_TYPE_FILE &&
		    obj->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
			obj = NULL;

		if (obj) {

			/* The file already exists or it might be a directory */

			/* A directory can't be opened as a file */
			if (obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) {
				openDenied = 1;
				yaffsfs_SetError(-EISDIR);
				errorReported = 1;
			}

			/* Open should fail if O_CREAT and O_EXCL are specified
			 * for a file that exists.
			 */
			if (!errorReported &&
			    (oflag & O_EXCL) && (oflag & O_CREAT)) {
				openDenied = 1;
				yaffsfs_SetError(-EEXIST);
				errorReported = 1;
			}

			/* Check file permissions */
			if (readRequested && !(obj->yst_mode & S_IREAD))
				openDenied = 1;

			if (writeRequested && !(obj->yst_mode & S_IWRITE))
				openDenied = 1;

			if (!errorReported && writeRequested &&
			    obj->my_dev->read_only) {
				openDenied = 1;
				yaffsfs_SetError(-EROFS);
				errorReported = 1;
			}

			if (openDenied && !errorReported) {
				yaffsfs_SetError(-EACCES);
				errorReported = 1;
			}

			/* Check sharing of an existing object. */
			if (!openDenied) {
				struct yaffsfs_FileDes *fdx;
				int i;

				sharedReadAllowed = 1;
				sharedWriteAllowed = 1;
				alreadyReading = 0;
				alreadyWriting = 0;
				for (i = 0; i < YAFFSFS_N_HANDLES; i++) {
					fdx = &yaffsfs_fd[i];
					if (fdx->handleCount > 0 &&
					    fdx->inodeId >= 0 &&
					    yaffsfs_inode[fdx->inodeId].iObj
					    == obj) {
						if (!fdx->shareRead)
							sharedReadAllowed = 0;
						if (!fdx->shareWrite)
							sharedWriteAllowed = 0;
						if (fdx->reading)
							alreadyReading = 1;
						if (fdx->writing)
							alreadyWriting = 1;
					}
				}

				if ((!sharedReadAllowed && readRequested) ||
				    (!shareRead && alreadyReading) ||
				    (!sharedWriteAllowed && writeRequested) ||
				    (!shareWrite && alreadyWriting)) {
					openDenied = 1;
					yaffsfs_SetError(-EBUSY);
					errorReported = 1;
				}
			}

		}

		/* If we could not open an existing object, then let's see if
		 * the directory exists. If not, error.
		 */
		if (!obj && !errorReported) {
			dir = yaffsfs_FindDirectory(NULL, path, &name, 0,
						    &notDir, &loop);
			if (!dir && notDir) {
				yaffsfs_SetError(-ENOTDIR);
				errorReported = 1;
			} else if (loop) {
				yaffsfs_SetError(-ELOOP);
				errorReported = 1;
			} else if (!dir) {
				yaffsfs_SetError(-ENOENT);
				errorReported = 1;
			}
		}

		if (!obj && dir && !errorReported && (oflag & O_CREAT)) {
			/* Let's see if we can create this file */
			if (dir->my_dev->read_only) {
				yaffsfs_SetError(-EROFS);
				errorReported = 1;
			} else if (yaffsfs_TooManyObjects(dir->my_dev)) {
				yaffsfs_SetError(-ENFILE);
				errorReported = 1;
			} else
				obj = yaffs_create_file(dir, name, mode, 0, 0);

			if (!obj && !errorReported) {
				yaffsfs_SetError(-ENOSPC);
				errorReported = 1;
			}
		}

		if (!obj && dir && !errorReported && !(oflag & O_CREAT)) {
			yaffsfs_SetError(-ENOENT);
			errorReported = 1;
		}

		if (obj && !openDenied) {
			int inodeId = yaffsfs_GetInodeIdForObject(obj);

			if (inodeId < 0) {
				/*
				 * Todo: Fix any problem if inodes run out,
				 * That can't happen if the number of inode
				 * items >= number of handles.
				 */
			}

			fd->inodeId = inodeId;
			fd->reading = readRequested;
			fd->writing = writeRequested;
			fd->append = (oflag & O_APPEND) ? 1 : 0;
			fd->position = 0;
			fd->shareRead = shareRead;
			fd->shareWrite = shareWrite;

			/* Hook inode to object */
			obj->my_inode = (void *)&yaffsfs_inode[inodeId];

			if ((oflag & O_TRUNC) && fd->writing)
				yaffs_resize_file(obj, 0);
		} else {
			yaffsfs_PutHandle(handle);
			if (!errorReported)
				yaffsfs_SetError(0);	/* Problem */
			handle = -1;
		}
	}

	yaffsfs_Unlock();

	return handle;
}

int yaffs_open(const YCHAR *path, int oflag, int mode)
{
	return yaffs_open_sharing(path, oflag, mode,
				  YAFFS_SHARE_READ | YAFFS_SHARE_WRITE);
}

int yaffs_Dofsync(int handle, int datasync)
{
	int retVal = -1;
	struct yaffs_obj *obj;

	yaffsfs_Lock();

	obj = yaffsfs_HandleToObject(handle);

	if (!obj)
		yaffsfs_SetError(-EBADF);
	else if (obj->my_dev->read_only)
		yaffsfs_SetError(-EROFS);
	else {
		yaffs_flush_file(obj, 1, datasync);
		retVal = 0;
	}

	yaffsfs_Unlock();

	return retVal;
}

int yaffs_fsync(int handle)
{
	return yaffs_Dofsync(handle, 0);
}

int yaffs_flush(int handle)
{
	return yaffs_fsync(handle);
}

int yaffs_fdatasync(int handle)
{
	return yaffs_Dofsync(handle, 1);
}

int yaffs_close(int handle)
{
	struct yaffsfs_Handle *h = NULL;
	struct yaffs_obj *obj = NULL;
	int retVal = -1;

	yaffsfs_Lock();

	h = yaffsfs_HandleToPointer(handle);
	obj = yaffsfs_HandleToObject(handle);

	if (!h || !obj)
		yaffsfs_SetError(-EBADF);
	else {
		/* clean up */
		yaffs_flush_file(obj, 1, 0);
		yaffsfs_PutHandle(handle);
		retVal = 0;
	}

	yaffsfs_Unlock();

	return retVal;
}

int yaffsfs_do_read(int handle, void *vbuf, unsigned int nbyte,
		    int isPread, loff_t offset)
{
	struct yaffsfs_FileDes *fd = NULL;
	struct yaffs_obj *obj = NULL;
	loff_t pos = 0;
	loff_t startPos = 0;
	loff_t endPos = 0;
	int nRead = 0;
	int nToRead = 0;
	int totalRead = 0;
	loff_t maxRead;
	u8 *buf = (u8 *) vbuf;

	if (!vbuf) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	yaffsfs_Lock();
	fd = yaffsfs_HandleToFileDes(handle);
	obj = yaffsfs_HandleToObject(handle);

	if (!fd || !obj) {
		/* bad handle */
		yaffsfs_SetError(-EBADF);
		totalRead = -1;
	} else if (!fd->reading) {
		/* Not a reading handle */
		yaffsfs_SetError(-EINVAL);
		totalRead = -1;
	} else if (nbyte > YAFFS_MAX_FILE_SIZE) {
		yaffsfs_SetError(-EINVAL);
		totalRead = -1;
	} else {
		if (isPread)
			startPos = offset;
		else
			startPos = fd->position;

		pos = startPos;

		if (yaffs_get_obj_length(obj) > pos)
			maxRead = yaffs_get_obj_length(obj) - pos;
		else
			maxRead = 0;

		if (nbyte > maxRead)
			nbyte = maxRead;

		yaffsfs_GetHandle(handle);

		endPos = pos + nbyte;

		if (pos < 0 || pos > YAFFS_MAX_FILE_SIZE ||
		    nbyte > YAFFS_MAX_FILE_SIZE ||
		    endPos < 0 || endPos > YAFFS_MAX_FILE_SIZE) {
			totalRead = -1;
			nbyte = 0;
		}

		while (nbyte > 0) {
			nToRead = YAFFSFS_RW_SIZE -
			    (pos & (YAFFSFS_RW_SIZE - 1));
			if (nToRead > nbyte)
				nToRead = nbyte;

			/* Tricky bit...
			 * Need to reverify object in case the device was
			 * unmounted in another thread.
			 */
			obj = yaffsfs_HandleToObject(handle);
			if (!obj)
				nRead = 0;
			else
				nRead = yaffs_file_rd(obj, buf, pos, nToRead);

			if (nRead > 0) {
				totalRead += nRead;
				pos += nRead;
				buf += nRead;
			}

			if (nRead == nToRead)
				nbyte -= nRead;
			else
				nbyte = 0;	/* no more to read */

			if (nbyte > 0) {
				yaffsfs_Unlock();
				yaffsfs_Lock();
			}

		}

		yaffsfs_PutHandle(handle);

		if (!isPread) {
			if (totalRead >= 0)
				fd->position = startPos + totalRead;
			else
				yaffsfs_SetError(-EINVAL);
		}

	}

	yaffsfs_Unlock();

	return (totalRead >= 0) ? totalRead : -1;

}

int yaffs_read(int handle, void *buf, unsigned int nbyte)
{
	return yaffsfs_do_read(handle, buf, nbyte, 0, 0);
}

int yaffs_pread(int handle, void *buf, unsigned int nbyte, loff_t offset)
{
	return yaffsfs_do_read(handle, buf, nbyte, 1, offset);
}

int yaffsfs_do_write(int handle, const void *vbuf, unsigned int nbyte,
		     int isPwrite, loff_t offset)
{
	struct yaffsfs_FileDes *fd = NULL;
	struct yaffs_obj *obj = NULL;
	loff_t pos = 0;
	loff_t startPos = 0;
	loff_t endPos;
	int nWritten = 0;
	int totalWritten = 0;
	int write_trhrough = 0;
	int nToWrite = 0;
	const u8 *buf = (const u8 *)vbuf;

	if (!vbuf) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	yaffsfs_Lock();
	fd = yaffsfs_HandleToFileDes(handle);
	obj = yaffsfs_HandleToObject(handle);

	if (!fd || !obj) {
		/* bad handle */
		yaffsfs_SetError(-EBADF);
		totalWritten = -1;
	} else if (!fd->writing) {
		yaffsfs_SetError(-EINVAL);
		totalWritten = -1;
	} else if (obj->my_dev->read_only) {
		yaffsfs_SetError(-EROFS);
		totalWritten = -1;
	} else {
		if (fd->append)
			startPos = yaffs_get_obj_length(obj);
		else if (isPwrite)
			startPos = offset;
		else
			startPos = fd->position;

		yaffsfs_GetHandle(handle);
		pos = startPos;
		endPos = pos + nbyte;

		if (pos < 0 || pos > YAFFS_MAX_FILE_SIZE ||
		    nbyte > YAFFS_MAX_FILE_SIZE ||
		    endPos < 0 || endPos > YAFFS_MAX_FILE_SIZE) {
			totalWritten = -1;
			nbyte = 0;
		}

		while (nbyte > 0) {

			nToWrite = YAFFSFS_RW_SIZE -
			    (pos & (YAFFSFS_RW_SIZE - 1));
			if (nToWrite > nbyte)
				nToWrite = nbyte;

			/* Tricky bit...
			 * Need to reverify object in case the device was
			 * remounted or unmounted in another thread.
			 */
			obj = yaffsfs_HandleToObject(handle);
			if (!obj || obj->my_dev->read_only)
				nWritten = 0;
			else
				nWritten =
				    yaffs_wr_file(obj, buf, pos, nToWrite,
						  write_trhrough);
			if (nWritten > 0) {
				totalWritten += nWritten;
				pos += nWritten;
				buf += nWritten;
			}

			if (nWritten == nToWrite)
				nbyte -= nToWrite;
			else
				nbyte = 0;

			if (nWritten < 1 && totalWritten < 1) {
				yaffsfs_SetError(-ENOSPC);
				totalWritten = -1;
			}

			if (nbyte > 0) {
				yaffsfs_Unlock();
				yaffsfs_Lock();
			}
		}

		yaffsfs_PutHandle(handle);

		if (!isPwrite) {
			if (totalWritten > 0)
				fd->position = startPos + totalWritten;
			else
				yaffsfs_SetError(-EINVAL);
		}
	}

	yaffsfs_Unlock();

	return (totalWritten >= 0) ? totalWritten : -1;
}

int yaffs_write(int fd, const void *buf, unsigned int nbyte)
{
	return yaffsfs_do_write(fd, buf, nbyte, 0, 0);
}

int yaffs_pwrite(int fd, const void *buf, unsigned int nbyte, loff_t offset)
{
	return yaffsfs_do_write(fd, buf, nbyte, 1, offset);
}

int yaffs_truncate(const YCHAR *path, loff_t new_size)
{
	struct yaffs_obj *obj = NULL;
	struct yaffs_obj *dir = NULL;
	int result = YAFFS_FAIL;
	int notDir = 0;
	int loop = 0;

	if (!path) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();

	obj = yaffsfs_FindObject(NULL, path, 0, 1, &dir, &notDir, &loop);
	obj = yaffsfs_FollowLink(obj, 0, &loop);

	if (!dir && notDir)
		yaffsfs_SetError(-ENOTDIR);
	else if (loop)
		yaffsfs_SetError(-ELOOP);
	else if (!dir || !obj)
		yaffsfs_SetError(-ENOENT);
	else if (obj->my_dev->read_only)
		yaffsfs_SetError(-EROFS);
	else if (obj->variant_type != YAFFS_OBJECT_TYPE_FILE)
		yaffsfs_SetError(-EISDIR);
	else if (obj->my_dev->read_only)
		yaffsfs_SetError(-EROFS);
	else if (new_size < 0 || new_size > YAFFS_MAX_FILE_SIZE)
		yaffsfs_SetError(-EINVAL);
	else
		result = yaffs_resize_file(obj, new_size);

	yaffsfs_Unlock();

	return (result) ? 0 : -1;
}

int yaffs_ftruncate(int handle, loff_t new_size)
{
	struct yaffsfs_FileDes *fd = NULL;
	struct yaffs_obj *obj = NULL;
	int result = 0;

	yaffsfs_Lock();
	fd = yaffsfs_HandleToFileDes(handle);
	obj = yaffsfs_HandleToObject(handle);

	if (!fd || !obj)
		/* bad handle */
		yaffsfs_SetError(-EBADF);
	else if (!fd->writing)
		yaffsfs_SetError(-EINVAL);
	else if (obj->my_dev->read_only)
		yaffsfs_SetError(-EROFS);
	else if (new_size < 0 || new_size > YAFFS_MAX_FILE_SIZE)
		yaffsfs_SetError(-EINVAL);
	else
		/* resize the file */
		result = yaffs_resize_file(obj, new_size);
	yaffsfs_Unlock();

	return (result) ? 0 : -1;

}

loff_t yaffs_lseek(int handle, loff_t offset, int whence)
{
	struct yaffsfs_FileDes *fd = NULL;
	struct yaffs_obj *obj = NULL;
	loff_t pos = -1;
	loff_t fSize = -1;

	yaffsfs_Lock();
	fd = yaffsfs_HandleToFileDes(handle);
	obj = yaffsfs_HandleToObject(handle);

	if (!fd || !obj)
		yaffsfs_SetError(-EBADF);
	else if (offset > YAFFS_MAX_FILE_SIZE)
		yaffsfs_SetError(-EINVAL);
	else {
		if (whence == SEEK_SET) {
			if (offset >= 0)
				pos = offset;
		} else if (whence == SEEK_CUR) {
			if ((fd->position + offset) >= 0)
				pos = (fd->position + offset);
		} else if (whence == SEEK_END) {
			fSize = yaffs_get_obj_length(obj);
			if (fSize >= 0 && (fSize + offset) >= 0)
				pos = fSize + offset;
		}

		if (pos >= 0 && pos <= YAFFS_MAX_FILE_SIZE)
			fd->position = pos;
		else {
			yaffsfs_SetError(-EINVAL);
			pos = -1;
		}
	}

	yaffsfs_Unlock();

	return pos;
}

int yaffsfs_DoUnlink(const YCHAR *path, int isDirectory)
{
	struct yaffs_obj *dir = NULL;
	struct yaffs_obj *obj = NULL;
	YCHAR *name;
	int result = YAFFS_FAIL;
	int notDir = 0;
	int loop = 0;

	if (!path) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();

	obj = yaffsfs_FindObject(NULL, path, 0, 0, NULL, NULL, NULL);
	dir = yaffsfs_FindDirectory(NULL, path, &name, 0, &notDir, &loop);

	if (!dir && notDir)
		yaffsfs_SetError(-ENOTDIR);
	else if (loop)
		yaffsfs_SetError(-ELOOP);
	else if (!dir)
		yaffsfs_SetError(-ENOENT);
	else if (yaffs_strncmp(name, _Y("."), 2) == 0)
		yaffsfs_SetError(-EINVAL);
	else if (!obj)
		yaffsfs_SetError(-ENOENT);
	else if (obj->my_dev->read_only)
		yaffsfs_SetError(-EROFS);
	else if (!isDirectory &&
		 obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY)
		yaffsfs_SetError(-EISDIR);
	else if (isDirectory &&
		 obj->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
		yaffsfs_SetError(-ENOTDIR);
	else if (isDirectory && obj == obj->my_dev->root_dir)
		yaffsfs_SetError(-EBUSY);	/* Can't rmdir a root */
	else {
		result = yaffs_unlinker(dir, name);

		if (result == YAFFS_FAIL && isDirectory)
			yaffsfs_SetError(-ENOTEMPTY);
	}

	yaffsfs_Unlock();

	return (result == YAFFS_FAIL) ? -1 : 0;
}

int yaffs_unlink(const YCHAR *path)
{
	return yaffsfs_DoUnlink(path, 0);
}

int yaffs_rename(const YCHAR *oldPath, const YCHAR *newPath)
{
	struct yaffs_obj *olddir = NULL;
	struct yaffs_obj *newdir = NULL;
	struct yaffs_obj *obj = NULL;
	struct yaffs_obj *newobj = NULL;
	YCHAR *oldname;
	YCHAR *newname;
	int result = YAFFS_FAIL;
	int rename_allowed = 1;
	int notOldDir = 0;
	int notNewDir = 0;
	int oldLoop = 0;
	int newLoop = 0;

	YCHAR *alt_newpath = NULL;

	if (!oldPath || !newPath) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(oldPath) < 0 || yaffsfs_CheckPath(newPath) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	if (yaffsfs_alt_dir_path(newPath, &alt_newpath) < 0) {
		yaffsfs_SetError(-ENOMEM);
		return -1;
	}
	if (alt_newpath)
		newPath = alt_newpath;

	yaffsfs_Lock();

	olddir = yaffsfs_FindDirectory(NULL, oldPath, &oldname, 0,
				       &notOldDir, &oldLoop);
	newdir = yaffsfs_FindDirectory(NULL, newPath, &newname, 0,
				       &notNewDir, &newLoop);
	obj = yaffsfs_FindObject(NULL, oldPath, 0, 0, NULL, NULL, NULL);
	newobj = yaffsfs_FindObject(NULL, newPath, 0, 0, NULL, NULL, NULL);

	/* If the object being renamed is a directory and the
	 * path ended with a "/" then the olddir == obj.
	 * We pass through NULL for the old name to tell the lower layers
	 * to use olddir as the object.
	 */

	if (olddir == obj)
		oldname = NULL;

	if ((!olddir && notOldDir) || (!newdir && notNewDir)) {
		yaffsfs_SetError(-ENOTDIR);
		rename_allowed = 0;
	} else if (oldLoop || newLoop) {
		yaffsfs_SetError(-ELOOP);
		rename_allowed = 0;
	} else if (olddir && oldname &&
			yaffs_strncmp(oldname, _Y("."), 2) == 0) {
		yaffsfs_SetError(-EINVAL);
		rename_allowed = 0;
	} else if (!olddir || !newdir || !obj) {
		yaffsfs_SetError(-ENOENT);
		rename_allowed = 0;
	} else if (obj->my_dev->read_only) {
		yaffsfs_SetError(-EROFS);
		rename_allowed = 0;
	} else if (yaffs_is_non_empty_dir(newobj)) {
		yaffsfs_SetError(-ENOTEMPTY);
		rename_allowed = 0;
	} else if (olddir->my_dev != newdir->my_dev) {
		/* Rename must be on same device */
		yaffsfs_SetError(-EXDEV);
		rename_allowed = 0;
	} else if (obj && obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) {
		/*
		 * It is a directory, check that it is not being renamed to
		 * being its own decendent.
		 * Do this by tracing from the new directory back to the root,
		 * checking for obj
		 */

		struct yaffs_obj *xx = newdir;

		while (rename_allowed && xx) {
			if (xx == obj)
				rename_allowed = 0;
			xx = xx->parent;
		}
		if (!rename_allowed)
			yaffsfs_SetError(-EINVAL);
	}

	if (rename_allowed)
		result = yaffs_rename_obj(olddir, oldname, newdir, newname);

	yaffsfs_Unlock();

	kfree(alt_newpath);

	return (result == YAFFS_FAIL) ? -1 : 0;
}

static int yaffsfs_DoStat(struct yaffs_obj *obj, struct yaffs_stat *buf)
{
	int retVal = -1;

	obj = yaffs_get_equivalent_obj(obj);

	if (obj && buf) {
		buf->st_dev = (int)obj->my_dev->os_context;
		buf->st_ino = obj->obj_id;
		buf->st_mode = obj->yst_mode & ~S_IFMT;

		if (obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY)
			buf->st_mode |= S_IFDIR;
		else if (obj->variant_type == YAFFS_OBJECT_TYPE_SYMLINK)
			buf->st_mode |= S_IFLNK;
		else if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE)
			buf->st_mode |= S_IFREG;

		buf->st_nlink = yaffs_get_obj_link_count(obj);
		buf->st_uid = 0;
		buf->st_gid = 0;
		buf->st_rdev = obj->yst_rdev;
		buf->st_size = yaffs_get_obj_length(obj);
		buf->st_blksize = obj->my_dev->data_bytes_per_chunk;
		buf->st_blocks = lldiv(buf->st_size + buf->st_blksize - 1,
		    buf->st_blksize);
#if CONFIG_YAFFS_WINCE
		buf->yst_wince_atime[0] = obj->win_atime[0];
		buf->yst_wince_atime[1] = obj->win_atime[1];
		buf->yst_wince_ctime[0] = obj->win_ctime[0];
		buf->yst_wince_ctime[1] = obj->win_ctime[1];
		buf->yst_wince_mtime[0] = obj->win_mtime[0];
		buf->yst_wince_mtime[1] = obj->win_mtime[1];
#else
		buf->yst_atime = obj->yst_atime;
		buf->yst_ctime = obj->yst_ctime;
		buf->yst_mtime = obj->yst_mtime;
#endif
		retVal = 0;
	}
	return retVal;
}

static int yaffsfs_DoStatOrLStat(const YCHAR *path,
				 struct yaffs_stat *buf, int doLStat)
{
	struct yaffs_obj *obj = NULL;
	struct yaffs_obj *dir = NULL;
	int retVal = -1;
	int notDir = 0;
	int loop = 0;

	if (!path || !buf) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();

	obj = yaffsfs_FindObject(NULL, path, 0, 1, &dir, &notDir, &loop);

	if (!doLStat && obj)
		obj = yaffsfs_FollowLink(obj, 0, &loop);

	if (!dir && notDir)
		yaffsfs_SetError(-ENOTDIR);
	else if (loop)
		yaffsfs_SetError(-ELOOP);
	else if (!dir || !obj)
		yaffsfs_SetError(-ENOENT);
	else
		retVal = yaffsfs_DoStat(obj, buf);

	yaffsfs_Unlock();

	return retVal;

}

int yaffs_stat(const YCHAR *path, struct yaffs_stat *buf)
{
	return yaffsfs_DoStatOrLStat(path, buf, 0);
}

int yaffs_lstat(const YCHAR *path, struct yaffs_stat *buf)
{
	return yaffsfs_DoStatOrLStat(path, buf, 1);
}

int yaffs_fstat(int fd, struct yaffs_stat *buf)
{
	struct yaffs_obj *obj;

	int retVal = -1;

	if (!buf) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	yaffsfs_Lock();
	obj = yaffsfs_HandleToObject(fd);

	if (obj)
		retVal = yaffsfs_DoStat(obj, buf);
	else
		/* bad handle */
		yaffsfs_SetError(-EBADF);

	yaffsfs_Unlock();

	return retVal;
}

static int yaffsfs_DoUtime(struct yaffs_obj *obj,
			   const struct yaffs_utimbuf *buf)
{
	int retVal = -1;
	int result;

	struct yaffs_utimbuf local;

	obj = yaffs_get_equivalent_obj(obj);

	if (obj && obj->my_dev->read_only) {
		yaffsfs_SetError(-EROFS);
		return -1;
	}

	if (!buf) {
		local.actime = Y_CURRENT_TIME;
		local.modtime = local.actime;
		buf = &local;
	}

	if (obj) {
		obj->yst_atime = buf->actime;
		obj->yst_mtime = buf->modtime;
		obj->dirty = 1;
		result = yaffs_flush_file(obj, 0, 0);
		retVal = result == YAFFS_OK ? 0 : -1;
	}

	return retVal;
}

int yaffs_utime(const YCHAR *path, const struct yaffs_utimbuf *buf)
{
	struct yaffs_obj *obj = NULL;
	struct yaffs_obj *dir = NULL;
	int retVal = -1;
	int notDir = 0;
	int loop = 0;

	if (!path) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();

	obj = yaffsfs_FindObject(NULL, path, 0, 1, &dir, &notDir, &loop);

	if (!dir && notDir)
		yaffsfs_SetError(-ENOTDIR);
	else if (loop)
		yaffsfs_SetError(-ELOOP);
	else if (!dir || !obj)
		yaffsfs_SetError(-ENOENT);
	else
		retVal = yaffsfs_DoUtime(obj, buf);

	yaffsfs_Unlock();

	return retVal;

}

int yaffs_futime(int fd, const struct yaffs_utimbuf *buf)
{
	struct yaffs_obj *obj;

	int retVal = -1;

	yaffsfs_Lock();
	obj = yaffsfs_HandleToObject(fd);

	if (obj)
		retVal = yaffsfs_DoUtime(obj, buf);
	else
		/* bad handle */
		yaffsfs_SetError(-EBADF);

	yaffsfs_Unlock();

	return retVal;
}

#ifndef CONFIG_YAFFS_WINCE
/* xattrib functions */

static int yaffs_do_setxattr(const YCHAR *path, const char *name,
			     const void *data, int size, int flags, int follow)
{
	struct yaffs_obj *obj;
	struct yaffs_obj *dir;
	int notDir = 0;
	int loop = 0;

	int retVal = -1;

	if (!path || !name || !data) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();

	obj = yaffsfs_FindObject(NULL, path, 0, 1, &dir, &notDir, &loop);

	if (follow)
		obj = yaffsfs_FollowLink(obj, 0, &loop);

	if (!dir && notDir)
		yaffsfs_SetError(-ENOTDIR);
	else if (loop)
		yaffsfs_SetError(-ELOOP);
	else if (!dir || !obj)
		yaffsfs_SetError(-ENOENT);
	else {
		retVal = yaffs_set_xattrib(obj, name, data, size, flags);
		if (retVal < 0) {
			yaffsfs_SetError(retVal);
			retVal = -1;
		}
	}

	yaffsfs_Unlock();

	return retVal;

}

int yaffs_setxattr(const YCHAR *path, const char *name,
		   const void *data, int size, int flags)
{
	return yaffs_do_setxattr(path, name, data, size, flags, 1);
}

int yaffs_lsetxattr(const YCHAR *path, const char *name,
		    const void *data, int size, int flags)
{
	return yaffs_do_setxattr(path, name, data, size, flags, 0);
}

int yaffs_fsetxattr(int fd, const char *name,
		    const void *data, int size, int flags)
{
	struct yaffs_obj *obj;

	int retVal = -1;

	if (!name || !data) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	yaffsfs_Lock();
	obj = yaffsfs_HandleToObject(fd);

	if (!obj)
		yaffsfs_SetError(-EBADF);
	else {
		retVal = yaffs_set_xattrib(obj, name, data, size, flags);
		if (retVal < 0) {
			yaffsfs_SetError(retVal);
			retVal = -1;
		}
	}

	yaffsfs_Unlock();

	return retVal;
}

static int yaffs_do_getxattr(const YCHAR *path, const char *name,
			     void *data, int size, int follow)
{
	struct yaffs_obj *obj;
	struct yaffs_obj *dir;
	int retVal = -1;
	int notDir = 0;
	int loop = 0;

	if (!path || !name || !data) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();

	obj = yaffsfs_FindObject(NULL, path, 0, 1, &dir, &notDir, &loop);

	if (follow)
		obj = yaffsfs_FollowLink(obj, 0, &loop);

	if (!dir && notDir)
		yaffsfs_SetError(-ENOTDIR);
	else if (loop)
		yaffsfs_SetError(-ELOOP);
	else if (!dir || !obj)
		yaffsfs_SetError(-ENOENT);
	else {
		retVal = yaffs_get_xattrib(obj, name, data, size);
		if (retVal < 0) {
			yaffsfs_SetError(retVal);
			retVal = -1;
		}
	}
	yaffsfs_Unlock();

	return retVal;

}

int yaffs_getxattr(const YCHAR *path, const char *name, void *data, int size)
{
	return yaffs_do_getxattr(path, name, data, size, 1);
}

int yaffs_lgetxattr(const YCHAR *path, const char *name, void *data, int size)
{
	return yaffs_do_getxattr(path, name, data, size, 0);
}

int yaffs_fgetxattr(int fd, const char *name, void *data, int size)
{
	struct yaffs_obj *obj;

	int retVal = -1;

	if (!name || !data) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	yaffsfs_Lock();
	obj = yaffsfs_HandleToObject(fd);

	if (obj) {
		retVal = yaffs_get_xattrib(obj, name, data, size);
		if (retVal < 0) {
			yaffsfs_SetError(retVal);
			retVal = -1;
		}
	} else
		/* bad handle */
		yaffsfs_SetError(-EBADF);

	yaffsfs_Unlock();

	return retVal;
}

static int yaffs_do_listxattr(const YCHAR *path, char *data,
			      int size, int follow)
{
	struct yaffs_obj *obj = NULL;
	struct yaffs_obj *dir = NULL;
	int retVal = -1;
	int notDir = 0;
	int loop = 0;

	if (!path || !data) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();

	obj = yaffsfs_FindObject(NULL, path, 0, 1, &dir, &notDir, &loop);

	if (follow)
		obj = yaffsfs_FollowLink(obj, 0, &loop);

	if (!dir && notDir)
		yaffsfs_SetError(-ENOTDIR);
	else if (loop)
		yaffsfs_SetError(-ELOOP);
	else if (!dir || !obj)
		yaffsfs_SetError(-ENOENT);
	else {
		retVal = yaffs_list_xattrib(obj, data, size);
		if (retVal < 0) {
			yaffsfs_SetError(retVal);
			retVal = -1;
		}
	}

	yaffsfs_Unlock();

	return retVal;

}

int yaffs_listxattr(const YCHAR *path, char *data, int size)
{
	return yaffs_do_listxattr(path, data, size, 1);
}

int yaffs_llistxattr(const YCHAR *path, char *data, int size)
{
	return yaffs_do_listxattr(path, data, size, 0);
}

int yaffs_flistxattr(int fd, char *data, int size)
{
	struct yaffs_obj *obj;

	int retVal = -1;

	if (!data) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	yaffsfs_Lock();
	obj = yaffsfs_HandleToObject(fd);

	if (obj) {
		retVal = yaffs_list_xattrib(obj, data, size);
		if (retVal < 0) {
			yaffsfs_SetError(retVal);
			retVal = -1;
		}
	} else
		/* bad handle */
		yaffsfs_SetError(-EBADF);

	yaffsfs_Unlock();

	return retVal;
}

static int yaffs_do_removexattr(const YCHAR *path, const char *name,
				int follow)
{
	struct yaffs_obj *obj = NULL;
	struct yaffs_obj *dir = NULL;
	int notDir = 0;
	int loop = 0;
	int retVal = -1;

	if (!path || !name) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();

	obj = yaffsfs_FindObject(NULL, path, 0, 1, &dir, &notDir, &loop);

	if (follow)
		obj = yaffsfs_FollowLink(obj, 0, &loop);

	if (!dir && notDir)
		yaffsfs_SetError(-ENOTDIR);
	else if (loop)
		yaffsfs_SetError(-ELOOP);
	else if (!dir || !obj)
		yaffsfs_SetError(-ENOENT);
	else {
		retVal = yaffs_remove_xattrib(obj, name);
		if (retVal < 0) {
			yaffsfs_SetError(retVal);
			retVal = -1;
		}
	}

	yaffsfs_Unlock();

	return retVal;

}

int yaffs_removexattr(const YCHAR *path, const char *name)
{
	return yaffs_do_removexattr(path, name, 1);
}

int yaffs_lremovexattr(const YCHAR *path, const char *name)
{
	return yaffs_do_removexattr(path, name, 0);
}

int yaffs_fremovexattr(int fd, const char *name)
{
	struct yaffs_obj *obj;

	int retVal = -1;

	if (!name) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	yaffsfs_Lock();
	obj = yaffsfs_HandleToObject(fd);

	if (obj) {
		retVal = yaffs_remove_xattrib(obj, name);
		if (retVal < 0) {
			yaffsfs_SetError(retVal);
			retVal = -1;
		}
	} else
		/* bad handle */
		yaffsfs_SetError(-EBADF);

	yaffsfs_Unlock();

	return retVal;
}
#endif

#ifdef CONFIG_YAFFS_WINCE
int yaffs_get_wince_times(int fd, unsigned *wctime,
			  unsigned *watime, unsigned *wmtime)
{
	struct yaffs_obj *obj;

	int retVal = -1;

	yaffsfs_Lock();
	obj = yaffsfs_HandleToObject(fd);

	if (obj) {

		if (wctime) {
			wctime[0] = obj->win_ctime[0];
			wctime[1] = obj->win_ctime[1];
		}
		if (watime) {
			watime[0] = obj->win_atime[0];
			watime[1] = obj->win_atime[1];
		}
		if (wmtime) {
			wmtime[0] = obj->win_mtime[0];
			wmtime[1] = obj->win_mtime[1];
		}

		retVal = 0;
	} else
		/*  bad handle */
		yaffsfs_SetError(-EBADF);

	yaffsfs_Unlock();

	return retVal;
}

int yaffs_set_wince_times(int fd,
			  const unsigned *wctime,
			  const unsigned *watime, const unsigned *wmtime)
{
	struct yaffs_obj *obj;
	int result;
	int retVal = -1;

	yaffsfs_Lock();
	obj = yaffsfs_HandleToObject(fd);

	if (obj) {

		if (wctime) {
			obj->win_ctime[0] = wctime[0];
			obj->win_ctime[1] = wctime[1];
		}
		if (watime) {
			obj->win_atime[0] = watime[0];
			obj->win_atime[1] = watime[1];
		}
		if (wmtime) {
			obj->win_mtime[0] = wmtime[0];
			obj->win_mtime[1] = wmtime[1];
		}

		obj->dirty = 1;
		result = yaffs_flush_file(obj, 0, 0);
		retVal = 0;
	} else
		/* bad handle */
		yaffsfs_SetError(-EBADF);

	yaffsfs_Unlock();

	return retVal;
}

#endif

static int yaffsfs_DoChMod(struct yaffs_obj *obj, mode_t mode)
{
	int result = -1;

	if (obj)
		obj = yaffs_get_equivalent_obj(obj);

	if (obj) {
		obj->yst_mode = mode;
		obj->dirty = 1;
		result = yaffs_flush_file(obj, 0, 0);
	}

	return result == YAFFS_OK ? 0 : -1;
}

int yaffs_access(const YCHAR *path, int amode)
{
	struct yaffs_obj *obj = NULL;
	struct yaffs_obj *dir = NULL;
	int notDir = 0;
	int loop = 0;
	int retval = -1;

	if (!path) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	if (amode & ~(R_OK | W_OK | X_OK)) {
		yaffsfs_SetError(-EINVAL);
		return -1;
	}

	yaffsfs_Lock();

	obj = yaffsfs_FindObject(NULL, path, 0, 1, &dir, &notDir, &loop);
	obj = yaffsfs_FollowLink(obj, 0, &loop);

	if (!dir && notDir)
		yaffsfs_SetError(-ENOTDIR);
	else if (loop)
		yaffsfs_SetError(-ELOOP);
	else if (!dir || !obj)
		yaffsfs_SetError(-ENOENT);
	else if ((amode & W_OK) && obj->my_dev->read_only)
		yaffsfs_SetError(-EROFS);
	else {
		int access_ok = 1;

		if ((amode & R_OK) && !(obj->yst_mode & S_IREAD))
			access_ok = 0;
		if ((amode & W_OK) && !(obj->yst_mode & S_IWRITE))
			access_ok = 0;
		if ((amode & X_OK) && !(obj->yst_mode & S_IEXEC))
			access_ok = 0;

		if (!access_ok)
			yaffsfs_SetError(-EACCES);
		else
			retval = 0;
	}

	yaffsfs_Unlock();

	return retval;

}

int yaffs_chmod(const YCHAR *path, mode_t mode)
{
	struct yaffs_obj *obj = NULL;
	struct yaffs_obj *dir = NULL;
	int retVal = -1;
	int notDir = 0;
	int loop = 0;

	if (!path) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	if (mode & ~(0777)) {
		yaffsfs_SetError(-EINVAL);
		return -1;
	}

	yaffsfs_Lock();

	obj = yaffsfs_FindObject(NULL, path, 0, 1, &dir, &notDir, &loop);
	obj = yaffsfs_FollowLink(obj, 0, &loop);

	if (!dir && notDir)
		yaffsfs_SetError(-ENOTDIR);
	else if (loop)
		yaffsfs_SetError(-ELOOP);
	else if (!dir || !obj)
		yaffsfs_SetError(-ENOENT);
	else if (obj->my_dev->read_only)
		yaffsfs_SetError(-EROFS);
	else
		retVal = yaffsfs_DoChMod(obj, mode);

	yaffsfs_Unlock();

	return retVal;

}

int yaffs_fchmod(int fd, mode_t mode)
{
	struct yaffs_obj *obj;
	int retVal = -1;

	if (mode & ~(0777)) {
		yaffsfs_SetError(-EINVAL);
		return -1;
	}

	yaffsfs_Lock();
	obj = yaffsfs_HandleToObject(fd);

	if (!obj)
		yaffsfs_SetError(-EBADF);
	else if (obj->my_dev->read_only)
		yaffsfs_SetError(-EROFS);
	else
		retVal = yaffsfs_DoChMod(obj, mode);

	yaffsfs_Unlock();

	return retVal;
}

int yaffs_mkdir(const YCHAR *path, mode_t mode)
{
	struct yaffs_obj *parent = NULL;
	struct yaffs_obj *dir = NULL;
	YCHAR *name;
	YCHAR *alt_path = NULL;
	int retVal = -1;
	int notDir = 0;
	int loop = 0;

	if (!path) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	if (yaffsfs_alt_dir_path(path, &alt_path) < 0) {
		yaffsfs_SetError(-ENOMEM);
		return -1;
	}
	if (alt_path)
		path = alt_path;

	yaffsfs_Lock();
	parent = yaffsfs_FindDirectory(NULL, path, &name, 0, &notDir, &loop);
	if (!parent && notDir)
		yaffsfs_SetError(-ENOTDIR);
	else if (loop)
		yaffsfs_SetError(-ELOOP);
	else if (!parent)
		yaffsfs_SetError(-ENOENT);
	else if (yaffsfs_TooManyObjects(parent->my_dev))
		yaffsfs_SetError(-ENFILE);
	else if (yaffs_strnlen(name, 5) == 0) {
		/* Trying to make the root itself */
		yaffsfs_SetError(-EEXIST);
	} else if (parent->my_dev->read_only)
		yaffsfs_SetError(-EROFS);
	else {
		dir = yaffs_create_dir(parent, name, mode, 0, 0);
		if (dir)
			retVal = 0;
		else if (yaffs_find_by_name(parent, name))
			yaffsfs_SetError(-EEXIST);	/* name exists */
		else
			yaffsfs_SetError(-ENOSPC);	/* assume no space */
	}

	yaffsfs_Unlock();

	kfree(alt_path);

	return retVal;
}

int yaffs_rmdir(const YCHAR *path)
{
	int result;
	YCHAR *alt_path;

	if (!path) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	if (yaffsfs_alt_dir_path(path, &alt_path) < 0) {
		yaffsfs_SetError(-ENOMEM);
		return -1;
	}
	if (alt_path)
		path = alt_path;
	result = yaffsfs_DoUnlink(path, 1);

	kfree(alt_path);

	return result;
}

void *yaffs_getdev(const YCHAR *path)
{
	struct yaffs_dev *dev = NULL;
	YCHAR *dummy;
	dev = yaffsfs_FindDevice(path, &dummy);
	return (void *)dev;
}

int yaffs_mount_common(const YCHAR *path, int read_only, int skip_checkpt)
{
	int retVal = -1;
	int result = YAFFS_FAIL;
	struct yaffs_dev *dev = NULL;

	if (!path) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	yaffs_trace(YAFFS_TRACE_MOUNT, "yaffs: Mounting %s", path);

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();

	yaffsfs_InitHandles();

	dev = yaffsfs_FindMountPoint(path);
	if (dev) {
		if (!dev->is_mounted) {
			dev->read_only = read_only ? 1 : 0;
			if (skip_checkpt) {
				u8 skip = dev->param.skip_checkpt_rd;
				dev->param.skip_checkpt_rd = 1;
				result = yaffs_guts_initialise(dev);
				dev->param.skip_checkpt_rd = skip;
			} else {
				result = yaffs_guts_initialise(dev);
			}

			if (result == YAFFS_FAIL)
				yaffsfs_SetError(-ENOMEM);
			retVal = result ? 0 : -1;

		} else
			yaffsfs_SetError(-EBUSY);
	} else
		yaffsfs_SetError(-ENODEV);

	yaffsfs_Unlock();
	return retVal;

}

int yaffs_mount2(const YCHAR *path, int readonly)
{
	return yaffs_mount_common(path, readonly, 0);
}

int yaffs_mount(const YCHAR *path)
{
	return yaffs_mount_common(path, 0, 0);
}

int yaffs_sync(const YCHAR *path)
{
	int retVal = -1;
	struct yaffs_dev *dev = NULL;
	YCHAR *dummy;

	if (!path) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();
	dev = yaffsfs_FindDevice(path, &dummy);
	if (dev) {
		if (!dev->is_mounted)
			yaffsfs_SetError(-EINVAL);
		else if (dev->read_only)
			yaffsfs_SetError(-EROFS);
		else {

			yaffs_flush_whole_cache(dev);
			yaffs_checkpoint_save(dev);
			retVal = 0;

		}
	} else
		yaffsfs_SetError(-ENODEV);

	yaffsfs_Unlock();
	return retVal;
}

static int yaffsfs_IsDevBusy(struct yaffs_dev *dev)
{
	int i;
	struct yaffs_obj *obj;

	for (i = 0; i < YAFFSFS_N_HANDLES; i++) {
		obj = yaffsfs_HandleToObject(i);
		if (obj && obj->my_dev == dev)
			return 1;
	}
	return 0;
}

int yaffs_remount(const YCHAR *path, int force, int read_only)
{
	int retVal = -1;
	struct yaffs_dev *dev = NULL;

	if (!path) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();
	dev = yaffsfs_FindMountPoint(path);
	if (dev) {
		if (dev->is_mounted) {
			yaffs_flush_whole_cache(dev);

			if (force || !yaffsfs_IsDevBusy(dev)) {
				if (read_only)
					yaffs_checkpoint_save(dev);
				dev->read_only = read_only ? 1 : 0;
				retVal = 0;
			} else
				yaffsfs_SetError(-EBUSY);

		} else
			yaffsfs_SetError(-EINVAL);

	} else
		yaffsfs_SetError(-ENODEV);

	yaffsfs_Unlock();
	return retVal;

}

int yaffs_unmount2(const YCHAR *path, int force)
{
	int retVal = -1;
	struct yaffs_dev *dev = NULL;

	if (!path) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();
	dev = yaffsfs_FindMountPoint(path);
	if (dev) {
		if (dev->is_mounted) {
			int inUse;
			yaffs_flush_whole_cache(dev);
			yaffs_checkpoint_save(dev);
			inUse = yaffsfs_IsDevBusy(dev);
			if (!inUse || force) {
				if (inUse)
					yaffsfs_BreakDeviceHandles(dev);
				yaffs_deinitialise(dev);

				retVal = 0;
			} else
				yaffsfs_SetError(-EBUSY);

		} else
			yaffsfs_SetError(-EINVAL);

	} else
		yaffsfs_SetError(-ENODEV);

	yaffsfs_Unlock();
	return retVal;

}

int yaffs_unmount(const YCHAR *path)
{
	return yaffs_unmount2(path, 0);
}

loff_t yaffs_freespace(const YCHAR *path)
{
	loff_t retVal = -1;
	struct yaffs_dev *dev = NULL;
	YCHAR *dummy;

	if (!path) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();
	dev = yaffsfs_FindDevice(path, &dummy);
	if (dev && dev->is_mounted) {
		retVal = yaffs_get_n_free_chunks(dev);
		retVal *= dev->data_bytes_per_chunk;

	} else
		yaffsfs_SetError(-EINVAL);

	yaffsfs_Unlock();
	return retVal;
}

loff_t yaffs_totalspace(const YCHAR *path)
{
	loff_t retVal = -1;
	struct yaffs_dev *dev = NULL;
	YCHAR *dummy;

	if (!path) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();
	dev = yaffsfs_FindDevice(path, &dummy);
	if (dev && dev->is_mounted) {
		retVal = (dev->param.end_block - dev->param.start_block + 1) -
		    dev->param.n_reserved_blocks;
		retVal *= dev->param.chunks_per_block;
		retVal *= dev->data_bytes_per_chunk;

	} else
		yaffsfs_SetError(-EINVAL);

	yaffsfs_Unlock();
	return retVal;
}

int yaffs_inodecount(const YCHAR *path)
{
	loff_t retVal = -1;
	struct yaffs_dev *dev = NULL;
	YCHAR *dummy;

	if (!path) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();
	dev = yaffsfs_FindDevice(path, &dummy);
	if (dev && dev->is_mounted) {
		int n_obj = dev->n_obj;
		if (n_obj > dev->n_hardlinks)
			retVal = n_obj - dev->n_hardlinks;
	}

	if (retVal < 0)
		yaffsfs_SetError(-EINVAL);

	yaffsfs_Unlock();
	return retVal;
}

void yaffs_add_device(struct yaffs_dev *dev)
{
	struct list_head *cfg;
	/* First check that the device is not in the list. */

	list_for_each(cfg, &yaffsfs_deviceList) {
		if (dev == list_entry(cfg, struct yaffs_dev, dev_list))
			return;
	}

	dev->is_mounted = 0;
	dev->param.remove_obj_fn = yaffsfs_RemoveObjectCallback;

	if (!dev->dev_list.next)
		INIT_LIST_HEAD(&dev->dev_list);

	list_add(&dev->dev_list, &yaffsfs_deviceList);
}

void yaffs_remove_device(struct yaffs_dev *dev)
{
	list_del_init(&dev->dev_list);
}

/* Functions to iterate through devices. NB Use with extreme care! */

static struct list_head *dev_iterator;
void yaffs_dev_rewind(void)
{
	dev_iterator = yaffsfs_deviceList.next;
}

struct yaffs_dev *yaffs_next_dev(void)
{
	struct yaffs_dev *retval;

	if (!dev_iterator)
		return NULL;
	if (dev_iterator == &yaffsfs_deviceList)
		return NULL;

	retval = list_entry(dev_iterator, struct yaffs_dev, dev_list);
	dev_iterator = dev_iterator->next;
	return retval;
}

/* Directory search stuff. */

static struct list_head search_contexts;

static void yaffsfs_SetDirRewound(struct yaffsfs_DirSearchContxt *dsc)
{
	if (dsc &&
	    dsc->dirObj &&
	    dsc->dirObj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) {

		dsc->offset = 0;

		if (list_empty(&dsc->dirObj->variant.dir_variant.children))
			dsc->nextReturn = NULL;
		else
			dsc->nextReturn =
			    list_entry(dsc->dirObj->variant.dir_variant.
				       children.next, struct yaffs_obj,
				       siblings);
	} else {
		/* Hey someone isn't playing nice! */
	}
}

static void yaffsfs_DirAdvance(struct yaffsfs_DirSearchContxt *dsc)
{
	if (dsc &&
	    dsc->dirObj &&
	    dsc->dirObj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) {

		if (dsc->nextReturn == NULL ||
		    list_empty(&dsc->dirObj->variant.dir_variant.children))
			dsc->nextReturn = NULL;
		else {
			struct list_head *next = dsc->nextReturn->siblings.next;

			if (next == &dsc->dirObj->variant.dir_variant.children)
				dsc->nextReturn = NULL;	/* end of list */
			else
				dsc->nextReturn = list_entry(next,
							     struct yaffs_obj,
							     siblings);
		}
	} else {
		/* Hey someone isn't playing nice! */
	}
}

static void yaffsfs_RemoveObjectCallback(struct yaffs_obj *obj)
{

	struct list_head *i;
	struct yaffsfs_DirSearchContxt *dsc;

	/* if search contexts not initilised then skip */
	if (!search_contexts.next)
		return;

	/* Iterate through the directory search contexts.
	 * If any are the one being removed, then advance the dsc to
	 * the next one to prevent a hanging ptr.
	 */
	list_for_each(i, &search_contexts) {
		dsc = list_entry(i, struct yaffsfs_DirSearchContxt, others);
		if (dsc->nextReturn == obj)
			yaffsfs_DirAdvance(dsc);
	}

}

yaffs_DIR *yaffs_opendir(const YCHAR *dirname)
{
	yaffs_DIR *dir = NULL;
	struct yaffs_obj *obj = NULL;
	struct yaffsfs_DirSearchContxt *dsc = NULL;
	int notDir = 0;
	int loop = 0;

	if (!dirname) {
		yaffsfs_SetError(-EFAULT);
		return NULL;
	}

	if (yaffsfs_CheckPath(dirname) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return NULL;
	}

	yaffsfs_Lock();

	obj = yaffsfs_FindObject(NULL, dirname, 0, 1, NULL, &notDir, &loop);

	if (!obj && notDir)
		yaffsfs_SetError(-ENOTDIR);
	else if (loop)
		yaffsfs_SetError(-ELOOP);
	else if (!obj)
		yaffsfs_SetError(-ENOENT);
	else if (obj->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
		yaffsfs_SetError(-ENOTDIR);
	else {
		int i;

		for (i = 0, dsc = NULL; i < YAFFSFS_N_DSC && !dsc; i++) {
			if (!yaffsfs_dsc[i].inUse)
				dsc = &yaffsfs_dsc[i];
		}

		dir = (yaffs_DIR *) dsc;

		if (dsc) {
			memset(dsc, 0, sizeof(struct yaffsfs_DirSearchContxt));
			dsc->inUse = 1;
			dsc->dirObj = obj;
			yaffs_strncpy(dsc->name, dirname, NAME_MAX);
			INIT_LIST_HEAD(&dsc->others);

			if (!search_contexts.next)
				INIT_LIST_HEAD(&search_contexts);

			list_add(&dsc->others, &search_contexts);
			yaffsfs_SetDirRewound(dsc);
		}

	}

	yaffsfs_Unlock();

	return dir;
}

struct yaffs_dirent *yaffs_readdir(yaffs_DIR * dirp)
{
	struct yaffsfs_DirSearchContxt *dsc;
	struct yaffs_dirent *retVal = NULL;

	dsc = (struct yaffsfs_DirSearchContxt *) dirp;
	yaffsfs_Lock();

	if (dsc && dsc->inUse) {
		yaffsfs_SetError(0);
		if (dsc->nextReturn) {
			dsc->de.d_ino =
			    yaffs_get_equivalent_obj(dsc->nextReturn)->obj_id;
			dsc->de.d_dont_use = (unsigned)dsc->nextReturn;
			dsc->de.d_off = dsc->offset++;
			yaffs_get_obj_name(dsc->nextReturn,
					   dsc->de.d_name, NAME_MAX);
			if (yaffs_strnlen(dsc->de.d_name, NAME_MAX + 1) == 0) {
				/* this should not happen! */
				yaffs_strcpy(dsc->de.d_name, _Y("zz"));
			}
			dsc->de.d_reclen = sizeof(struct yaffs_dirent);
			retVal = &dsc->de;
			yaffsfs_DirAdvance(dsc);
		} else
			retVal = NULL;
	} else
		yaffsfs_SetError(-EBADF);

	yaffsfs_Unlock();

	return retVal;

}

void yaffs_rewinddir(yaffs_DIR *dirp)
{
	struct yaffsfs_DirSearchContxt *dsc;

	dsc = (struct yaffsfs_DirSearchContxt *) dirp;

	yaffsfs_Lock();

	yaffsfs_SetDirRewound(dsc);

	yaffsfs_Unlock();
}

int yaffs_closedir(yaffs_DIR *dirp)
{
	struct yaffsfs_DirSearchContxt *dsc;

	dsc = (struct yaffsfs_DirSearchContxt *) dirp;

	if (!dsc) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	yaffsfs_Lock();
	dsc->inUse = 0;
	list_del(&dsc->others);	/* unhook from list */
	yaffsfs_Unlock();
	return 0;
}

/* End of directory stuff */

int yaffs_symlink(const YCHAR *oldpath, const YCHAR *newpath)
{
	struct yaffs_obj *parent = NULL;
	struct yaffs_obj *obj;
	YCHAR *name;
	int retVal = -1;
	int mode = 0;		/* ignore for now */
	int notDir = 0;
	int loop = 0;

	if (!oldpath || !newpath) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(newpath) < 0 || yaffsfs_CheckPath(oldpath) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();
	parent = yaffsfs_FindDirectory(NULL, newpath, &name, 0, &notDir, &loop);
	if (!parent && notDir)
		yaffsfs_SetError(-ENOTDIR);
	else if (loop)
		yaffsfs_SetError(-ELOOP);
	else if (!parent || yaffs_strnlen(name, 5) < 1)
		yaffsfs_SetError(-ENOENT);
	else if (yaffsfs_TooManyObjects(parent->my_dev))
		yaffsfs_SetError(-ENFILE);
	else if (parent->my_dev->read_only)
		yaffsfs_SetError(-EROFS);
	else {
		obj = yaffs_create_symlink(parent, name, mode, 0, 0, oldpath);
		if (obj)
			retVal = 0;
		else if (yaffsfs_FindObject
			 (NULL, newpath, 0, 0, NULL, NULL, NULL))
			yaffsfs_SetError(-EEXIST);
		else
			yaffsfs_SetError(-ENOSPC);
	}

	yaffsfs_Unlock();

	return retVal;

}

int yaffs_readlink(const YCHAR *path, YCHAR *buf, int bufsiz)
{
	struct yaffs_obj *obj = NULL;
	struct yaffs_obj *dir = NULL;
	int retVal = -1;
	int notDir = 0;
	int loop = 0;

	if (!path || !buf) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	yaffsfs_Lock();

	obj = yaffsfs_FindObject(NULL, path, 0, 1, &dir, &notDir, &loop);

	if (!dir && notDir)
		yaffsfs_SetError(-ENOTDIR);
	else if (loop)
		yaffsfs_SetError(-ELOOP);
	else if (!dir || !obj)
		yaffsfs_SetError(-ENOENT);
	else if (obj->variant_type != YAFFS_OBJECT_TYPE_SYMLINK)
		yaffsfs_SetError(-EINVAL);
	else {
		YCHAR *alias = obj->variant.symlink_variant.alias;
		memset(buf, 0, bufsiz);
		yaffs_strncpy(buf, alias, bufsiz - 1);
		retVal = 0;
	}
	yaffsfs_Unlock();
	return retVal;
}

int yaffs_link(const YCHAR *oldpath, const YCHAR *linkpath)
{
	/* Creates a link called newpath to existing oldpath */
	struct yaffs_obj *obj = NULL;
	struct yaffs_obj *lnk = NULL;
	struct yaffs_obj *obj_dir = NULL;
	struct yaffs_obj *lnk_dir = NULL;
	int retVal = -1;
	int notDirObj = 0;
	int notDirLnk = 0;
	int objLoop = 0;
	int lnkLoop = 0;
	YCHAR *newname;

	if (!oldpath || !linkpath) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(linkpath) < 0 || yaffsfs_CheckPath(oldpath) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	yaffsfs_Lock();

	obj = yaffsfs_FindObject(NULL, oldpath, 0, 1,
				 &obj_dir, &notDirObj, &objLoop);
	lnk = yaffsfs_FindObject(NULL, linkpath, 0, 0, NULL, NULL, NULL);
	lnk_dir = yaffsfs_FindDirectory(NULL, linkpath, &newname,
					0, &notDirLnk, &lnkLoop);

	if ((!obj_dir && notDirObj) || (!lnk_dir && notDirLnk))
		yaffsfs_SetError(-ENOTDIR);
	else if (objLoop || lnkLoop)
		yaffsfs_SetError(-ELOOP);
	else if (!obj_dir || !lnk_dir || !obj)
		yaffsfs_SetError(-ENOENT);
	else if (obj->my_dev->read_only)
		yaffsfs_SetError(-EROFS);
	else if (yaffsfs_TooManyObjects(obj->my_dev))
		yaffsfs_SetError(-ENFILE);
	else if (lnk)
		yaffsfs_SetError(-EEXIST);
	else if (lnk_dir->my_dev != obj->my_dev)
		yaffsfs_SetError(-EXDEV);
	else {
		retVal = yaffsfs_CheckNameLength(newname);

		if (retVal == 0) {
			lnk = yaffs_link_obj(lnk_dir, newname, obj);
			if (lnk)
				retVal = 0;
			else {
				yaffsfs_SetError(-ENOSPC);
				retVal = -1;
			}
		}
	}
	yaffsfs_Unlock();

	return retVal;
}

int yaffs_mknod(const YCHAR *pathname, mode_t mode, dev_t dev)
{
	yaffsfs_SetError(-EINVAL);
	return -1;
}

/*
 * D E B U G   F U N C T I O N S
 */

/*
 * yaffs_n_handles()
 * Returns number of handles attached to the object
 */
int yaffs_n_handles(const YCHAR *path)
{
	struct yaffs_obj *obj;

	if (!path) {
		yaffsfs_SetError(-EFAULT);
		return -1;
	}

	if (yaffsfs_CheckPath(path) < 0) {
		yaffsfs_SetError(-ENAMETOOLONG);
		return -1;
	}

	obj = yaffsfs_FindObject(NULL, path, 0, 1, NULL, NULL, NULL);

	if (obj)
		return yaffsfs_CountHandles(obj);
	else
		return -1;
}

int yaffs_get_error(void)
{
	return yaffsfs_GetLastError();
}

int yaffs_set_error(int error)
{
	yaffsfs_SetError(error);
	return 0;
}

int yaffs_dump_dev(const YCHAR *path)
{
#if 0
	YCHAR *rest;

	struct yaffs_obj *obj = yaffsfs_FindRoot(path, &rest);

	if (obj) {
		struct yaffs_dev *dev = obj->my_dev;

		printf("\n"
		       "n_page_writes.......... %d\n"
		       "n_page_reads........... %d\n"
		       "n_erasures....... %d\n"
		       "n_gc_copies............ %d\n"
		       "garbageCollections... %d\n"
		       "passiveGarbageColl'ns %d\n"
		       "\n",
		       dev->n_page_writes,
		       dev->n_page_reads,
		       dev->n_erasures,
		       dev->n_gc_copies,
		       dev->garbageCollections, dev->passiveGarbageCollections);

	}
#endif
	return 0;
}
