From d62fba5f7dc6974473dab1612dca6504afa4c702 Mon Sep 17 00:00:00 2001 From: charles Date: Wed, 6 Jan 2010 04:00:23 +0000 Subject: [PATCH 1/1] Change direct handle management to use an inode layer to make it consistent with Linux VFS. This is done to improve testing consistency. --- direct/yaffsfs.c | 136 +++++++++++++++++++++++++++++++++++++++-------- yaffs_guts.c | 16 +----- yaffs_guts.h | 9 +--- 3 files changed, 115 insertions(+), 46 deletions(-) diff --git a/direct/yaffsfs.c b/direct/yaffsfs.c index bb6f5f6..645db71 100644 --- 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(yaffs_Object *obj); 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[YAFFSFS_N_HANDLES]; 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(int h) 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 oflag, int mode) 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 oflag, int mode) 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 oflag, int mode) } 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 } diff --git a/yaffs_guts.c b/yaffs_guts.c index d4349c9..f9819f0 100644 --- 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_Object *tn) { 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_Object *tn) 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_Object *tn) tn->deferedFree = 1; return; } -#endif yaffs_UnhashObject(tn); @@ -5254,13 +5250,8 @@ static int yaffs_UnlinkFileIfNeeded(yaffs_Object *in) 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_Object *obj) int immediateDeletion = 0; -#ifdef __KERNEL__ if (!obj->myInode) immediateDeletion = 1; -#else - if (obj->inUse <= 0) - immediateDeletion = 1; -#endif if(obj) yaffs_UpdateParent(obj->parent); diff --git a/yaffs_guts.h b/yaffs_guts.h index c58c84b..48e5533 100644 --- 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; -- 2.30.2