140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project/*
240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * YAFFS: Yet another FFS. A NAND-flash specific file system.
340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * yaffsfs.c  The interface functions for using YAFFS via a "direct" interface.
440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * Copyright (C) 2002 Aleph One Ltd.
640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * Created by Charles Manning <charles@aleph1.co.uk>
840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * This program is free software; you can redistribute it and/or modify
1040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * it under the terms of the GNU General Public License version 2 as
1140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * published by the Free Software Foundation.
1240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
1340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project */
1440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
1540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include "yaffsfs.h"
1640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include "yaffs_guts.h"
1740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include "yaffscfg.h"
1840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <string.h> // for memset
1940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include "yportenv.h"
2040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
2140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#define YAFFSFS_MAX_SYMLINK_DEREFERENCES 5
2240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
2340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#ifndef NULL
2440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#define NULL ((void *)0)
2540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#endif
2640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
2740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
2840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectconst char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.13 2006/10/03 10:13:03 charles Exp $";
2940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
3040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// configurationList is the list of devices that are supported
3140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic yaffsfs_DeviceConfiguration *yaffsfs_configurationList;
3240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
3340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
3440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project/* Some forward references */
3540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic yaffs_Object *yaffsfs_FindObject(yaffs_Object *relativeDirectory, const char *path, int symDepth);
3640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic void yaffsfs_RemoveObjectCallback(yaffs_Object *obj);
3740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
3840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
3940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// Handle management.
4040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project//
4140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
4240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projecttypedef struct
4340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
4440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	__u8  inUse:1;		// this handle is in use
4540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	__u8  readOnly:1;	// this handle is read only
4640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	__u8  append:1;		// append only
4740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	__u8  exclusive:1;	// exclusive
4840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	__u32 position;		// current position in file
4940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *obj;	// the object
5040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}yaffsfs_Handle;
5140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
5240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
5340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic yaffsfs_Handle yaffsfs_handle[YAFFSFS_N_HANDLES];
5440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
5540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// yaffsfs_InitHandle
5640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project/// Inilitalise handles on start-up.
5740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project//
5840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int yaffsfs_InitHandles(void)
5940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
6040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int i;
6140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	for(i = 0; i < YAFFSFS_N_HANDLES; i++)
6240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
6340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_handle[i].inUse = 0;
6440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_handle[i].obj = NULL;
6540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
6640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return 0;
6740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
6840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
6940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectyaffsfs_Handle *yaffsfs_GetHandlePointer(int h)
7040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
7140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(h < 0 || h >= YAFFSFS_N_HANDLES)
7240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
7340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		return NULL;
7440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
7540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
7640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return &yaffsfs_handle[h];
7740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
7840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
7940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectyaffs_Object *yaffsfs_GetHandleObject(int handle)
8040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
8140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Handle *h = yaffsfs_GetHandlePointer(handle);
8240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
8340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(h && h->inUse)
8440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
8540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		return h->obj;
8640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
8740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
8840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return NULL;
8940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
9040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
9140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
9240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project//yaffsfs_GetHandle
9340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// Grab a handle (when opening a file)
9440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project//
9540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
9640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int yaffsfs_GetHandle(void)
9740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
9840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int i;
9940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Handle *h;
10040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
10140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	for(i = 0; i < YAFFSFS_N_HANDLES; i++)
10240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
10340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		h = yaffsfs_GetHandlePointer(i);
10440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(!h)
10540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
10640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			// todo bug: should never happen
10740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
10840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(!h->inUse)
10940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
11040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			memset(h,0,sizeof(yaffsfs_Handle));
11140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			h->inUse=1;
11240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			return i;
11340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
11440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
11540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return -1;
11640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
11740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
11840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// yaffs_PutHandle
11940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// Let go of a handle (when closing a file)
12040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project//
12140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int yaffsfs_PutHandle(int handle)
12240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
12340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Handle *h = yaffsfs_GetHandlePointer(handle);
12440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
12540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(h)
12640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
12740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		h->inUse = 0;
12840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		h->obj = NULL;
12940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
13040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return 0;
13140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
13240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
13340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
13440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
13540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// Stuff to search for a directory from a path
13640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
13740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
13840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffsfs_Match(char a, char b)
13940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
14040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	// case sensitive
14140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return (a == b);
14240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
14340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
14440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// yaffsfs_FindDevice
14540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// yaffsfs_FindRoot
14640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// Scan the configuration list to find the root.
14740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// Curveballs: Should match paths that end in '/' too
14840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// Curveball2 Might have "/x/ and "/x/y". Need to return the longest match
14940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic yaffs_Device *yaffsfs_FindDevice(const char *path, char **restOfPath)
15040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
15140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_DeviceConfiguration *cfg = yaffsfs_configurationList;
15240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	const char *leftOver;
15340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	const char *p;
15440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Device *retval = NULL;
15540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int thisMatchLength;
15640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int longestMatch = -1;
15740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
15840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	// Check all configs, choose the one that:
15940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	// 1) Actually matches a prefix (ie /a amd /abc will not match
16040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	// 2) Matches the longest.
16140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	while(cfg && cfg->prefix && cfg->dev)
16240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
16340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		leftOver = path;
16440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		p = cfg->prefix;
16540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		thisMatchLength = 0;
16640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
16740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		while(*p &&  //unmatched part of prefix
16840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		      strcmp(p,"/") && // the rest of the prefix is not / (to catch / at end)
16940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		      *leftOver &&
17040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		      yaffsfs_Match(*p,*leftOver))
17140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
17240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			p++;
17340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			leftOver++;
17440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			thisMatchLength++;
17540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
17640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if((!*p || strcmp(p,"/") == 0) &&      // end of prefix
17740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		   (!*leftOver || *leftOver == '/') && // no more in this path name part
17840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		   (thisMatchLength > longestMatch))
17940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
18040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			// Matched prefix
18140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			*restOfPath = (char *)leftOver;
18240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			retval = cfg->dev;
18340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			longestMatch = thisMatchLength;
18440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
18540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		cfg++;
18640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
18740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return retval;
18840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
18940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
19040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic yaffs_Object *yaffsfs_FindRoot(const char *path, char **restOfPath)
19140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
19240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
19340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Device *dev;
19440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
19540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	dev= yaffsfs_FindDevice(path,restOfPath);
19640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(dev && dev->isMounted)
19740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
19840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		return dev->rootDir;
19940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
20040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return NULL;
20140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
20240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
20340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic yaffs_Object *yaffsfs_FollowLink(yaffs_Object *obj,int symDepth)
20440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
20540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
20640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	while(obj && obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
20740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
20840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		char *alias = obj->variant.symLinkVariant.alias;
20940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
21040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(*alias == '/')
21140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
21240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			// Starts with a /, need to scan from root up
21340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			obj = yaffsfs_FindObject(NULL,alias,symDepth++);
21440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
21540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		else
21640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
21740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			// Relative to here, so use the parent of the symlink as a start
21840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			obj = yaffsfs_FindObject(obj->parent,alias,symDepth++);
21940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
22040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
22140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return obj;
22240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
22340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
22440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
22540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// yaffsfs_FindDirectory
22640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// Parse a path to determine the directory and the name within the directory.
22740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project//
22840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// eg. "/data/xx/ff" --> puts name="ff" and returns the directory "/data/xx"
22940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic yaffs_Object *yaffsfs_DoFindDirectory(yaffs_Object *startDir,const char *path,char **name,int symDepth)
23040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
23140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *dir;
23240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	char *restOfPath;
23340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	char str[YAFFS_MAX_NAME_LENGTH+1];
23440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int i;
23540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
23640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(symDepth > YAFFSFS_MAX_SYMLINK_DEREFERENCES)
23740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
23840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		return NULL;
23940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
24040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
24140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(startDir)
24240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
24340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		dir = startDir;
24440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		restOfPath = (char *)path;
24540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
24640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
24740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
24840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		dir = yaffsfs_FindRoot(path,&restOfPath);
24940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
25040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
25140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	while(dir)
25240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
25340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// parse off /.
25440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// curve ball: also throw away surplus '/'
25540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// eg. "/ram/x////ff" gets treated the same as "/ram/x/ff"
25640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		while(*restOfPath == '/')
25740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
25840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			restOfPath++; // get rid of '/'
25940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
26040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
26140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		*name = restOfPath;
26240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		i = 0;
26340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
26440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		while(*restOfPath && *restOfPath != '/')
26540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
26640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if (i < YAFFS_MAX_NAME_LENGTH)
26740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
26840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				str[i] = *restOfPath;
26940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				str[i+1] = '\0';
27040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				i++;
27140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
27240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			restOfPath++;
27340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
27440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
27540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(!*restOfPath)
27640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
27740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			// got to the end of the string
27840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			return dir;
27940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
28040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		else
28140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
28240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(strcmp(str,".") == 0)
28340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
28440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				// Do nothing
28540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
28640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			else if(strcmp(str,"..") == 0)
28740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
28840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				dir = dir->parent;
28940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
29040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			else
29140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
29240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				dir = yaffs_FindObjectByName(dir,str);
29340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
29440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				while(dir && dir->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
29540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				{
29640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
29740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					dir = yaffsfs_FollowLink(dir,symDepth);
29840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
29940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				}
30040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
30140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				if(dir && dir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
30240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				{
30340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					dir = NULL;
30440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				}
30540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
30640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
30740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
30840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	// directory did not exist.
30940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return NULL;
31040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
31140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
31240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic yaffs_Object *yaffsfs_FindDirectory(yaffs_Object *relativeDirectory,const char *path,char **name,int symDepth)
31340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
31440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return yaffsfs_DoFindDirectory(relativeDirectory,path,name,symDepth);
31540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
31640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
31740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// yaffsfs_FindObject turns a path for an existing object into the object
31840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project//
31940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic yaffs_Object *yaffsfs_FindObject(yaffs_Object *relativeDirectory, const char *path,int symDepth)
32040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
32140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *dir;
32240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	char *name;
32340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
32440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	dir = yaffsfs_FindDirectory(relativeDirectory,path,&name,symDepth);
32540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
32640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(dir && *name)
32740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
32840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		return yaffs_FindObjectByName(dir,name);
32940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
33040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
33140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return dir;
33240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
33340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
33440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
33540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
33640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_open(const char *path, int oflag, int mode)
33740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
33840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *obj = NULL;
33940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *dir = NULL;
34040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	char *name;
34140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int handle = -1;
34240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Handle *h = NULL;
34340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int alreadyOpen = 0;
34440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int alreadyExclusive = 0;
34540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int openDenied = 0;
34640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int symDepth = 0;
34740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int errorReported = 0;
34840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
34940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int i;
35040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
35140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
35240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	// todo sanity check oflag (eg. can't have O_TRUNC without WRONLY or RDWR
35340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
35440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
35540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
35640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
35740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	handle = yaffsfs_GetHandle();
35840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
35940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(handle >= 0)
36040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
36140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
36240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		h = yaffsfs_GetHandlePointer(handle);
36340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
36440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
36540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// try to find the exisiting object
36640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		obj = yaffsfs_FindObject(NULL,path,0);
36740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
36840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(obj && obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
36940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
37040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
37140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			obj = yaffsfs_FollowLink(obj,symDepth++);
37240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
37340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
37440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(obj)
37540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
37640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			// Check if the object is already in use
37740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			alreadyOpen = alreadyExclusive = 0;
37840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
37940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			for(i = 0; i <= YAFFSFS_N_HANDLES; i++)
38040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
38140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
38240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				if(i != handle &&
38340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				   yaffsfs_handle[i].inUse &&
38440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				    obj == yaffsfs_handle[i].obj)
38540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				 {
38640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				 	alreadyOpen = 1;
38740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					if(yaffsfs_handle[i].exclusive)
38840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					{
38940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						alreadyExclusive = 1;
39040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					}
39140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				 }
39240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
39340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
39440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(((oflag & O_EXCL) && alreadyOpen) || alreadyExclusive)
39540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
39640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				openDenied = 1;
39740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
39840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
39940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			// Open should fail if O_CREAT and O_EXCL are specified
40040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if((oflag & O_EXCL) && (oflag & O_CREAT))
40140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
40240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				openDenied = 1;
40340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				yaffsfs_SetError(-EEXIST);
40440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				errorReported = 1;
40540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
40640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
40740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			// Check file permissions
40840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if( (oflag & (O_RDWR | O_WRONLY)) == 0 &&     // ie O_RDONLY
40940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			   !(obj->yst_mode & S_IREAD))
41040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
41140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				openDenied = 1;
41240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
41340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
41440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if( (oflag & O_RDWR) &&
41540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			   !(obj->yst_mode & S_IREAD))
41640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
41740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				openDenied = 1;
41840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
41940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
42040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if( (oflag & (O_RDWR | O_WRONLY)) &&
42140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			   !(obj->yst_mode & S_IWRITE))
42240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
42340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				openDenied = 1;
42440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
42540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
42640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
42740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
42840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		else if((oflag & O_CREAT))
42940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
43040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			// Let's see if we can create this file
43140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			dir = yaffsfs_FindDirectory(NULL,path,&name,0);
43240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(dir)
43340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
43440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				obj = yaffs_MknodFile(dir,name,mode,0,0);
43540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
43640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			else
43740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
43840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				yaffsfs_SetError(-ENOTDIR);
43940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
44040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
44140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
44240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(obj && !openDenied)
44340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
44440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			h->obj = obj;
44540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			h->inUse = 1;
44640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	    	h->readOnly = (oflag & (O_WRONLY | O_RDWR)) ? 0 : 1;
44740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			h->append =  (oflag & O_APPEND) ? 1 : 0;
44840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			h->exclusive = (oflag & O_EXCL) ? 1 : 0;
44940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			h->position = 0;
45040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
45140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			obj->inUse++;
45240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if((oflag & O_TRUNC) && !h->readOnly)
45340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
45440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				//todo truncate
45540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				yaffs_ResizeFile(obj,0);
45640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
45740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
45840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
45940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		else
46040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
46140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			yaffsfs_PutHandle(handle);
46240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(!errorReported)
46340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
46440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				yaffsfs_SetError(-EACCESS);
46540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				errorReported = 1;
46640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
46740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			handle = -1;
46840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
46940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
47040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
47140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
47240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
47340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
47440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return handle;
47540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
47640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
47740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_close(int fd)
47840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
47940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Handle *h = NULL;
48040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int retVal = 0;
48140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
48240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
48340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
48440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	h = yaffsfs_GetHandlePointer(fd);
48540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
48640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(h && h->inUse)
48740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
48840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// clean up
48940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffs_FlushFile(h->obj,1);
49040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		h->obj->inUse--;
49140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(h->obj->inUse <= 0 && h->obj->unlinked)
49240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
49340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			yaffs_DeleteFile(h->obj);
49440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
49540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_PutHandle(fd);
49640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = 0;
49740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
49840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
49940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
50040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// bad handle
50140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-EBADF);
50240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = -1;
50340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
50440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
50540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
50640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
50740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return retVal;
50840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
50940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
51040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_read(int fd, void *buf, unsigned int nbyte)
51140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
51240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Handle *h = NULL;
51340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *obj = NULL;
51440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int pos = 0;
51540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int nRead = -1;
51640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int maxRead;
51740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
51840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
51940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	h = yaffsfs_GetHandlePointer(fd);
52040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	obj = yaffsfs_GetHandleObject(fd);
52140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
52240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(!h || !obj)
52340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
52440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// bad handle
52540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-EBADF);
52640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
52740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else if( h && obj)
52840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
52940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		pos=  h->position;
53040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(yaffs_GetObjectFileLength(obj) > pos)
53140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
53240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			maxRead = yaffs_GetObjectFileLength(obj) - pos;
53340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
53440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		else
53540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
53640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			maxRead = 0;
53740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
53840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
53940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(nbyte > maxRead)
54040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
54140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			nbyte = maxRead;
54240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
54340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
54440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
54540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(nbyte > 0)
54640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
54740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			nRead = yaffs_ReadDataFromFile(obj,buf,pos,nbyte);
54840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(nRead >= 0)
54940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
55040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				h->position = pos + nRead;
55140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
55240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			else
55340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
55440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				//todo error
55540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
55640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
55740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		else
55840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
55940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			nRead = 0;
56040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
56140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
56240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
56340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
56440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
56540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
56640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
56740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return (nRead >= 0) ? nRead : -1;
56840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
56940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
57040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
57140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_write(int fd, const void *buf, unsigned int nbyte)
57240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
57340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Handle *h = NULL;
57440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *obj = NULL;
57540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int pos = 0;
57640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int nWritten = -1;
57740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int writeThrough = 0;
57840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
57940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
58040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	h = yaffsfs_GetHandlePointer(fd);
58140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	obj = yaffsfs_GetHandleObject(fd);
58240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
58340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(!h || !obj)
58440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
58540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// bad handle
58640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-EBADF);
58740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
58840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else if( h && obj && h->readOnly)
58940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
59040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// todo error
59140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
59240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else if( h && obj)
59340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
59440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(h->append)
59540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
59640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			pos =  yaffs_GetObjectFileLength(obj);
59740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
59840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		else
59940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
60040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			pos = h->position;
60140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
60240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
60340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		nWritten = yaffs_WriteDataToFile(obj,buf,pos,nbyte,writeThrough);
60440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
60540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(nWritten >= 0)
60640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
60740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			h->position = pos + nWritten;
60840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
60940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		else
61040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
61140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			//todo error
61240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
61340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
61440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
61540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
61640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
61740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
61840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
61940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return (nWritten >= 0) ? nWritten : -1;
62040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
62140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
62240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
62340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_truncate(int fd, off_t newSize)
62440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
62540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Handle *h = NULL;
62640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *obj = NULL;
62740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int result = 0;
62840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
62940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
63040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	h = yaffsfs_GetHandlePointer(fd);
63140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	obj = yaffsfs_GetHandleObject(fd);
63240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
63340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(!h || !obj)
63440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
63540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// bad handle
63640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-EBADF);
63740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
63840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
63940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
64040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// resize the file
64140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		result = yaffs_ResizeFile(obj,newSize);
64240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
64340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
64440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
64540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
64640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return (result) ? 0 : -1;
64740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
64840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
64940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
65040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectoff_t yaffs_lseek(int fd, off_t offset, int whence)
65140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
65240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Handle *h = NULL;
65340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *obj = NULL;
65440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int pos = -1;
65540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int fSize = -1;
65640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
65740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
65840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	h = yaffsfs_GetHandlePointer(fd);
65940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	obj = yaffsfs_GetHandleObject(fd);
66040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
66140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(!h || !obj)
66240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
66340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// bad handle
66440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-EBADF);
66540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
66640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else if(whence == SEEK_SET)
66740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
66840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(offset >= 0)
66940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
67040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			pos = offset;
67140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
67240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
67340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else if(whence == SEEK_CUR)
67440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
67540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if( (h->position + offset) >= 0)
67640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
67740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			pos = (h->position + offset);
67840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
67940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
68040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else if(whence == SEEK_END)
68140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
68240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		fSize = yaffs_GetObjectFileLength(obj);
68340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(fSize >= 0 && (fSize + offset) >= 0)
68440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
68540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			pos = fSize + offset;
68640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
68740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
68840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
68940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(pos >= 0)
69040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
69140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		h->position = pos;
69240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
69340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
69440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
69540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// todo error
69640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
69740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
69840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
69940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
70040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
70140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return pos;
70240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
70340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
70440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
70540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffsfs_DoUnlink(const char *path,int isDirectory)
70640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
70740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *dir = NULL;
70840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *obj = NULL;
70940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	char *name;
71040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int result = YAFFS_FAIL;
71140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
71240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
71340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
71440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	obj = yaffsfs_FindObject(NULL,path,0);
71540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	dir = yaffsfs_FindDirectory(NULL,path,&name,0);
71640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(!dir)
71740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
71840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-ENOTDIR);
71940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
72040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else if(!obj)
72140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
72240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-ENOENT);
72340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
72440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else if(!isDirectory && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)
72540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
72640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-EISDIR);
72740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
72840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else if(isDirectory && obj->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
72940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
73040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-ENOTDIR);
73140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
73240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else if(isDirectory && obj->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
73340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
73440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-ENOTDIR);
73540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
73640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
73740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
73840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		result = yaffs_Unlink(dir,name);
73940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
74040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(result == YAFFS_FAIL && isDirectory)
74140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
74240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			yaffsfs_SetError(-ENOTEMPTY);
74340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
74440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
74540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
74640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
74740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
74840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	// todo error
74940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
75040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return (result == YAFFS_FAIL) ? -1 : 0;
75140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
75240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_rmdir(const char *path)
75340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
75440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return yaffsfs_DoUnlink(path,1);
75540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
75640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
75740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_unlink(const char *path)
75840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
75940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return yaffsfs_DoUnlink(path,0);
76040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
76140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
76240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_rename(const char *oldPath, const char *newPath)
76340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
76440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *olddir = NULL;
76540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *newdir = NULL;
76640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *obj = NULL;
76740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	char *oldname;
76840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	char *newname;
76940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int result= YAFFS_FAIL;
77040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int renameAllowed = 1;
77140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
77240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
77340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
77440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	olddir = yaffsfs_FindDirectory(NULL,oldPath,&oldname,0);
77540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	newdir = yaffsfs_FindDirectory(NULL,newPath,&newname,0);
77640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	obj = yaffsfs_FindObject(NULL,oldPath,0);
77740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
77840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(!olddir || !newdir || !obj)
77940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
78040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// bad file
78140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-EBADF);
78240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		renameAllowed = 0;
78340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
78440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else if(olddir->myDev != newdir->myDev)
78540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
78640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// oops must be on same device
78740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// todo error
78840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-EXDEV);
78940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		renameAllowed = 0;
79040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
79140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else if(obj && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)
79240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
79340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// It is a directory, check that it is not being renamed to
79440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// being its own decendent.
79540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// Do this by tracing from the new directory back to the root, checking for obj
79640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
79740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffs_Object *xx = newdir;
79840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
79940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		while( renameAllowed && xx)
80040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
80140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(xx == obj)
80240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
80340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				renameAllowed = 0;
80440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
80540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			xx = xx->parent;
80640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
80740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(!renameAllowed) yaffsfs_SetError(-EACCESS);
80840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
80940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
81040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(renameAllowed)
81140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
81240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		result = yaffs_RenameObject(olddir,oldname,newdir,newname);
81340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
81440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
81540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
81640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
81740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return (result == YAFFS_FAIL) ? -1 : 0;
81840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
81940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
82040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
82140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int yaffsfs_DoStat(yaffs_Object *obj,struct yaffs_stat *buf)
82240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
82340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int retVal = -1;
82440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
82540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(obj)
82640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
82740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		obj = yaffs_GetEquivalentObject(obj);
82840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
82940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
83040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(obj && buf)
83140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
83240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    	buf->st_dev = (int)obj->myDev->genericDevice;
83340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    	buf->st_ino = obj->objectId;
83440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    	buf->st_mode = obj->yst_mode & ~S_IFMT; // clear out file type bits
83540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
83640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)
83740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
83840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			buf->st_mode |= S_IFDIR;
83940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
84040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		else if(obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
84140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
84240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			buf->st_mode |= S_IFLNK;
84340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
84440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		else if(obj->variantType == YAFFS_OBJECT_TYPE_FILE)
84540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
84640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			buf->st_mode |= S_IFREG;
84740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
84840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
84940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    	buf->st_nlink = yaffs_GetObjectLinkCount(obj);
85040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    	buf->st_uid = 0;
85140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    	buf->st_gid = 0;;
85240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    	buf->st_rdev = obj->yst_rdev;
85340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    	buf->st_size = yaffs_GetObjectFileLength(obj);
85440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		buf->st_blksize = obj->myDev->nDataBytesPerChunk;
85540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    	buf->st_blocks = (buf->st_size + buf->st_blksize -1)/buf->st_blksize;
85640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    	buf->yst_atime = obj->yst_atime;
85740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    	buf->yst_ctime = obj->yst_ctime;
85840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    	buf->yst_mtime = obj->yst_mtime;
85940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = 0;
86040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
86140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return retVal;
86240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
86340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
86440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int yaffsfs_DoStatOrLStat(const char *path, struct yaffs_stat *buf,int doLStat)
86540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
86640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *obj;
86740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
86840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int retVal = -1;
86940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
87040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
87140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	obj = yaffsfs_FindObject(NULL,path,0);
87240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
87340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(!doLStat && obj)
87440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
87540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		obj = yaffsfs_FollowLink(obj,0);
87640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
87740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
87840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(obj)
87940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
88040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = yaffsfs_DoStat(obj,buf);
88140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
88240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
88340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
88440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// todo error not found
88540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-ENOENT);
88640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
88740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
88840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
88940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
89040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return retVal;
89140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
89240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
89340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
89440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_stat(const char *path, struct yaffs_stat *buf)
89540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
89640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return yaffsfs_DoStatOrLStat(path,buf,0);
89740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
89840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
89940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_lstat(const char *path, struct yaffs_stat *buf)
90040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
90140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return yaffsfs_DoStatOrLStat(path,buf,1);
90240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
90340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
90440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_fstat(int fd, struct yaffs_stat *buf)
90540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
90640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *obj;
90740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
90840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int retVal = -1;
90940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
91040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
91140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	obj = yaffsfs_GetHandleObject(fd);
91240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
91340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(obj)
91440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
91540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = yaffsfs_DoStat(obj,buf);
91640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
91740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
91840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
91940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// bad handle
92040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-EBADF);
92140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
92240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
92340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
92440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
92540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return retVal;
92640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
92740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
92840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int yaffsfs_DoChMod(yaffs_Object *obj,mode_t mode)
92940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
93040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int result;
93140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
93240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(obj)
93340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
93440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		obj = yaffs_GetEquivalentObject(obj);
93540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
93640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
93740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(obj)
93840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
93940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		obj->yst_mode = mode;
94040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		obj->dirty = 1;
94140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		result = yaffs_FlushFile(obj,0);
94240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
94340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
94440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return result == YAFFS_OK ? 0 : -1;
94540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
94640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
94740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
94840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_chmod(const char *path, mode_t mode)
94940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
95040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *obj;
95140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
95240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int retVal = -1;
95340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
95440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
95540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	obj = yaffsfs_FindObject(NULL,path,0);
95640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
95740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(obj)
95840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
95940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = yaffsfs_DoChMod(obj,mode);
96040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
96140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
96240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
96340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// todo error not found
96440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-ENOENT);
96540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
96640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
96740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
96840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
96940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return retVal;
97040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
97140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
97240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
97340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
97440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_fchmod(int fd, mode_t mode)
97540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
97640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *obj;
97740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
97840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int retVal = -1;
97940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
98040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
98140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	obj = yaffsfs_GetHandleObject(fd);
98240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
98340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(obj)
98440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
98540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = yaffsfs_DoChMod(obj,mode);
98640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
98740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
98840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
98940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// bad handle
99040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-EBADF);
99140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
99240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
99340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
99440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
99540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return retVal;
99640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
99740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
99840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
99940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_mkdir(const char *path, mode_t mode)
100040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
100140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *parent = NULL;
100240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *dir = NULL;
100340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	char *name;
100440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int retVal= -1;
100540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
100640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
100740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	parent = yaffsfs_FindDirectory(NULL,path,&name,0);
100840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(parent)
100940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		dir = yaffs_MknodDirectory(parent,name,mode,0,0);
101040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(dir)
101140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
101240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = 0;
101340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
101440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
101540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
101640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-ENOSPC); // just assume no space for now
101740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = -1;
101840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
101940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
102040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
102140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
102240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return retVal;
102340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
102440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
102540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_mount(const char *path)
102640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
102740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int retVal=-1;
102840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int result=YAFFS_FAIL;
102940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Device *dev=NULL;
103040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	char *dummy;
103140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
103240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	T(YAFFS_TRACE_ALWAYS,("yaffs: Mounting %s\n",path));
103340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
103440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
103540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	dev = yaffsfs_FindDevice(path,&dummy);
103640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(dev)
103740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
103840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(!dev->isMounted)
103940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
104040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			result = yaffs_GutsInitialise(dev);
104140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(result == YAFFS_FAIL)
104240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
104340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				// todo error - mount failed
104440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				yaffsfs_SetError(-ENOMEM);
104540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
104640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			retVal = result ? 0 : -1;
104740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
104840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
104940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		else
105040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
105140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			//todo error - already mounted.
105240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			yaffsfs_SetError(-EBUSY);
105340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
105440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
105540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
105640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
105740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// todo error - no device
105840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-ENODEV);
105940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
106040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
106140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return retVal;
106240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
106340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
106440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
106540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_unmount(const char *path)
106640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
106740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int retVal=-1;
106840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Device *dev=NULL;
106940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	char *dummy;
107040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
107140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
107240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	dev = yaffsfs_FindDevice(path,&dummy);
107340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(dev)
107440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
107540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(dev->isMounted)
107640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
107740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			int i;
107840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			int inUse;
107940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
108040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			yaffs_FlushEntireDeviceCache(dev);
108140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			yaffs_CheckpointSave(dev);
108240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
108340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			for(i = inUse = 0; i < YAFFSFS_N_HANDLES && !inUse; i++)
108440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
108540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				if(yaffsfs_handle[i].inUse && yaffsfs_handle[i].obj->myDev == dev)
108640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				{
108740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					inUse = 1; // the device is in use, can't unmount
108840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				}
108940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
109040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
109140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(!inUse)
109240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
109340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				yaffs_Deinitialise(dev);
109440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
109540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				retVal = 0;
109640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
109740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			else
109840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
109940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				// todo error can't unmount as files are open
110040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				yaffsfs_SetError(-EBUSY);
110140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
110240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
110340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
110440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		else
110540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
110640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			//todo error - not mounted.
110740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			yaffsfs_SetError(-EINVAL);
110840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
110940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
111040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
111140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
111240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
111340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// todo error - no device
111440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-ENODEV);
111540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
111640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
111740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return retVal;
111840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
111940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
112040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
112140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectloff_t yaffs_freespace(const char *path)
112240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
112340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	loff_t retVal=-1;
112440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Device *dev=NULL;
112540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	char *dummy;
112640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
112740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
112840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	dev = yaffsfs_FindDevice(path,&dummy);
112940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(dev  && dev->isMounted)
113040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
113140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = yaffs_GetNumberOfFreeChunks(dev);
113240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal *= dev->nDataBytesPerChunk;
113340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
113440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
113540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
113640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
113740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-EINVAL);
113840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
113940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
114040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
114140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return retVal;
114240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
114340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
114440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
114540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
114640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectvoid yaffs_initialise(yaffsfs_DeviceConfiguration *cfgList)
114740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
114840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
114940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_DeviceConfiguration *cfg;
115040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
115140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_configurationList = cfgList;
115240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
115340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_InitHandles();
115440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
115540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	cfg = yaffsfs_configurationList;
115640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
115740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	while(cfg && cfg->prefix && cfg->dev)
115840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
115940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		cfg->dev->isMounted = 0;
116040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		cfg->dev->removeObjectCallback = yaffsfs_RemoveObjectCallback;
116140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		cfg++;
116240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
116340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
116440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
116540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
116640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
116740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
116840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project//
116940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// Directory search stuff.
117040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
117140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project//
117240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// Directory search context
117340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project//
117440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// NB this is an opaque structure.
117540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
117640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
117740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projecttypedef struct
117840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
117940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	__u32 magic;
118040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_dirent de;		/* directory entry being used by this dsc */
118140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	char name[NAME_MAX+1];		/* name of directory being searched */
118240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *dirObj;		/* ptr to directory being searched */
118340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *nextReturn;	/* obj to be returned by next readddir */
118440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int offset;
118540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	struct list_head others;
118640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project} yaffsfs_DirectorySearchContext;
118740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
118840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
118940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
119040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic struct list_head search_contexts;
119140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
119240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
119340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic void yaffsfs_SetDirRewound(yaffsfs_DirectorySearchContext *dsc)
119440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
119540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(dsc &&
119640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	   dsc->dirObj &&
119740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	   dsc->dirObj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){
119840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
119940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	   dsc->offset = 0;
120040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
120140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	   if( list_empty(&dsc->dirObj->variant.directoryVariant.children)){
120240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	   	dsc->nextReturn = NULL;
120340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	   } else {
120440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	      	dsc->nextReturn = list_entry(dsc->dirObj->variant.directoryVariant.children.next,
120540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						yaffs_Object,siblings);
120640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	   }
120740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	} else {
120840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		/* Hey someone isn't playing nice! */
120940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
121040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
121140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
121240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic void yaffsfs_DirAdvance(yaffsfs_DirectorySearchContext *dsc)
121340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
121440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(dsc &&
121540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	   dsc->dirObj &&
121640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	   dsc->dirObj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){
121740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
121840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	   if( dsc->nextReturn == NULL ||
121940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	       list_empty(&dsc->dirObj->variant.directoryVariant.children)){
122040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	   	dsc->nextReturn = NULL;
122140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	   } else {
122240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		   struct list_head *next = dsc->nextReturn->siblings.next;
122340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
122440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		   if( next == &dsc->dirObj->variant.directoryVariant.children)
122540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	   		dsc->nextReturn = NULL; /* end of list */
122640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	   	   else
122740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		   	dsc->nextReturn = list_entry(next,yaffs_Object,siblings);
122840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	   }
122940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	} else {
123040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		/* Hey someone isn't playing nice! */
123140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
123240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
123340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
123440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic void yaffsfs_RemoveObjectCallback(yaffs_Object *obj)
123540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
123640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
123740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	struct list_head *i;
123840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_DirectorySearchContext *dsc;
123940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
124040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	/* if search contexts not initilised then skip */
124140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(!search_contexts.next)
124240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		return;
124340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
124440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	/* Iteratethrough the directory search contexts.
124540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	 * If any are the one being removed, then advance the dsc to
124640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	 * the next one to prevent a hanging ptr.
124740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	 */
124840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	 list_for_each(i, &search_contexts) {
124940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if (i) {
125040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			dsc = list_entry(i, yaffsfs_DirectorySearchContext,others);
125140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(dsc->nextReturn == obj)
125240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				yaffsfs_DirAdvance(dsc);
125340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
125440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
125540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
125640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
125740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
125840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectyaffs_DIR *yaffs_opendir(const char *dirname)
125940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
126040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_DIR *dir = NULL;
126140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project 	yaffs_Object *obj = NULL;
126240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_DirectorySearchContext *dsc = NULL;
126340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
126440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
126540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
126640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	obj = yaffsfs_FindObject(NULL,dirname,0);
126740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
126840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(obj && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)
126940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
127040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
127140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		dsc = YMALLOC(sizeof(yaffsfs_DirectorySearchContext));
127240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		dir = (yaffs_DIR *)dsc;
127340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(dsc)
127440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
127540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			memset(dsc,0,sizeof(yaffsfs_DirectorySearchContext));
127640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			dsc->magic = YAFFS_MAGIC;
127740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			dsc->dirObj = obj;
127840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			strncpy(dsc->name,dirname,NAME_MAX);
127940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			INIT_LIST_HEAD(&dsc->others);
128040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
128140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(!search_contexts.next)
128240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				INIT_LIST_HEAD(&search_contexts);
128340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
128440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			list_add(&dsc->others,&search_contexts);
128540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			yaffsfs_SetDirRewound(dsc);		}
128640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
128740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
128840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
128940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
129040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
129140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return dir;
129240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
129340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
129440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstruct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp)
129540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
129640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp;
129740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	struct yaffs_dirent *retVal = NULL;
129840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
129940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
130040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
130140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(dsc && dsc->magic == YAFFS_MAGIC){
130240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(0);
130340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(dsc->nextReturn){
130440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			dsc->de.d_ino = yaffs_GetEquivalentObject(dsc->nextReturn)->objectId;
130540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			dsc->de.d_off = dsc->offset++;
130640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			yaffs_GetObjectName(dsc->nextReturn,dsc->de.d_name,NAME_MAX+1);
130740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			dsc->de.d_reclen = sizeof(struct yaffs_dirent);
130840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			retVal = &dsc->de;
130940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			yaffsfs_DirAdvance(dsc);
131040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		} else
131140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			retVal = NULL;
131240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
131340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
131440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
131540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-EBADF);
131640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
131740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
131840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
131940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
132040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return retVal;
132140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
132240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
132340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
132440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
132540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectvoid yaffs_rewinddir(yaffs_DIR *dirp)
132640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
132740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp;
132840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
132940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
133040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
133140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_SetDirRewound(dsc);
133240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
133340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
133440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
133540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
133640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
133740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_closedir(yaffs_DIR *dirp)
133840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
133940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp;
134040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
134140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
134240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	dsc->magic = 0;
134340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	list_del(&dsc->others); /* unhook from list */
134440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	YFREE(dsc);
134540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
134640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return 0;
134740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
134840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
134940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// end of directory stuff
135040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
135140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
135240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_symlink(const char *oldpath, const char *newpath)
135340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
135440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *parent = NULL;
135540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *obj;
135640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	char *name;
135740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int retVal= -1;
135840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int mode = 0; // ignore for now
135940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
136040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
136140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	parent = yaffsfs_FindDirectory(NULL,newpath,&name,0);
136240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	obj = yaffs_MknodSymLink(parent,name,mode,0,0,oldpath);
136340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(obj)
136440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
136540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = 0;
136640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
136740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
136840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
136940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-ENOSPC); // just assume no space for now
137040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = -1;
137140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
137240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
137340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
137440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
137540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return retVal;
137640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
137740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
137840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
137940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_readlink(const char *path, char *buf, int bufsiz)
138040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
138140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *obj = NULL;
138240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int retVal;
138340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
138440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
138540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
138640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
138740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	obj = yaffsfs_FindObject(NULL,path,0);
138840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
138940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(!obj)
139040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
139140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-ENOENT);
139240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = -1;
139340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
139440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else if(obj->variantType != YAFFS_OBJECT_TYPE_SYMLINK)
139540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
139640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-EINVAL);
139740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = -1;
139840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
139940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
140040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
140140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		char *alias = obj->variant.symLinkVariant.alias;
140240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		memset(buf,0,bufsiz);
140340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		strncpy(buf,alias,bufsiz - 1);
140440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = 0;
140540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
140640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
140740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return retVal;
140840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
140940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
141040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_link(const char *oldpath, const char *newpath)
141140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
141240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	// Creates a link called newpath to existing oldpath
141340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *obj = NULL;
141440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *target = NULL;
141540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int retVal = 0;
141640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
141740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
141840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Lock();
141940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
142040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	obj = yaffsfs_FindObject(NULL,oldpath,0);
142140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	target = yaffsfs_FindObject(NULL,newpath,0);
142240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
142340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(!obj)
142440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
142540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-ENOENT);
142640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = -1;
142740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
142840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else if(target)
142940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
143040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffsfs_SetError(-EEXIST);
143140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		retVal = -1;
143240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
143340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
143440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
143540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffs_Object *newdir = NULL;
143640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffs_Object *link = NULL;
143740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
143840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		char *newname;
143940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
144040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		newdir = yaffsfs_FindDirectory(NULL,newpath,&newname,0);
144140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
144240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(!newdir)
144340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
144440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			yaffsfs_SetError(-ENOTDIR);
144540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			retVal = -1;
144640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
144740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		else if(newdir->myDev != obj->myDev)
144840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
144940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			yaffsfs_SetError(-EXDEV);
145040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			retVal = -1;
145140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
145240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		if(newdir && strlen(newname) > 0)
145340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
145440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			link = yaffs_Link(newdir,newname,obj);
145540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(link)
145640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				retVal = 0;
145740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			else
145840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
145940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				yaffsfs_SetError(-ENOSPC);
146040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				retVal = -1;
146140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
146240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
146340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
146440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
146540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffsfs_Unlock();
146640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
146740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return retVal;
146840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
146940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
147040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_mknod(const char *pathname, mode_t mode, dev_t dev);
147140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
147240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint yaffs_DumpDevStruct(const char *path)
147340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
147440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	char *rest;
147540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
147640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Object *obj = yaffsfs_FindRoot(path,&rest);
147740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
147840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(obj)
147940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
148040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		yaffs_Device *dev = obj->myDev;
148140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
148240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		printf("\n"
148340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			   "nPageWrites.......... %d\n"
148440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			   "nPageReads........... %d\n"
148540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			   "nBlockErasures....... %d\n"
148640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			   "nGCCopies............ %d\n"
148740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			   "garbageCollections... %d\n"
148840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			   "passiveGarbageColl'ns %d\n"
148940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			   "\n",
149040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				dev->nPageWrites,
149140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				dev->nPageReads,
149240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				dev->nBlockErasures,
149340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				dev->nGCCopies,
149440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				dev->garbageCollections,
149540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				dev->passiveGarbageCollections
149640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		);
149740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
149840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
149940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return 0;
150040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
150140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
1502