yaffs direct tests: Fix directory and error handling in a few functions
[yaffs2.git] / direct / yaffsfs.c
index 753bf4fa63c5d14c5dab03931b8949b53840bbb5..b7d337f1fa92568754abdbbe0b1fd7fec6087c05 100644 (file)
@@ -211,8 +211,10 @@ 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)
+               if(in->count <= 0){
                        yaffsfs_ReleaseInode(in);
+                       in->count = 0;
+               }
        }       
 }
 
@@ -277,15 +279,19 @@ static int yaffsfs_PutHandle(int handle)
        return 0;
 }
 
-static void yaffsfs_PutDeviceHandles(struct yaffs_dev *dev)
+static void yaffsfs_BreakDeviceHandles(struct yaffs_dev *dev)
 {
-       yaffsfs_Handle *yh;
+       yaffsfs_Handle *h;
+       struct yaffs_obj *obj;
        int i;
        for(i = 0; i < YAFFSFS_N_HANDLES; i++){
-               yh = & yaffsfs_handle[i];
-               if(yh->useCount>0 && 
-                       yaffsfs_inode[yh->inodeId].iObj->my_dev == dev)
-                       yaffsfs_PutHandle(i);
+               h = yaffsfs_GetHandlePointer(i);
+               obj = yaffsfs_GetHandleObject(i);
+               if(h && h->useCount>0 && obj && obj->my_dev == dev){
+                       h->useCount = 0;
+                       yaffsfs_PutInode(h->inodeId);
+                       h->inodeId = -1;
+               }
        }
 }
 
@@ -881,6 +887,7 @@ int yaffsfs_do_read(int fd, void *vbuf, unsigned int nbyte, int isPread, int off
        struct yaffs_obj *obj = NULL;
        int pos = 0;
        int startPos = 0;
+       int endPos = 0;
        int nRead = 0;
        int nToRead = 0;
        int totalRead = 0;
@@ -921,6 +928,15 @@ int yaffsfs_do_read(int fd, void *vbuf, unsigned int nbyte, int isPread, int off
 
                yaffsfs_GetHandle(fd);
 
+               endPos = pos + nbyte;
+
+               if(pos < 0 || pos > YAFFS_MAX_FILE_SIZE ||
+                       nbyte > YAFFS_MAX_FILE_SIZE ||
+                       endPos < 0 || endPos > YAFFS_MAX_FILE_SIZE){
+                       totalRead = -1;
+                       nbyte = 0;
+               }
+
                while(nbyte > 0) {
                        nToRead = YAFFSFS_RW_SIZE - (pos & (YAFFSFS_RW_SIZE -1));
                        if(nToRead > nbyte)
@@ -960,9 +976,8 @@ int yaffsfs_do_read(int fd, void *vbuf, unsigned int nbyte, int isPread, int off
                if(!isPread) {
                        if(totalRead >= 0)
                                h->position = startPos + totalRead;
-                       else {
-                                       /* todo error */
-                       }
+                       else
+                               yaffsfs_SetError(-EINVAL);
                }
 
        }
@@ -989,6 +1004,7 @@ int yaffsfs_do_write(int fd, const void *vbuf, unsigned int nbyte, int isPwrite,
        struct yaffs_obj *obj = NULL;
        int pos = 0;
        int startPos = 0;
+       int endPos;
        int nWritten = 0;
        int totalWritten = 0;
        int write_trhrough = 0;
@@ -1016,6 +1032,15 @@ int yaffsfs_do_write(int fd, const void *vbuf, unsigned int nbyte, int isPwrite,
 
                yaffsfs_GetHandle(fd);
                pos = startPos;
+               endPos = pos + nbyte;
+
+               if(pos < 0 || pos > YAFFS_MAX_FILE_SIZE ||
+                       nbyte > YAFFS_MAX_FILE_SIZE ||
+                       endPos < 0 || endPos > YAFFS_MAX_FILE_SIZE){
+                       totalWritten = -1;
+                       nbyte = 0;
+               }
+
                while(nbyte > 0) {
 
                        nToWrite = YAFFSFS_RW_SIZE - (pos & (YAFFSFS_RW_SIZE -1));
@@ -1059,9 +1084,8 @@ int yaffsfs_do_write(int fd, const void *vbuf, unsigned int nbyte, int isPwrite,
                if(!isPwrite){
                        if(totalWritten > 0)
                                h->position = startPos + totalWritten;
-                       else {
-                               /* todo error */
-                       }
+                       else
+                               yaffsfs_SetError(-EINVAL);
                }
        }
 
@@ -1168,10 +1192,12 @@ off_t yaffs_lseek(int fd, off_t offset, int whence)
                                pos = fSize + offset;
                } 
 
-               if(pos >= 0)
+               if(pos >= 0 && pos <= YAFFS_MAX_FILE_SIZE)
                        h->position = pos;
-               else
+               else{
                        yaffsfs_SetError(-EINVAL);
+                       pos = -1;
+               }
        }
 
        yaffsfs_Unlock();
@@ -1216,8 +1242,6 @@ int yaffsfs_DoUnlink(const YCHAR *path,int isDirectory)
 
        yaffsfs_Unlock();
 
-       /* todo error */
-
        return (result == YAFFS_FAIL) ? -1 : 0;
 }
 
@@ -2024,16 +2048,13 @@ int yaffs_mount2(const YCHAR *path,int read_only)
                        dev->read_only = read_only ? 1 : 0;
                        result = yaffs_guts_initialise(dev);
                        if(result == YAFFS_FAIL)
-                               /* todo error - mount failed */
                                yaffsfs_SetError(-ENOMEM);
                        retVal = result ? 0 : -1;
 
                }
                else
-                       /* todo error - already mounted. */
                        yaffsfs_SetError(-EBUSY);
        } else
-               /* todo error - no device */
                yaffsfs_SetError(-ENODEV);
 
        yaffsfs_Unlock();
@@ -2067,11 +2088,9 @@ int yaffs_sync(const YCHAR *path)
                         retVal = 0;
                         
                 } else
-                        /* todo error - not mounted. */
                         yaffsfs_SetError(-EINVAL);
                         
         }else
-                /* todo error - no device */
                 yaffsfs_SetError(-ENODEV);
 
         yaffsfs_Unlock();
@@ -2154,20 +2173,17 @@ int yaffs_unmount2(const YCHAR *path, int force)
 
                        if(!inUse || force){
                                if(inUse)
-                                       yaffsfs_PutDeviceHandles(dev);
+                                       yaffsfs_BreakDeviceHandles(dev);
                                yaffs_deinitialise(dev);
 
                                retVal = 0;
                        } else
-                               /* todo error can't unmount as files are open */
                                yaffsfs_SetError(-EBUSY);
 
                } else
-                       /* todo error - not mounted. */
                        yaffsfs_SetError(-EINVAL);
 
        } else
-               /* todo error - no device */
                yaffsfs_SetError(-ENODEV);
 
        yaffsfs_Unlock();
@@ -2491,10 +2507,10 @@ int yaffs_symlink(const YCHAR *oldpath, const YCHAR *newpath)
                obj = yaffs_create_symlink(parent,name,mode,0,0,oldpath);
                if(obj)
                        retVal = 0;
-               else{
-                       yaffsfs_SetError(-ENOSPC); /* just assume no space for now */
-                       retVal = -1;
-               }
+               else if (yaffsfs_FindObject(NULL,newpath,0,0, NULL))
+                       yaffsfs_SetError(-EEXIST);
+               else
+                       yaffsfs_SetError(-ENOSPC);
        }
 
        yaffsfs_Unlock();
@@ -2534,7 +2550,10 @@ int yaffs_link(const YCHAR *oldpath, const YCHAR *linkpath)
        /* Creates a link called newpath to existing oldpath */
        struct yaffs_obj *obj = NULL;
        struct yaffs_obj *lnk = NULL;
+       struct yaffs_obj *obj_dir = NULL;
+       struct yaffs_obj *lnk_dir = NULL;
        int retVal = -1;
+       YCHAR *newname;
 
        if(yaffsfs_CheckPath(linkpath) < 0){
                yaffsfs_SetError(-ENAMETOOLONG);
@@ -2543,39 +2562,31 @@ int yaffs_link(const YCHAR *oldpath, const YCHAR *linkpath)
 
        yaffsfs_Lock();
 
-       obj = yaffsfs_FindObject(NULL,oldpath,0,1,NULL);
+       obj = yaffsfs_FindObject(NULL,oldpath,0,1,&obj_dir);
        lnk = yaffsfs_FindObject(NULL,linkpath,0,0,NULL);
+       lnk_dir = yaffsfs_FindDirectory(NULL,linkpath,&newname,0);
 
-       if(!obj)
+       if(!obj_dir || !lnk_dir)
+               yaffsfs_SetError(-ENOTDIR);
+       else if(!obj)
                yaffsfs_SetError(-ENOENT);
        else if(obj->my_dev->read_only)
                yaffsfs_SetError(-EINVAL);
        else if(lnk)
                yaffsfs_SetError(-EEXIST);
-       else {
-               struct yaffs_obj *newdir = NULL;
-               struct yaffs_obj *link = NULL;
-
-               YCHAR *newname;
-
-               newdir = yaffsfs_FindDirectory(NULL,linkpath,&newname,0);
-
-               if(!newdir)
-                       yaffsfs_SetError(-ENOTDIR);
-               else if(newdir->my_dev != obj->my_dev)
-                       yaffsfs_SetError(-EXDEV);
-               
+       else if(lnk_dir->my_dev != obj->my_dev)
+               yaffsfs_SetError(-EXDEV);
+       else {          
                retVal = yaffsfs_CheckNameLength(newname);
                
                if(retVal == 0) {
-                       link = yaffs_link_obj(newdir,newname,obj);
-                       if(link)
+                       lnk = yaffs_link_obj(lnk_dir,newname,obj);
+                       if(lnk)
                                retVal = 0;
                        else{
                                yaffsfs_SetError(-ENOSPC);
                                retVal = -1;
                        }
-
                }
        }
        yaffsfs_Unlock();
@@ -2594,7 +2605,10 @@ int yaffs_mknod(const YCHAR *pathname, mode_t mode, dev_t dev)
 }
 
 
-
+/*
+ * D E B U G   F U N C T I O N S
+ */
 /*
  * yaffs_n_handles()
  * Returns number of handles attached to the object
@@ -2623,7 +2637,6 @@ int yaffs_get_error(void)
 
 int yaffs_set_error(int error)
 {
-       /*yaffsfs_SetError does not return. So the program is assumed to have worked. */
        yaffsfs_SetError(error);
        return 0;
 }