changeset 341:89e691a21fd1

Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency.
author charles <charles>
date Wed, 06 Jan 2010 04:00:23 +0000
parents 28e07f9b4641
children ce702882929d
files direct/yaffsfs.c yaffs_guts.c yaffs_guts.h
diffstat 3 files changed, 115 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/direct/yaffsfs.c
+++ b/direct/yaffsfs.c
@@ -24,7 +24,7 @@
 #endif
 
 
-const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.29 2009-12-07 01:17:33 charles Exp $";
+const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.30 2010-01-06 04:00:23 charles Exp $";
 
 // configurationList is the list of devices that are supported
 static yaffsfs_DeviceConfiguration *yaffsfs_configurationList;
@@ -41,16 +41,21 @@ static void yaffsfs_RemoveObjectCallback
 
 unsigned int yaffs_wr_attempts;
 
+typedef struct {
+	int count;
+	yaffs_Object *iObj;
+} yaffsfs_Inode;
+
 typedef struct{
 	__u8  inUse:1;		// this handle is in use
 	__u8  readOnly:1;	// this handle is read only
 	__u8  append:1;		// append only
 	__u8  exclusive:1;	// exclusive
+	int   inodeId:20;	// the object
 	__u32 position;		// current position in file
-	yaffs_Object *obj;	// the object
 }yaffsfs_Handle;
 
-
+static yaffsfs_Inode yaffsfs_inode[YAFFSFS_N_HANDLES];
 static yaffsfs_Handle yaffsfs_handle[YAFFSFS_N_HANDLES];
 
 // yaffsfs_InitHandle
@@ -59,10 +64,11 @@ static yaffsfs_Handle yaffsfs_handle[YAF
 static int yaffsfs_InitHandles(void)
 {
 	int i;
-	for(i = 0; i < YAFFSFS_N_HANDLES; i++){
-		yaffsfs_handle[i].inUse = 0;
-		yaffsfs_handle[i].obj = NULL;
-	}
+	memset(yaffsfs_inode,0,sizeof(yaffsfs_inode));
+	memset(yaffsfs_handle,0,sizeof(yaffsfs_handle));
+	for(i = 0; i < YAFFSFS_N_HANDLES; i++)
+		yaffsfs_handle[i].inodeId = -1;
+
 	return 0;
 }
 
@@ -74,16 +80,87 @@ yaffsfs_Handle *yaffsfs_GetHandlePointer
 	return &yaffsfs_handle[h];
 }
 
-yaffs_Object *yaffsfs_GetHandleObject(int handle)
+yaffsfs_Inode *yaffsfs_GetInodePointer(int handle)
 {
 	yaffsfs_Handle *h = yaffsfs_GetHandlePointer(handle);
 
-	if(h && h->inUse)
-		return h->obj;
+	if(h && h->inUse && h->inodeId >= 0 && h->inodeId < YAFFSFS_N_HANDLES)
+		return  &yaffsfs_inode[h->inodeId];
+
+	return NULL;
+}
+
+yaffs_Object *yaffsfs_GetHandleObject(int handle)
+{
+	yaffsfs_Inode *in = yaffsfs_GetInodePointer(handle);
+
+	if(in)
+		return in->iObj;
 
 	return NULL;
 }
 
+//yaffsfs_GetInodeIdForObject
+// Grab an inode entry when opening a new inode.
+//
+
+static int yaffsfs_GetInodeIdForObject(yaffs_Object *obj)
+{
+	int i;
+	int ret = -1;
+	yaffsfs_Inode *in = NULL;
+	
+	if(obj)
+		obj = yaffs_GetEquivalentObject(obj);
+
+	/* Look for it. If we can't find it then make one */
+	for(i = 0; i < YAFFSFS_N_HANDLES && ret < 0; i++){
+		if(yaffsfs_inode[i].iObj == obj)
+			ret = i;
+	}
+
+	for(i = 0; i < YAFFSFS_N_HANDLES && ret < 0; i++){
+		if(!yaffsfs_inode[i].iObj)
+			ret = i;
+	}
+	
+	
+	if(ret>=0){
+		in = &yaffsfs_inode[ret];
+		if(!in->iObj)
+			in->count = 0;
+		in->iObj = obj;
+		in->count++;
+	}
+	
+	
+	return ret;
+}
+
+static void yaffsfs_ReleaseInode(yaffsfs_Inode *in)
+{
+	yaffs_Object *obj;
+	
+	obj = in->iObj;
+
+	if(obj->unlinked)
+		yaffs_DeleteObject(obj);
+	
+	obj->myInode = NULL;
+	in->iObj = NULL;
+
+}
+
+static void yaffsfs_PutInode(int inodeId)
+{
+	if(inodeId >= 0 && inodeId < YAFFSFS_N_HANDLES){
+		yaffsfs_Inode *in = & yaffsfs_inode[inodeId];
+		in->count--;
+		if(in->count <= 0)
+			yaffsfs_ReleaseInode(in);
+	}	
+}
+
 
 //yaffsfs_GetHandle
 // Grab a handle (when opening a file)
@@ -101,6 +178,7 @@ static int yaffsfs_GetHandle(void)
 		}
 		if(!h->inUse){
 			memset(h,0,sizeof(yaffsfs_Handle));
+			h->inodeId=-1;
 			h->inUse=1;
 			return i;
 		}
@@ -109,21 +187,24 @@ static int yaffsfs_GetHandle(void)
 }
 
 // yaffs_PutHandle
-// Let go of a handle (when closing a file)
+// Let go of a handle when closing a file or aborting an open.
 //
 static int yaffsfs_PutHandle(int handle)
 {
 	yaffsfs_Handle *h = yaffsfs_GetHandlePointer(handle);
 
 	if(h){
+		if(h->inodeId >= 0)
+			yaffsfs_PutInode(h->inodeId);
 		h->inUse = 0;
-		h->obj = NULL;
+		h->inodeId = -1;
 	}
 	return 0;
 }
 
 
 
+
 // Stuff to search for a directory from a path
 
 
@@ -431,6 +512,9 @@ int yaffs_open(const YCHAR *path, int of
 		if(obj && obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
 			obj = yaffsfs_FollowLink(obj,symDepth++);
 
+		if(obj)
+			obj = yaffs_GetEquivalentObject(obj);
+
 		if(obj && obj->variantType != YAFFS_OBJECT_TYPE_FILE)
 			obj = NULL;
 
@@ -439,10 +523,9 @@ int yaffs_open(const YCHAR *path, int of
 			alreadyOpen = alreadyExclusive = 0;
 
 			for(i = 0; i < YAFFSFS_N_HANDLES; i++){
-
 				if(i != handle &&
 				   yaffsfs_handle[i].inUse &&
-				    obj == yaffsfs_handle[i].obj){
+				    obj == yaffsfs_inode[yaffsfs_handle[i].inodeId].iObj){
 				 	alreadyOpen = 1;
 					if(yaffsfs_handle[i].exclusive)
 						alreadyExclusive = 1;
@@ -484,14 +567,25 @@ int yaffs_open(const YCHAR *path, int of
 		}
 
 		if(obj && !openDenied) {
-			h->obj = obj;
+			int inodeId = yaffsfs_GetInodeIdForObject(obj);
+
+			if(inodeId<0) {
+				/*
+				 * Todo: Fix any problem if inodes run out, though that
+				 * can't happen if the number of inode items >= number of handles. 
+				 */
+			}
+			
+			h->inodeId = inodeId;
 			h->inUse = 1;
 			h->readOnly = (oflag & (O_WRONLY | O_RDWR)) ? 0 : 1;
 			h->append =  (oflag & O_APPEND) ? 1 : 0;
 			h->exclusive = (oflag & O_EXCL) ? 1 : 0;
 			h->position = 0;
 
-                        obj->inUse++;
+			/* Hook inode to object */
+                        obj->myInode = (void*) &yaffsfs_inode[inodeId];
+
                         if((oflag & O_TRUNC) && !h->readOnly)
                                 yaffs_ResizeFile(obj,0);
 		} else {
@@ -520,7 +614,7 @@ int yaffs_Dofsync(int fd,int datasync)
 
 	if(h && h->inUse)
 		// flush the file
-		yaffs_FlushFile(h->obj,1,datasync);
+		yaffs_FlushFile(yaffsfs_inode[h->inodeId].iObj,1,datasync);
 	else {
 		// bad handle
 		yaffsfs_SetError(-EBADF);
@@ -558,11 +652,7 @@ int yaffs_close(int fd)
 
 	if(h && h->inUse) {
 		// clean up
-		yaffs_FlushFile(h->obj,1,0);
-		h->obj->inUse--;
-		if(h->obj->inUse <= 0 && h->obj->unlinked)
-			yaffs_DeleteObject(h->obj);
-
+		yaffs_FlushFile(yaffsfs_inode[h->inodeId].iObj,1,0);
 		yaffsfs_PutHandle(fd);
 		retVal = 0;
 	} else {
@@ -1296,7 +1386,7 @@ int yaffs_unmount(const YCHAR *path)
 			yaffs_CheckpointSave(dev);
 
 			for(i = inUse = 0; i < YAFFSFS_N_HANDLES && !inUse; i++){
-				if(yaffsfs_handle[i].inUse && yaffsfs_handle[i].obj->myDev == dev)
+				if(yaffsfs_handle[i].inUse && yaffsfs_inode[yaffsfs_handle[i].inodeId].iObj->myDev == dev)
 					inUse = 1; // the device is in use, can't unmount
 			}
 
--- a/yaffs_guts.c
+++ b/yaffs_guts.c
@@ -12,7 +12,7 @@
  */
 
 const char *yaffs_guts_c_version =
-    "$Id: yaffs_guts.c,v 1.104 2010-01-05 22:58:15 charles Exp $";
+    "$Id: yaffs_guts.c,v 1.105 2010-01-06 04:02:12 charles Exp $";
 
 #include "yportenv.h"
 
@@ -2050,9 +2050,7 @@ static void yaffs_FreeObject(yaffs_Objec
 {
 	yaffs_Device *dev = tn->myDev;
 
-#ifdef __KERNEL__
 	T(YAFFS_TRACE_OS, (TSTR("FreeObject %p inode %p"TENDSTR), tn, tn->myInode));
-#endif
 
 	if (tn->parent)
 		YBUG();
@@ -2060,7 +2058,6 @@ static void yaffs_FreeObject(yaffs_Objec
 		YBUG();
 
 
-#ifdef __KERNEL__
 	if (tn->myInode) {
 		/* We're still hooked up to a cached inode.
 		 * Don't delete now, but mark for later deletion
@@ -2068,7 +2065,6 @@ static void yaffs_FreeObject(yaffs_Objec
 		tn->deferedFree = 1;
 		return;
 	}
-#endif
 
 	yaffs_UnhashObject(tn);
 
@@ -5254,13 +5250,8 @@ static int yaffs_UnlinkFileIfNeeded(yaff
 	int retVal;
 	int immediateDeletion = 0;
 
-#ifdef __KERNEL__
 	if (!in->myInode)
 		immediateDeletion = 1;
-#else
-	if (in->inUse <= 0)
-		immediateDeletion = 1;
-#endif
 
 	if (immediateDeletion) {
 		retVal =
@@ -5380,13 +5371,8 @@ static int yaffs_UnlinkWorker(yaffs_Obje
 
 	int immediateDeletion = 0;
 
-#ifdef __KERNEL__
 	if (!obj->myInode)
 		immediateDeletion = 1;
-#else
-	if (obj->inUse <= 0)
-		immediateDeletion = 1;
-#endif
 
 	if(obj)
 		yaffs_UpdateParent(obj->parent);
--- a/yaffs_guts.h
+++ b/yaffs_guts.h
@@ -455,10 +455,6 @@ struct yaffs_ObjectStruct {
 	YCHAR shortName[YAFFS_SHORT_NAME_LENGTH + 1];
 #endif
 
-#ifndef __KERNEL__
-	__u32 inUse;
-#endif
-
 #ifdef CONFIG_YAFFS_WINCE
 	__u32 win_ctime[2];
 	__u32 win_mtime[2];
@@ -473,10 +469,7 @@ struct yaffs_ObjectStruct {
 
 	__u32 yst_rdev;
 
-#ifdef __KERNEL__
-	struct inode *myInode;
-
-#endif
+	void *myInode;
 
 	yaffs_ObjectType variantType;