tizen 2.3.1 release
[platform/kernel/u-boot.git] / fs / yaffs2 / yaffsfs.c
index 334598e..111cb34 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2011 Aleph One Ltd.
+ * Copyright (C) 2002-2007 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
  * published by the Free Software Foundation.
  */
 
-#include <div64.h>
+/* XXX U-BOOT XXX */
+#include <common.h>
+#include <malloc.h>
+
 #include "yaffsfs.h"
 #include "yaffs_guts.h"
 #include "yaffscfg.h"
 #include "yportenv.h"
-#include "yaffs_trace.h"
+
+/* XXX U-BOOT XXX */
+#if 0
+#include <string.h> // for memset
+#endif
 
 #define YAFFSFS_MAX_SYMLINK_DEREFERENCES 5
 
 #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;
+const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.18 2007/07/18 19:40:38 charles Exp $";
 
-       if (obj)
-               obj = yaffs_get_equivalent_obj(obj);
+// configurationList is the list of devices that are supported
+static yaffsfs_DeviceConfiguration *yaffsfs_configurationList;
 
-       ret = yaffsfs_FindInodeIdForObject(obj);
 
-       for (i = 0; i < YAFFSFS_N_HANDLES && ret < 0; i++) {
-               if (!yaffsfs_inode[i].iObj)
-                       ret = i;
-       }
+/* Some forward references */
+static yaffs_Object *yaffsfs_FindObject(yaffs_Object *relativeDirectory, const char *path, int symDepth);
+static void yaffsfs_RemoveObjectCallback(yaffs_Object *obj);
 
-       if (ret >= 0) {
-               in = &yaffsfs_inode[ret];
-               if (!in->iObj)
-                       in->count = 0;
-               in->iObj = obj;
-               in->count++;
-       }
 
-       return ret;
-}
+// Handle management.
+//
 
-static int yaffsfs_CountHandles(struct yaffs_obj *obj)
-{
-       int i = yaffsfs_FindInodeIdForObject(obj);
 
-       if (i >= 0)
-               return yaffsfs_inode[i].count;
-       else
-               return 0;
-}
+unsigned int yaffs_wr_attempts;
 
-static void yaffsfs_ReleaseInode(struct yaffsfs_Inode *in)
+typedef struct
 {
-       struct yaffs_obj *obj;
-
-       obj = in->iObj;
-
-       if (obj->unlinked)
-               yaffs_del_obj(obj);
+       __u8  inUse:1;          // this handle is in use
+       __u8  readOnly:1;       // this handle is read only
+       __u8  append:1;         // append only
+       __u8  exclusive:1;      // exclusive
+       __u32 position;         // current position in file
+       yaffs_Object *obj;      // the object
+}yaffsfs_Handle;
 
-       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 yaffsfs_Handle yaffsfs_handle[YAFFSFS_N_HANDLES];
 
-static int yaffsfs_NewHandle(struct yaffsfs_Handle **hptr)
+// yaffsfs_InitHandle
+/// Inilitalise handles on start-up.
+//
+static int yaffsfs_InitHandles(void)
 {
        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;
-               }
+       for(i = 0; i < YAFFSFS_N_HANDLES; i++)
+       {
+               yaffsfs_handle[i].inUse = 0;
+               yaffsfs_handle[i].obj = NULL;
        }
-       return -1;
+       return 0;
 }
 
-static int yaffsfs_NewHandleAndFileDes(void)
+yaffsfs_Handle *yaffsfs_GetHandlePointer(int h)
 {
-       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;
-               }
+       if(h < 0 || h >= YAFFSFS_N_HANDLES)
+       {
+               return NULL;
        }
 
-       /* Dump the handle because we could not get a fd */
-       h->useCount = 0;
-       return -1;
+       return &yaffsfs_handle[h];
 }
 
-/*
- * yaffs_get_handle
- * Increase use of handle when reading/writing a file
- * Also gets the file descriptor.
- */
-
-static int yaffsfs_GetHandle(int handle)
+yaffs_Object *yaffsfs_GetHandleObject(int handle)
 {
-       struct yaffsfs_Handle *h = yaffsfs_HandleToPointer(handle);
+       yaffsfs_Handle *h = yaffsfs_GetHandlePointer(handle);
 
-       if (h && h->useCount > 0) {
-               h->useCount++;
-               return 0;
+       if(h && h->inUse)
+       {
+               return h->obj;
        }
-       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;
+       return NULL;
 }
 
-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;
-}
+//yaffsfs_GetHandle
+// Grab a handle (when opening a file)
+//
 
-static void yaffsfs_BreakDeviceHandles(struct yaffs_dev *dev)
+static int yaffsfs_GetHandle(void)
 {
-       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;
+       yaffsfs_Handle *h;
+
+       for(i = 0; i < YAFFSFS_N_HANDLES; i++)
+       {
+               h = yaffsfs_GetHandlePointer(i);
+               if(!h)
+               {
+                       // todo bug: should never happen
                }
-               if (fd && fd->handleCount > 0 && obj && obj->my_dev == dev) {
-                       fd->handleCount = 0;
-                       yaffsfs_PutInode(fd->inodeId);
-                       fd->inodeId = -1;
+               if(!h->inUse)
+               {
+                       memset(h,0,sizeof(yaffsfs_Handle));
+                       h->inUse=1;
+                       return i;
                }
        }
+       return -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)
+// yaffs_PutHandle
+// Let go of a handle (when closing a file)
+//
+static int yaffsfs_PutHandle(int handle)
 {
-       const YCHAR *str = YAFFS_PATH_DIVIDERS;
+       yaffsfs_Handle *h = yaffsfs_GetHandlePointer(handle);
 
-       while (*str) {
-               if (*str == ch)
-                       return 1;
-               str++;
+       if(h)
+       {
+               h->inUse = 0;
+               h->obj = NULL;
        }
-
        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;
-       }
+// Stuff to search for a directory from a path
 
-       return retVal;
-}
 
-static int yaffsfs_alt_dir_path(const YCHAR *path, YCHAR **ret_path)
+int yaffsfs_Match(char a, char b)
 {
-       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;
+       // case sensitive
+       return (a == b);
 }
 
-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)
+// yaffsfs_FindDevice
+// yaffsfs_FindRoot
+// Scan the configuration list to find the root.
+// Curveballs: Should match paths that end in '/' too
+// Curveball2 Might have "/x/ and "/x/y". Need to return the longest match
+static yaffs_Device *yaffsfs_FindDevice(const char *path, char **restOfPath)
 {
-       struct list_head *cfg;
-       const YCHAR *leftOver;
-       const YCHAR *p;
-       struct yaffs_dev *retval = NULL;
-       struct yaffs_dev *dev = NULL;
+       yaffsfs_DeviceConfiguration *cfg = yaffsfs_configurationList;
+       const char *leftOver;
+       const char *p;
+       yaffs_Device *retval = 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);
+       // Check all configs, choose the one that:
+       // 1) Actually matches a prefix (ie /a amd /abc will not match
+       // 2) Matches the longest.
+       while(cfg && cfg->prefix && cfg->dev)
+       {
                leftOver = path;
-               p = dev->param.name;
+               p = cfg->prefix;
                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))
+               while(*p &&  //unmatched part of prefix
+                     strcmp(p,"/") && // the rest of the prefix is not / (to catch / at end)
+                     *leftOver &&
+                     yaffsfs_Match(*p,*leftOver))
+               {
                        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;
+                       leftOver++;
+                       thisMatchLength++;
+               }
+               if((!*p || strcmp(p,"/") == 0) &&      // end of prefix
+                  (!*leftOver || *leftOver == '/') && // no more in this path name part
+                  (thisMatchLength > longestMatch))
+               {
+                       // Matched prefix
+                       *restOfPath = (char *)leftOver;
+                       retval = cfg->dev;
                        longestMatch = thisMatchLength;
                }
-
+               cfg++;
        }
        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)
+static yaffs_Object *yaffsfs_FindRoot(const char *path, char **restOfPath)
 {
-       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;
+       yaffs_Device *dev;
 
+       dev= yaffsfs_FindDevice(path,restOfPath);
+       if(dev && dev->isMounted)
+       {
+               return dev->rootDir;
+       }
        return NULL;
 }
 
-static struct yaffs_obj *yaffsfs_FollowLink(struct yaffs_obj *obj,
-                                           int symDepth, int *loop)
+static yaffs_Object *yaffsfs_FollowLink(yaffs_Object *obj,int symDepth)
 {
 
-       if (obj)
-               obj = yaffs_get_equivalent_obj(obj);
-
-       while (obj && obj->variant_type == YAFFS_OBJECT_TYPE_SYMLINK) {
-               YCHAR *alias = obj->variant.symlink_variant.alias;
+       while(obj && obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
+       {
+               char *alias = obj->variant.symLinkVariant.alias;
 
-               if (yaffsfs_IsPathDivider(*alias))
-                       /* Starts with a /, need to scan from root up */
-                       obj = yaffsfs_FindObject(NULL, alias, symDepth++,
-                                                1, NULL, NULL, loop);
+               if(*alias == '/')
+               {
+                       // Starts with a /, need to scan from root up
+                       obj = yaffsfs_FindObject(NULL,alias,symDepth++);
+               }
                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);
+               {
+                       // Relative to here, so use the parent of the symlink as a start
+                       obj = yaffsfs_FindObject(obj->parent,alias,symDepth++);
+               }
        }
        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)
+
+// 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 yaffs_Object *yaffsfs_DoFindDirectory(yaffs_Object *startDir,const char *path,char **name,int symDepth)
 {
-       struct yaffs_obj *dir;
-       YCHAR *restOfPath;
-       YCHAR str[YAFFS_MAX_NAME_LENGTH + 1];
+       yaffs_Object *dir;
+       char *restOfPath;
+       char str[YAFFS_MAX_NAME_LENGTH+1];
        int i;
 
-       if (symDepth > YAFFSFS_MAX_SYMLINK_DEREFERENCES) {
-               if (loop)
-                       *loop = 1;
+       if(symDepth > YAFFSFS_MAX_SYMLINK_DEREFERENCES)
+       {
                return NULL;
        }
 
-       if (startDir) {
+       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 '/' */
+               restOfPath = (char *)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(*restOfPath == '/')
+               {
+                       restOfPath++; // get rid of '/'
+               }
 
                *name = restOfPath;
                i = 0;
 
-               while (*restOfPath && !yaffsfs_IsPathDivider(*restOfPath)) {
-                       if (i < YAFFS_MAX_NAME_LENGTH) {
+               while(*restOfPath && *restOfPath != '/')
+               {
+                       if (i < YAFFS_MAX_NAME_LENGTH)
+                       {
                                str[i] = *restOfPath;
-                               str[i + 1] = '\0';
+                               str[i+1] = '\0';
                                i++;
                        }
                        restOfPath++;
                }
 
-               if (!*restOfPath)
-                       /* got to the end of the string */
+               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) {
+               }
+               else
+               {
+                       if(strcmp(str,".") == 0)
+                       {
+                               // Do nothing
+                       }
+                       else if(strcmp(str,"..") == 0)
+                       {
                                dir = dir->parent;
-                       } else {
-                               dir = yaffs_find_by_name(dir, str);
+                       }
+                       else
+                       {
+                               dir = yaffs_FindObjectByName(dir,str);
 
-                               dir = yaffsfs_FollowLink(dir, symDepth, loop);
+                               while(dir && dir->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
+                               {
+
+                                       dir = yaffsfs_FollowLink(dir,symDepth);
 
-                               if (dir && dir->variant_type !=
-                                   YAFFS_OBJECT_TYPE_DIRECTORY) {
-                                       if (notDir)
-                                               *notDir = 1;
-                                       dir = NULL;
                                }
 
+                               if(dir && dir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
+                               {
+                                       dir = NULL;
+                               }
                        }
                }
        }
-       /* directory did not exist. */
+       // 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)
+static yaffs_Object *yaffsfs_FindDirectory(yaffs_Object *relativeDirectory,const char *path,char **name,int symDepth)
 {
-       return yaffsfs_DoFindDirectory(relDir, path, name, symDepth, notDir,
-                                               loop);
+       return yaffsfs_DoFindDirectory(relativeDirectory,path,name,symDepth);
 }
 
-/*
- * 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)
+// yaffsfs_FindObject turns a path for an existing object into the object
+//
+static yaffs_Object *yaffsfs_FindObject(yaffs_Object *relativeDirectory, const char *path,int symDepth)
 {
-       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;
-}
+       yaffs_Object *dir;
+       char *name;
 
-/*************************************************************************
- *     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;
+       dir = yaffsfs_FindDirectory(relativeDirectory,path,&name,symDepth);
 
-       yaffsfs_Lock();
-       existingHandle = yaffsfs_HandleToPointer(handle);
-       existingFD = yaffsfs_HandleToFileDes(handle);
-       if (existingFD)
-               newHandleNumber = yaffsfs_NewHandle(&newHandle);
-       if (newHandle) {
-               newHandle->fdId = existingHandle->fdId;
-               existingFD->handleCount++;
+       if(dir && *name)
+       {
+               return yaffs_FindObjectByName(dir,name);
        }
 
-       yaffsfs_Unlock();
-
-       if (!existingFD)
-               yaffsfs_SetError(-EBADF);
-       else if (!newHandle)
-               yaffsfs_SetError(-ENOMEM);
-
-       return newHandleNumber;
-
+       return dir;
 }
 
-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)
+int yaffs_open(const char *path, int oflag, int mode)
 {
-       struct yaffs_obj *obj = NULL;
-       struct yaffs_obj *dir = NULL;
-       YCHAR *name;
+       yaffs_Object *obj = NULL;
+       yaffs_Object *dir = NULL;
+       char *name;
        int handle = -1;
-       struct yaffsfs_FileDes *fd = NULL;
+       yaffsfs_Handle *h = NULL;
+       int alreadyOpen = 0;
+       int alreadyExclusive = 0;
        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);
+       int i;
 
-       /* Todo: Are there any more flag combos to sanitise ? */
 
-       /* Figure out if reading or writing is requested */
+       // todo sanity check oflag (eg. can't have O_TRUNC without WRONLY or RDWR
 
-       readRequested = (rwflags == O_RDWR || rwflags == O_RDONLY) ? 1 : 0;
-       writeRequested = (rwflags == O_RDWR || rwflags == O_WRONLY) ? 1 : 0;
 
        yaffsfs_Lock();
 
-       handle = yaffsfs_NewHandleAndFileDes();
+       handle = yaffsfs_GetHandle();
 
-       if (handle < 0) {
-               yaffsfs_SetError(-ENFILE);
-               errorReported = 1;
-       } else {
+       if(handle >= 0)
+       {
 
-               fd = yaffsfs_HandleToFileDes(handle);
+               h = yaffsfs_GetHandlePointer(handle);
 
-               /* try to find the exisiting object */
-               obj = yaffsfs_FindObject(NULL, path, 0, 1, NULL, NULL, NULL);
 
-               obj = yaffsfs_FollowLink(obj, symDepth++, &loop);
+               // try to find the exisiting object
+               obj = yaffsfs_FindObject(NULL,path,0);
 
-               if (obj &&
-                   obj->variant_type != YAFFS_OBJECT_TYPE_FILE &&
-                   obj->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
-                       obj = NULL;
+               if(obj && obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
+               {
 
-               if (obj) {
+                       obj = yaffsfs_FollowLink(obj,symDepth++);
+               }
 
-                       /* The file already exists or it might be a directory */
+               if(obj)
+               {
+                       // Check if the object is already in use
+                       alreadyOpen = alreadyExclusive = 0;
+
+                       for(i = 0; i <= YAFFSFS_N_HANDLES; i++)
+                       {
+
+                               if(i != handle &&
+                                  yaffsfs_handle[i].inUse &&
+                                   obj == yaffsfs_handle[i].obj)
+                                {
+                                       alreadyOpen = 1;
+                                       if(yaffsfs_handle[i].exclusive)
+                                       {
+                                               alreadyExclusive = 1;
+                                       }
+                                }
+                       }
 
-                       /* A directory can't be opened as a file */
-                       if (obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) {
+                       if(((oflag & O_EXCL) && alreadyOpen) || alreadyExclusive)
+                       {
                                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)) {
+                       // Open should fail if O_CREAT and O_EXCL are specified
+                       if((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) {
+                       // Check file permissions
+                       if( (oflag & (O_RDWR | O_WRONLY)) == 0 &&     // ie O_RDONLY
+                          !(obj->yst_mode & S_IREAD))
+                       {
                                openDenied = 1;
-                               yaffsfs_SetError(-EROFS);
-                               errorReported = 1;
                        }
 
-                       if (openDenied && !errorReported) {
-                               yaffsfs_SetError(-EACCES);
-                               errorReported = 1;
+                       if( (oflag & O_RDWR) &&
+                          !(obj->yst_mode & S_IREAD))
+                       {
+                               openDenied = 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( (oflag & (O_RDWR | O_WRONLY)) &&
+                          !(obj->yst_mode & S_IWRITE))
+                       {
+                               openDenied = 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) {
+               else if((oflag & O_CREAT))
+               {
+                       // Let's see if we can create this file
+                       dir = yaffsfs_FindDirectory(NULL,path,&name,0);
+                       if(dir)
+                       {
+                               obj = yaffs_MknodFile(dir,name,mode,0,0);
+                       }
+                       else
+                       {
                                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 && !openDenied)
+               {
+                       h->obj = obj;
+                       h->inUse = 1;
+               h->readOnly = (oflag & (O_WRONLY | O_RDWR)) ? 0 : 1;
+                       h->append =  (oflag & O_APPEND) ? 1 : 0;
+                       h->exclusive = (oflag & O_EXCL) ? 1 : 0;
+                       h->position = 0;
+
+                       obj->inUse++;
+                       if((oflag & O_TRUNC) && !h->readOnly)
+                       {
+                               //todo truncate
+                               yaffs_ResizeFile(obj,0);
+                       }
 
-                       if (!obj && !errorReported) {
-                               yaffsfs_SetError(-ENOSPC);
+               }
+               else
+               {
+                       yaffsfs_PutHandle(handle);
+                       if(!errorReported)
+                       {
+                               yaffsfs_SetError(-EACCESS);
                                errorReported = 1;
                        }
+                       handle = -1;
                }
 
-               if (!obj && dir && !errorReported && !(oflag & O_CREAT)) {
-                       yaffsfs_SetError(-ENOENT);
-                       errorReported = 1;
-               }
+       }
 
-               if (obj && !openDenied) {
-                       int inodeId = yaffsfs_GetInodeIdForObject(obj);
+       yaffsfs_Unlock();
 
-                       if (inodeId < 0) {
-                               /*
-                                * Todo: Fix any problem if inodes run out,
-                                * That can't happen if the number of inode
-                                * items >= number of handles.
-                                */
-                       }
+       return handle;
+}
 
-                       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)
+int yaffs_close(int fd)
 {
-       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_Handle *h = NULL;
+       int retVal = 0;
 
        yaffsfs_Lock();
 
-       obj = yaffsfs_HandleToObject(handle);
+       h = yaffsfs_GetHandlePointer(fd);
 
-       if (!obj)
-               yaffsfs_SetError(-EBADF);
-       else if (obj->my_dev->read_only)
-               yaffsfs_SetError(-EROFS);
-       else {
-               yaffs_flush_file(obj, 1, datasync);
+       if(h && h->inUse)
+       {
+               // clean up
+               yaffs_FlushFile(h->obj,1);
+               h->obj->inUse--;
+               if(h->obj->inUse <= 0 && h->obj->unlinked)
+               {
+                       yaffs_DeleteFile(h->obj);
+               }
+               yaffsfs_PutHandle(fd);
                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)
+       else
+       {
+               // bad handle
                yaffsfs_SetError(-EBADF);
-       else {
-               /* clean up */
-               yaffs_flush_file(obj, 1, 0);
-               yaffsfs_PutHandle(handle);
-               retVal = 0;
+               retVal = -1;
        }
 
        yaffsfs_Unlock();
@@ -1062,1854 +517,776 @@ int yaffs_close(int handle)
        return retVal;
 }
 
-int yaffsfs_do_read(int handle, void *vbuf, unsigned int nbyte,
-                   int isPread, loff_t offset)
+int yaffs_read(int fd, void *buf, unsigned int nbyte)
 {
-       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_Handle *h = NULL;
+       yaffs_Object *obj = NULL;
+       int pos = 0;
+       int nRead = -1;
+       int maxRead;
 
        yaffsfs_Lock();
-       fd = yaffsfs_HandleToFileDes(handle);
-       obj = yaffsfs_HandleToObject(handle);
+       h = yaffsfs_GetHandlePointer(fd);
+       obj = yaffsfs_GetHandleObject(fd);
 
-       if (!fd || !obj) {
-               /* bad handle */
+       if(!h || !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 if( h && obj)
+       {
+               pos=  h->position;
+               if(yaffs_GetObjectFileLength(obj) > pos)
+               {
+                       maxRead = yaffs_GetObjectFileLength(obj) - pos;
+               }
                else
+               {
                        maxRead = 0;
+               }
 
-               if (nbyte > maxRead)
+               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(nbyte > 0)
+               {
+                       nRead = yaffs_ReadDataFromFile(obj,buf,pos,nbyte);
+                       if(nRead >= 0)
+                       {
+                               h->position = pos + nRead;
                        }
-
-                       if (nRead == nToRead)
-                               nbyte -= nRead;
                        else
-                               nbyte = 0;      /* no more to read */
-
-                       if (nbyte > 0) {
-                               yaffsfs_Unlock();
-                               yaffsfs_Lock();
+                       {
+                               //todo error
                        }
-
                }
-
-               yaffsfs_PutHandle(handle);
-
-               if (!isPread) {
-                       if (totalRead >= 0)
-                               fd->position = startPos + totalRead;
-                       else
-                               yaffsfs_SetError(-EINVAL);
+               else
+               {
+                       nRead = 0;
                }
 
        }
 
        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);
-}
+       return (nRead >= 0) ? nRead : -1;
 
-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)
+int yaffs_write(int fd, const void *buf, unsigned int nbyte)
 {
-       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_Handle *h = NULL;
+       yaffs_Object *obj = NULL;
+       int pos = 0;
+       int nWritten = -1;
+       int writeThrough = 0;
 
        yaffsfs_Lock();
-       fd = yaffsfs_HandleToFileDes(handle);
-       obj = yaffsfs_HandleToObject(handle);
+       h = yaffsfs_GetHandlePointer(fd);
+       obj = yaffsfs_GetHandleObject(fd);
 
-       if (!fd || !obj) {
-               /* bad handle */
+       if(!h || !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 if( h && obj && h->readOnly)
+       {
+               // todo error
+       }
+       else if( h && obj)
+       {
+               if(h->append)
+               {
+                       pos =  yaffs_GetObjectFileLength(obj);
+               }
                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;
+               {
+                       pos = h->position;
                }
 
-               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;
+               nWritten = yaffs_WriteDataToFile(obj,buf,pos,nbyte,writeThrough);
 
-                       if (nWritten < 1 && totalWritten < 1) {
-                               yaffsfs_SetError(-ENOSPC);
-                               totalWritten = -1;
-                       }
-
-                       if (nbyte > 0) {
-                               yaffsfs_Unlock();
-                               yaffsfs_Lock();
-                       }
+               if(nWritten >= 0)
+               {
+                       h->position = pos + nWritten;
                }
-
-               yaffsfs_PutHandle(handle);
-
-               if (!isPwrite) {
-                       if (totalWritten > 0)
-                               fd->position = startPos + totalWritten;
-                       else
-                               yaffsfs_SetError(-EINVAL);
+               else
+               {
+                       //todo error
                }
-       }
-
-       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);
+       yaffsfs_Unlock();
 
-       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 (nWritten >= 0) ? nWritten : -1;
 
-       return (result) ? 0 : -1;
 }
 
-int yaffs_ftruncate(int handle, loff_t new_size)
+int yaffs_truncate(int fd, off_t newSize)
 {
-       struct yaffsfs_FileDes *fd = NULL;
-       struct yaffs_obj *obj = NULL;
+       yaffsfs_Handle *h = NULL;
+       yaffs_Object *obj = NULL;
        int result = 0;
 
        yaffsfs_Lock();
-       fd = yaffsfs_HandleToFileDes(handle);
-       obj = yaffsfs_HandleToObject(handle);
+       h = yaffsfs_GetHandlePointer(fd);
+       obj = yaffsfs_GetHandleObject(fd);
 
-       if (!fd || !obj)
-               /* bad handle */
+       if(!h || !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);
+       {
+               // resize the file
+               result = yaffs_ResizeFile(obj,newSize);
+       }
        yaffsfs_Unlock();
 
+
        return (result) ? 0 : -1;
 
 }
 
-loff_t yaffs_lseek(int handle, loff_t offset, int whence)
+off_t yaffs_lseek(int fd, off_t offset, int whence)
 {
-       struct yaffsfs_FileDes *fd = NULL;
-       struct yaffs_obj *obj = NULL;
-       loff_t pos = -1;
-       loff_t fSize = -1;
+       yaffsfs_Handle *h = NULL;
+       yaffs_Object *obj = NULL;
+       int pos = -1;
+       int fSize = -1;
 
        yaffsfs_Lock();
-       fd = yaffsfs_HandleToFileDes(handle);
-       obj = yaffsfs_HandleToObject(handle);
+       h = yaffsfs_GetHandlePointer(fd);
+       obj = yaffsfs_GetHandleObject(fd);
 
-       if (!fd || !obj)
+       if(!h || !obj)
+       {
+               // bad handle
                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;
+       }
+       else if(whence == SEEK_SET)
+       {
+               if(offset >= 0)
+               {
+                       pos = offset;
                }
-
-               if (pos >= 0 && pos <= YAFFS_MAX_FILE_SIZE)
-                       fd->position = pos;
-               else {
-                       yaffsfs_SetError(-EINVAL);
-                       pos = -1;
+       }
+       else if(whence == SEEK_CUR)
+       {
+               if( (h->position + offset) >= 0)
+               {
+                       pos = (h->position + offset);
+               }
+       }
+       else if(whence == SEEK_END)
+       {
+               fSize = yaffs_GetObjectFileLength(obj);
+               if(fSize >= 0 && (fSize + offset) >= 0)
+               {
+                       pos = fSize + offset;
                }
        }
 
+       if(pos >= 0)
+       {
+               h->position = pos;
+       }
+       else
+       {
+               // todo error
+       }
+
+
        yaffsfs_Unlock();
 
        return pos;
 }
 
-int yaffsfs_DoUnlink(const YCHAR *path, int isDirectory)
+
+int yaffsfs_DoUnlink(const char *path,int isDirectory)
 {
-       struct yaffs_obj *dir = NULL;
-       struct yaffs_obj *obj = NULL;
-       YCHAR *name;
+       yaffs_Object *dir = NULL;
+       yaffs_Object *obj = NULL;
+       char *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)
+       obj = yaffsfs_FindObject(NULL,path,0);
+       dir = yaffsfs_FindDirectory(NULL,path,&name,0);
+       if(!dir)
+       {
                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)
+       }
+       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)
+       }
+       else if(!isDirectory && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)
+       {
                yaffsfs_SetError(-EISDIR);
-       else if (isDirectory &&
-                obj->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
+       }
+       else if(isDirectory && obj->variantType != 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);
+       }
+       else
+       {
+               result = yaffs_Unlink(dir,name);
 
-               if (result == YAFFS_FAIL && isDirectory)
+               if(result == YAFFS_FAIL && isDirectory)
+               {
                        yaffsfs_SetError(-ENOTEMPTY);
+               }
        }
 
        yaffsfs_Unlock();
 
+       // todo error
+
        return (result == YAFFS_FAIL) ? -1 : 0;
 }
+int yaffs_rmdir(const char *path)
+{
+       return yaffsfs_DoUnlink(path,1);
+}
 
-int yaffs_unlink(const YCHAR *path)
+int yaffs_unlink(const char *path)
 {
-       return yaffsfs_DoUnlink(path, 0);
+       return yaffsfs_DoUnlink(path,0);
 }
 
-int yaffs_rename(const YCHAR *oldPath, const YCHAR *newPath)
+int yaffs_rename(const char *oldPath, const char *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;
+       yaffs_Object *olddir = NULL;
+       yaffs_Object *newdir = NULL;
+       yaffs_Object *obj = NULL;
+       char *oldname;
+       char *newname;
+       int result= YAFFS_FAIL;
+       int renameAllowed = 1;
 
-       YCHAR *alt_newpath = NULL;
+       yaffsfs_Lock();
 
-       if (!oldPath || !newPath) {
-               yaffsfs_SetError(-EFAULT);
-               return -1;
-       }
+       olddir = yaffsfs_FindDirectory(NULL,oldPath,&oldname,0);
+       newdir = yaffsfs_FindDirectory(NULL,newPath,&newname,0);
+       obj = yaffsfs_FindObject(NULL,oldPath,0);
 
-       if (yaffsfs_CheckPath(oldPath) < 0 || yaffsfs_CheckPath(newPath) < 0) {
-               yaffsfs_SetError(-ENAMETOOLONG);
-               return -1;
+       if(!olddir || !newdir || !obj)
+       {
+               // bad file
+               yaffsfs_SetError(-EBADF);
+               renameAllowed = 0;
        }
-
-       if (yaffsfs_alt_dir_path(newPath, &alt_newpath) < 0) {
-               yaffsfs_SetError(-ENOMEM);
-               return -1;
+       else if(olddir->myDev != newdir->myDev)
+       {
+               // oops must be on same device
+               // todo error
+               yaffsfs_SetError(-EXDEV);
+               renameAllowed = 0;
        }
-       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.
-        */
+       else if(obj && obj->variantType == 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
 
-       if (olddir == obj)
-               oldname = NULL;
+               yaffs_Object *xx = newdir;
 
-       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;
+               while( renameAllowed && xx)
+               {
+                       if(xx == obj)
+                       {
+                               renameAllowed = 0;
+                       }
                        xx = xx->parent;
                }
-               if (!rename_allowed)
-                       yaffsfs_SetError(-EINVAL);
+               if(!renameAllowed) yaffsfs_SetError(-EACCESS);
        }
 
-       if (rename_allowed)
-               result = yaffs_rename_obj(olddir, oldname, newdir, newname);
+       if(renameAllowed)
+       {
+               result = yaffs_RenameObject(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)
+
+static int yaffsfs_DoStat(yaffs_Object *obj,struct yaffs_stat *buf)
 {
        int retVal = -1;
 
-       obj = yaffs_get_equivalent_obj(obj);
+       if(obj)
+       {
+               obj = yaffs_GetEquivalentObject(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 && buf)
+       {
+       buf->st_dev = (int)obj->myDev->genericDevice;
+       buf->st_ino = obj->objectId;
+       buf->st_mode = obj->yst_mode & ~S_IFMT; // clear out file type bits
 
-               if (obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY)
+               if(obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)
+               {
                        buf->st_mode |= S_IFDIR;
-               else if (obj->variant_type == YAFFS_OBJECT_TYPE_SYMLINK)
+               }
+               else if(obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
+               {
                        buf->st_mode |= S_IFLNK;
-               else if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE)
+               }
+               else if(obj->variantType == 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
+       buf->st_nlink = yaffs_GetObjectLinkCount(obj);
+       buf->st_uid = 0;
+       buf->st_gid = 0;;
+       buf->st_rdev = obj->yst_rdev;
+       buf->st_size = yaffs_GetObjectFileLength(obj);
+               buf->st_blksize = obj->myDev->nDataBytesPerChunk;
+       buf->st_blocks = (buf->st_size + buf->st_blksize -1)/buf->st_blksize;
+       buf->yst_atime = obj->yst_atime;
+       buf->yst_ctime = obj->yst_ctime;
+       buf->yst_mtime = obj->yst_mtime;
                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)
+static int yaffsfs_DoStatOrLStat(const char *path, struct yaffs_stat *buf,int doLStat)
 {
-       struct yaffs_obj *obj;
+       yaffs_Object *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;
-       }
+       obj = yaffsfs_FindObject(NULL,path,0);
 
-       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(!doLStat && obj)
+       {
+               obj = yaffsfs_FollowLink(obj,0);
        }
 
-       if (yaffsfs_CheckPath(path) < 0) {
-               yaffsfs_SetError(-ENAMETOOLONG);
-               return -1;
+       if(obj)
+       {
+               retVal = yaffsfs_DoStat(obj,buf);
        }
-
-       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);
+       {
+               // todo error not found
+               yaffsfs_SetError(-ENOENT);
+       }
 
        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);
+int yaffs_stat(const char *path, struct yaffs_stat *buf)
+{
+       return yaffsfs_DoStatOrLStat(path,buf,0);
+}
 
-       return retVal;
+int yaffs_lstat(const char *path, struct yaffs_stat *buf)
+{
+       return yaffsfs_DoStatOrLStat(path,buf,1);
 }
 
-int yaffs_rmdir(const YCHAR *path)
+int yaffs_fstat(int fd, struct yaffs_stat *buf)
 {
-       int result;
-       YCHAR *alt_path;
+       yaffs_Object *obj;
 
-       if (!path) {
-               yaffsfs_SetError(-EFAULT);
-               return -1;
-       }
+       int retVal = -1;
 
-       if (yaffsfs_CheckPath(path) < 0) {
-               yaffsfs_SetError(-ENAMETOOLONG);
-               return -1;
-       }
+       yaffsfs_Lock();
+       obj = yaffsfs_GetHandleObject(fd);
 
-       if (yaffsfs_alt_dir_path(path, &alt_path) < 0) {
-               yaffsfs_SetError(-ENOMEM);
-               return -1;
+       if(obj)
+       {
+               retVal = yaffsfs_DoStat(obj,buf);
+       }
+       else
+       {
+               // bad handle
+               yaffsfs_SetError(-EBADF);
        }
-       if (alt_path)
-               path = alt_path;
-       result = yaffsfs_DoUnlink(path, 1);
-
-       kfree(alt_path);
 
-       return result;
-}
+       yaffsfs_Unlock();
 
-void *yaffs_getdev(const YCHAR *path)
-{
-       struct yaffs_dev *dev = NULL;
-       YCHAR *dummy;
-       dev = yaffsfs_FindDevice(path, &dummy);
-       return (void *)dev;
+       return retVal;
 }
 
-int yaffs_mount_common(const YCHAR *path, int read_only, int skip_checkpt)
+static int yaffsfs_DoChMod(yaffs_Object *obj,mode_t mode)
 {
-       int retVal = -1;
        int result = YAFFS_FAIL;
-       struct yaffs_dev *dev = NULL;
 
-       if (!path) {
-               yaffsfs_SetError(-EFAULT);
-               return -1;
+       if(obj)
+       {
+               obj = yaffs_GetEquivalentObject(obj);
        }
 
-       yaffs_trace(YAFFS_TRACE_MOUNT, "yaffs: Mounting %s", path);
-
-       if (yaffsfs_CheckPath(path) < 0) {
-               yaffsfs_SetError(-ENAMETOOLONG);
-               return -1;
+       if(obj)
+       {
+               obj->yst_mode = mode;
+               obj->dirty = 1;
+               result = yaffs_FlushFile(obj,0);
        }
 
-       yaffsfs_Lock();
+       return result == YAFFS_OK ? 0 : -1;
+}
 
-       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);
-                       }
+int yaffs_chmod(const char *path, mode_t mode)
+{
+       yaffs_Object *obj;
 
-                       if (result == YAFFS_FAIL)
-                               yaffsfs_SetError(-ENOMEM);
-                       retVal = result ? 0 : -1;
+       int retVal = -1;
 
-               } else
-                       yaffsfs_SetError(-EBUSY);
-       } else
-               yaffsfs_SetError(-ENODEV);
+       yaffsfs_Lock();
+       obj = yaffsfs_FindObject(NULL,path,0);
+
+       if(obj)
+       {
+               retVal = yaffsfs_DoChMod(obj,mode);
+       }
+       else
+       {
+               // todo error not found
+               yaffsfs_SetError(-ENOENT);
+       }
 
        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)
+int yaffs_fchmod(int fd, mode_t mode)
 {
-       return yaffs_mount_common(path, 0, 0);
-}
+       yaffs_Object *obj;
 
-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 {
+       obj = yaffsfs_GetHandleObject(fd);
 
-                       yaffs_flush_whole_cache(dev);
-                       yaffs_checkpoint_save(dev);
-                       retVal = 0;
-
-               }
-       } else
-               yaffsfs_SetError(-ENODEV);
+       if(obj)
+       {
+               retVal = yaffsfs_DoChMod(obj,mode);
+       }
+       else
+       {
+               // bad handle
+               yaffsfs_SetError(-EBADF);
+       }
 
        yaffsfs_Unlock();
+
        return retVal;
 }
 
-static int yaffsfs_IsDevBusy(struct yaffs_dev *dev)
+
+int yaffs_mkdir(const char *path, mode_t mode)
 {
-       int i;
-       struct yaffs_obj *obj;
+       yaffs_Object *parent = NULL;
+       yaffs_Object *dir = NULL;
+       char *name;
+       int retVal= -1;
 
-       for (i = 0; i < YAFFSFS_N_HANDLES; i++) {
-               obj = yaffsfs_HandleToObject(i);
-               if (obj && obj->my_dev == dev)
-                       return 1;
+       yaffsfs_Lock();
+       parent = yaffsfs_FindDirectory(NULL,path,&name,0);
+       if(parent)
+               dir = yaffs_MknodDirectory(parent,name,mode,0,0);
+       if(dir)
+       {
+               retVal = 0;
        }
-       return 0;
+       else
+       {
+               yaffsfs_SetError(-ENOSPC); // just assume no space for now
+               retVal = -1;
+       }
+
+       yaffsfs_Unlock();
+
+       return retVal;
 }
 
-int yaffs_remount(const YCHAR *path, int force, int read_only)
+int yaffs_mount(const char *path)
 {
-       int retVal = -1;
-       struct yaffs_dev *dev = NULL;
-
-       if (!path) {
-               yaffsfs_SetError(-EFAULT);
-               return -1;
-       }
+       int retVal=-1;
+       int result=YAFFS_FAIL;
+       yaffs_Device *dev=NULL;
+       char *dummy;
 
-       if (yaffsfs_CheckPath(path) < 0) {
-               yaffsfs_SetError(-ENAMETOOLONG);
-               return -1;
-       }
+       T(YAFFS_TRACE_ALWAYS,("yaffs: Mounting %s\n",path));
 
        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);
+       dev = yaffsfs_FindDevice(path,&dummy);
+       if(dev)
+       {
+               if(!dev->isMounted)
+               {
+                       result = yaffs_GutsInitialise(dev);
+                       if(result == YAFFS_FAIL)
+                       {
+                               // todo error - mount failed
+                               yaffsfs_SetError(-ENOMEM);
+                       }
+                       retVal = result ? 0 : -1;
 
-       } else
+               }
+               else
+               {
+                       //todo error - already mounted.
+                       yaffsfs_SetError(-EBUSY);
+               }
+       }
+       else
+       {
+               // todo error - no device
                yaffsfs_SetError(-ENODEV);
-
+       }
        yaffsfs_Unlock();
        return retVal;
 
 }
 
-int yaffs_unmount2(const YCHAR *path, int force)
+int yaffs_unmount(const char *path)
 {
-       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;
-       }
+       int retVal=-1;
+       yaffs_Device *dev=NULL;
+       char *dummy;
 
        yaffsfs_Lock();
-       dev = yaffsfs_FindMountPoint(path);
-       if (dev) {
-               if (dev->is_mounted) {
+       dev = yaffsfs_FindDevice(path,&dummy);
+       if(dev)
+       {
+               if(dev->isMounted)
+               {
+                       int i;
                        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);
+
+                       yaffs_FlushEntireDeviceCache(dev);
+                       yaffs_CheckpointSave(dev);
+
+                       for(i = inUse = 0; i < YAFFSFS_N_HANDLES && !inUse; i++)
+                       {
+                               if(yaffsfs_handle[i].inUse && yaffsfs_handle[i].obj->myDev == dev)
+                               {
+                                       inUse = 1; // the device is in use, can't unmount
+                               }
+                       }
+
+                       if(!inUse)
+                       {
+                               yaffs_Deinitialise(dev);
 
                                retVal = 0;
-                       } else
+                       }
+                       else
+                       {
+                               // todo error can't unmount as files are open
                                yaffsfs_SetError(-EBUSY);
+                       }
 
-               } else
+               }
+               else
+               {
+                       //todo error - not mounted.
                        yaffsfs_SetError(-EINVAL);
 
-       } else
+               }
+       }
+       else
+       {
+               // todo error - no device
                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 yaffs_freespace(const char *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;
-       }
+       loff_t retVal=-1;
+       yaffs_Device *dev=NULL;
+       char *dummy;
 
        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;
+       dev = yaffsfs_FindDevice(path,&dummy);
+       if(dev  && dev->isMounted)
+       {
+               retVal = yaffs_GetNumberOfFreeChunks(dev);
+               retVal *= dev->nDataBytesPerChunk;
 
-       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
+       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;
-       }
+void yaffs_initialise(yaffsfs_DeviceConfiguration *cfgList)
+{
 
-       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;
-       }
+       yaffsfs_DeviceConfiguration *cfg;
 
-       if (retVal < 0)
-               yaffsfs_SetError(-EINVAL);
+       yaffsfs_configurationList = cfgList;
 
-       yaffsfs_Unlock();
-       return retVal;
-}
+       yaffsfs_InitHandles();
 
-void yaffs_add_device(struct yaffs_dev *dev)
-{
-       struct list_head *cfg;
-       /* First check that the device is not in the list. */
+       cfg = yaffsfs_configurationList;
 
-       list_for_each(cfg, &yaffsfs_deviceList) {
-               if (dev == list_entry(cfg, struct yaffs_dev, dev_list))
-                       return;
+       while(cfg && cfg->prefix && cfg->dev)
+       {
+               cfg->dev->isMounted = 0;
+               cfg->dev->removeObjectCallback = yaffsfs_RemoveObjectCallback;
+               cfg++;
        }
-
-       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! */
+//
+// Directory search stuff.
 
-static struct list_head *dev_iterator;
-void yaffs_dev_rewind(void)
-{
-       dev_iterator = yaffsfs_deviceList.next;
-}
+//
+// Directory search context
+//
+// NB this is an opaque structure.
 
-struct yaffs_dev *yaffs_next_dev(void)
-{
-       struct yaffs_dev *retval;
 
-       if (!dev_iterator)
-               return NULL;
-       if (dev_iterator == &yaffsfs_deviceList)
-               return NULL;
+typedef struct
+{
+       __u32 magic;
+       yaffs_dirent de;                /* directory entry being used by this dsc */
+       char name[NAME_MAX+1];          /* name of directory being searched */
+       yaffs_Object *dirObj;           /* ptr to directory being searched */
+       yaffs_Object *nextReturn;       /* obj to be returned by next readddir */
+       int offset;
+       struct list_head others;
+} yaffsfs_DirectorySearchContext;
 
-       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)
+
+static void yaffsfs_SetDirRewound(yaffsfs_DirectorySearchContext *dsc)
 {
-       if (dsc &&
-           dsc->dirObj &&
-           dsc->dirObj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) {
+       if(dsc &&
+          dsc->dirObj &&
+          dsc->dirObj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){
 
-               dsc->offset = 0;
+          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);
+          if( list_empty(&dsc->dirObj->variant.directoryVariant.children)){
+               dsc->nextReturn = NULL;
+          } else {
+               dsc->nextReturn = list_entry(dsc->dirObj->variant.directoryVariant.children.next,
+                                               yaffs_Object,siblings);
+          }
        } else {
                /* Hey someone isn't playing nice! */
        }
 }
 
-static void yaffsfs_DirAdvance(struct yaffsfs_DirSearchContxt *dsc)
+static void yaffsfs_DirAdvance(yaffsfs_DirectorySearchContext *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);
-               }
+       if(dsc &&
+          dsc->dirObj &&
+          dsc->dirObj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){
+
+          if( dsc->nextReturn == NULL ||
+              list_empty(&dsc->dirObj->variant.directoryVariant.children)){
+               dsc->nextReturn = NULL;
+          } else {
+                  struct list_head *next = dsc->nextReturn->siblings.next;
+
+                  if( next == &dsc->dirObj->variant.directoryVariant.children)
+                       dsc->nextReturn = NULL; /* end of list */
+                  else
+                       dsc->nextReturn = list_entry(next,yaffs_Object,siblings);
+          }
        } else {
                /* Hey someone isn't playing nice! */
        }
 }
 
-static void yaffsfs_RemoveObjectCallback(struct yaffs_obj *obj)
+static void yaffsfs_RemoveObjectCallback(yaffs_Object *obj)
 {
 
        struct list_head *i;
-       struct yaffsfs_DirSearchContxt *dsc;
+       yaffsfs_DirectorySearchContext *dsc;
 
        /* if search contexts not initilised then skip */
-       if (!search_contexts.next)
+       if(!search_contexts.next)
                return;
 
-       /* Iterate through the directory search contexts.
+       /* Iteratethrough 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) {
+        list_for_each(i, &search_contexts) {
                if (i) {
-                       dsc = list_entry(i, struct yaffsfs_DirSearchContxt,
-                                        others);
-                       if (dsc->nextReturn == obj)
+                       dsc = list_entry(i, yaffsfs_DirectorySearchContext,others);
+                       if(dsc->nextReturn == obj)
                                yaffsfs_DirAdvance(dsc);
                }
        }
 
 }
 
-yaffs_DIR *yaffs_opendir(const YCHAR *dirname)
+yaffs_DIR *yaffs_opendir(const char *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;
-       }
+       yaffs_Object *obj = NULL;
+       yaffsfs_DirectorySearchContext *dsc = 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];
-               }
+       obj = yaffsfs_FindObject(NULL,dirname,0);
 
-               dir = (yaffs_DIR *) dsc;
+       if(obj && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)
+       {
 
-               if (dsc) {
-                       memset(dsc, 0, sizeof(struct yaffsfs_DirSearchContxt));
-                       dsc->inUse = 1;
+               dsc = YMALLOC(sizeof(yaffsfs_DirectorySearchContext));
+               dir = (yaffs_DIR *)dsc;
+               if(dsc)
+               {
+                       memset(dsc,0,sizeof(yaffsfs_DirectorySearchContext));
+                       dsc->magic = YAFFS_MAGIC;
                        dsc->dirObj = obj;
-                       yaffs_strncpy(dsc->name, dirname, NAME_MAX);
+                       strncpy(dsc->name,dirname,NAME_MAX);
                        INIT_LIST_HEAD(&dsc->others);
 
-                       if (!search_contexts.next)
+                       if(!search_contexts.next)
                                INIT_LIST_HEAD(&search_contexts);
 
-                       list_add(&dsc->others, &search_contexts);
-                       yaffsfs_SetDirRewound(dsc);
-               }
+                       list_add(&dsc->others,&search_contexts);
+                       yaffsfs_SetDirRewound(dsc);             }
 
        }
 
@@ -2918,34 +1295,35 @@ yaffs_DIR *yaffs_opendir(const YCHAR *dirname)
        return dir;
 }
 
-struct yaffs_dirent *yaffs_readdir(yaffs_DIR * dirp)
+struct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp)
 {
-       struct yaffsfs_DirSearchContxt *dsc;
+       yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp;
        struct yaffs_dirent *retVal = NULL;
 
-       dsc = (struct yaffsfs_DirSearchContxt *) dirp;
        yaffsfs_Lock();
 
-       if (dsc && dsc->inUse) {
+       if(dsc && dsc->magic == YAFFS_MAGIC){
                yaffsfs_SetError(0);
-               if (dsc->nextReturn) {
-                       dsc->de.d_ino =
-                           yaffs_get_equivalent_obj(dsc->nextReturn)->obj_id;
+               if(dsc->nextReturn){
+                       dsc->de.d_ino = yaffs_GetEquivalentObject(dsc->nextReturn)->objectId;
                        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"));
+                       yaffs_GetObjectName(dsc->nextReturn,dsc->de.d_name,NAME_MAX);
+                       if(strlen(dsc->de.d_name) == 0)
+                       {
+                               // this should not happen!
+                               strcpy(dsc->de.d_name,"zz");
                        }
                        dsc->de.d_reclen = sizeof(struct yaffs_dirent);
                        retVal = &dsc->de;
                        yaffsfs_DirAdvance(dsc);
                } else
                        retVal = NULL;
-       } else
+       }
+       else
+       {
                yaffsfs_SetError(-EBADF);
+       }
 
        yaffsfs_Unlock();
 
@@ -2953,11 +1331,10 @@ struct yaffs_dirent *yaffs_readdir(yaffs_DIR * dirp)
 
 }
 
+
 void yaffs_rewinddir(yaffs_DIR *dirp)
 {
-       struct yaffsfs_DirSearchContxt *dsc;
-
-       dsc = (struct yaffsfs_DirSearchContxt *) dirp;
+       yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp;
 
        yaffsfs_Lock();
 
@@ -2966,67 +1343,41 @@ void yaffs_rewinddir(yaffs_DIR *dirp)
        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_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp;
 
        yaffsfs_Lock();
-       dsc->inUse = 0;
-       list_del(&dsc->others); /* unhook from list */
+       dsc->magic = 0;
+       list_del(&dsc->others); /* unhook from list */
+       YFREE(dsc);
        yaffsfs_Unlock();
        return 0;
 }
 
-/* End of directory stuff */
+// 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;
-       }
+int yaffs_symlink(const char *oldpath, const char *newpath)
+{
+       yaffs_Object *parent = NULL;
+       yaffs_Object *obj;
+       char *name;
+       int retVal= -1;
+       int mode = 0; // ignore for now
 
        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 if (parent) {
-               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);
+       parent = yaffsfs_FindDirectory(NULL,newpath,&name,0);
+       obj = yaffs_MknodSymLink(parent,name,mode,0,0,oldpath);
+       if(obj)
+       {
+               retVal = 0;
+       }
+       else
+       {
+               yaffsfs_SetError(-ENOSPC); // just assume no space for now
+               retVal = -1;
        }
 
        yaffsfs_Unlock();
@@ -3035,98 +1386,90 @@ int yaffs_symlink(const YCHAR *oldpath, const YCHAR *newpath)
 
 }
 
-int yaffs_readlink(const YCHAR *path, YCHAR *buf, int bufsiz)
+int yaffs_readlink(const char *path, char *buf, int bufsiz)
 {
-       struct yaffs_obj *obj = NULL;
-       struct yaffs_obj *dir = NULL;
-       int retVal = -1;
-       int notDir = 0;
-       int loop = 0;
+       yaffs_Object *obj = NULL;
+       int retVal;
 
-       if (!path || !buf) {
-               yaffsfs_SetError(-EFAULT);
-               return -1;
-       }
 
        yaffsfs_Lock();
 
-       obj = yaffsfs_FindObject(NULL, path, 0, 1, &dir, &notDir, &loop);
+       obj = yaffsfs_FindObject(NULL,path,0);
 
-       if (!dir && notDir)
-               yaffsfs_SetError(-ENOTDIR);
-       else if (loop)
-               yaffsfs_SetError(-ELOOP);
-       else if (!dir || !obj)
+       if(!obj)
+       {
                yaffsfs_SetError(-ENOENT);
-       else if (obj->variant_type != YAFFS_OBJECT_TYPE_SYMLINK)
+               retVal = -1;
+       }
+       else if(obj->variantType != 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 = -1;
+       }
+       else
+       {
+               char *alias = obj->variant.symLinkVariant.alias;
+               memset(buf,0,bufsiz);
+               strncpy(buf,alias,bufsiz - 1);
                retVal = 0;
        }
        yaffsfs_Unlock();
        return retVal;
 }
 
-int yaffs_link(const YCHAR *oldpath, const YCHAR *linkpath)
+int yaffs_link(const char *oldpath, const char *newpath)
 {
-       /* 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;
-       }
+       // Creates a link called newpath to existing oldpath
+       yaffs_Object *obj = NULL;
+       yaffs_Object *target = NULL;
+       int retVal = 0;
 
-       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);
+       obj = yaffsfs_FindObject(NULL,oldpath,0);
+       target = yaffsfs_FindObject(NULL,newpath,0);
 
-       if ((!obj_dir && notDirObj) || (!lnk_dir && notDirLnk))
-               yaffsfs_SetError(-ENOTDIR);
-       else if (objLoop || lnkLoop)
-               yaffsfs_SetError(-ELOOP);
-       else if (!obj_dir || !lnk_dir || !obj)
+       if(!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)
+               retVal = -1;
+       }
+       else if(target)
+       {
                yaffsfs_SetError(-EEXIST);
-       else if (lnk_dir->my_dev != obj->my_dev)
-               yaffsfs_SetError(-EXDEV);
-       else {
-               retVal = yaffsfs_CheckNameLength(newname);
+               retVal = -1;
+       }
+       else
+       {
+               yaffs_Object *newdir = NULL;
+               yaffs_Object *link = NULL;
+
+               char *newname;
 
-               if (retVal == 0) {
-                       lnk = yaffs_link_obj(lnk_dir, newname, obj);
-                       if (lnk)
+               newdir = yaffsfs_FindDirectory(NULL,newpath,&newname,0);
+
+               if(!newdir)
+               {
+                       yaffsfs_SetError(-ENOTDIR);
+                       retVal = -1;
+               }
+               else if(newdir->myDev != obj->myDev)
+               {
+                       yaffsfs_SetError(-EXDEV);
+                       retVal = -1;
+               }
+               if(newdir && strlen(newname) > 0)
+               {
+                       link = yaffs_Link(newdir,newname,obj);
+                       if(link)
                                retVal = 0;
-                       else {
+                       else
+                       {
                                yaffsfs_SetError(-ENOSPC);
                                retVal = -1;
                        }
+
                }
        }
        yaffsfs_Unlock();
@@ -3134,84 +1477,34 @@ int yaffs_link(const YCHAR *oldpath, const YCHAR *linkpath)
        return retVal;
 }
 
-int yaffs_mknod(const YCHAR *pathname, mode_t mode, dev_t dev)
-{
-       pathname = pathname;
-       mode = mode;
-       dev = 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_mknod(const char *pathname, mode_t mode, dev_t dev);
 
-int yaffs_dump_dev(const YCHAR *path)
+int yaffs_DumpDevStruct(const char *path)
 {
-#if 1
-       path = path;
-#else
-       YCHAR *rest;
+       char *rest;
 
-       struct yaffs_obj *obj = yaffsfs_FindRoot(path, &rest);
+       yaffs_Object *obj = yaffsfs_FindRoot(path,&rest);
 
-       if (obj) {
-               struct yaffs_dev *dev = obj->my_dev;
+       if(obj)
+       {
+               yaffs_Device *dev = obj->myDev;
 
                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);
+                          "nPageWrites.......... %d\n"
+                          "nPageReads........... %d\n"
+                          "nBlockErasures....... %d\n"
+                          "nGCCopies............ %d\n"
+                          "garbageCollections... %d\n"
+                          "passiveGarbageColl'ns %d\n"
+                          "\n",
+                               dev->nPageWrites,
+                               dev->nPageReads,
+                               dev->nBlockErasures,
+                               dev->nGCCopies,
+                               dev->garbageCollections,
+                               dev->passiveGarbageCollections
+               );
 
        }
-#endif
        return 0;
 }