X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=direct%2Fyaffsfs.c;h=2110fe8f4ef1a621ecc5e15d7cb94431e1015e2e;hp=37d6cae1d0cce812d4217f6444c06fbaf8360dd5;hb=1658295946bc589b4d351e75a59bd697630cd9e1;hpb=da279cc0ca8272f8ddb7fd3fbd4d09fc054e8c11 diff --git a/direct/yaffsfs.c b/direct/yaffsfs.c index 37d6cae..2110fe8 100644 --- a/direct/yaffsfs.c +++ b/direct/yaffsfs.c @@ -17,7 +17,7 @@ #include "yportenv.h" #include "yaffs_trace.h" -#include /* for memset */ +#include "string.h" #define YAFFSFS_MAX_SYMLINK_DEREFERENCES 5 @@ -75,7 +75,7 @@ typedef struct{ u8 shareWrite:1; int inodeId:12; /* Index to corresponding yaffsfs_Inode */ int handleCount:10; /* Number of handles for this fd */ - u32 position; /* current position in file */ + loff_t position; /* current position in file */ }yaffsfs_FileDes; typedef struct { @@ -83,6 +83,20 @@ typedef struct { short int useCount; } yaffsfs_Handle; + +typedef struct +{ + yaffs_dirent de; /* directory entry being used by this dsc */ + YCHAR name[NAME_MAX+1]; /* name of directory being searched */ + struct yaffs_obj *dirObj; /* ptr to directory being searched */ + struct yaffs_obj *nextReturn; /* obj to be returned by next readddir */ + struct list_head others; + int offset:20; + unsigned inUse:1; +} yaffsfs_DirectorySearchContext; + + +static yaffsfs_DirectorySearchContext yaffsfs_dsc[YAFFSFS_N_DSC]; static yaffsfs_Inode yaffsfs_inode[YAFFSFS_N_HANDLES]; static yaffsfs_FileDes yaffsfs_fd[YAFFSFS_N_HANDLES]; static yaffsfs_Handle yaffsfs_handle[YAFFSFS_N_HANDLES]; @@ -112,9 +126,10 @@ static void yaffsfs_InitHandles(void) if(yaffsfs_handlesInitialised) return; - memset(yaffsfs_inode,0,sizeof(yaffsfs_inode)); - memset(yaffsfs_fd,0,sizeof(yaffsfs_fd)); - memset(yaffsfs_handle,0,sizeof(yaffsfs_handle)); + memset(yaffsfs_inode, 0, sizeof(yaffsfs_inode)); + memset(yaffsfs_fd, 0, sizeof(yaffsfs_fd)); + memset(yaffsfs_handle, 0, sizeof(yaffsfs_handle)); + memset(yaffsfs_dsc, 0, sizeof(yaffsfs_dsc)); for(i = 0; i < YAFFSFS_N_HANDLES; i++) yaffsfs_fd[i].inodeId = -1; @@ -380,13 +395,27 @@ static void yaffsfs_BreakDeviceHandles(struct yaffs_dev *dev) /* * Stuff to handle names. */ +#ifdef CONFIG_YAFFS_CASE_INSENSITIVE +static int yaffs_toupper(YCHAR a) +{ + if(a >= 'a' && a <= 'z') + return (a - 'a') + 'A'; + else + return a; +} +int yaffsfs_Match(YCHAR a, YCHAR b) +{ + return (yaffs_toupper(a) == yaffs_toupper(b)); +} +#else int yaffsfs_Match(YCHAR a, YCHAR b) { /* case sensitive */ return (a == b); } +#endif int yaffsfs_IsPathDivider(YCHAR ch) { @@ -405,7 +434,7 @@ int yaffsfs_CheckNameLength(const char *name) { int retVal = 0; - int nameLength = strnlen(name,YAFFS_MAX_NAME_LENGTH+1); + int nameLength = yaffs_strnlen(name,YAFFS_MAX_NAME_LENGTH+1); if(nameLength == 0){ yaffsfs_SetError(-ENOENT); @@ -430,7 +459,7 @@ static int yaffsfs_alt_dir_path(const YCHAR *path, YCHAR **ret_path) * We will use 3 * max name length instead. */ *ret_path = NULL; - path_length = strnlen(path,(YAFFS_MAX_NAME_LENGTH+1)*3 +1); + path_length = yaffs_strnlen(path,(YAFFS_MAX_NAME_LENGTH+1)*3 +1); /* If the last character is a path divider, then we need to * trim it back so that the name look-up works properly. @@ -443,7 +472,7 @@ static int yaffsfs_alt_dir_path(const YCHAR *path, YCHAR **ret_path) alt_path = kmalloc(path_length + 1, 0); if(!alt_path) return -1; - strcpy(alt_path, path); + yaffs_strcpy(alt_path, path); for(i = path_length-1; i >= 0 && yaffsfs_IsPathDivider(alt_path[i]); i--) @@ -650,9 +679,9 @@ static struct yaffs_obj *yaffsfs_DoFindDirectory(struct yaffs_obj *startDir, /* got to the end of the string */ return dir; else{ - if(strcmp(str,_Y(".")) == 0){ + if(yaffs_strcmp(str,_Y(".")) == 0){ /* Do nothing */ - } else if(strcmp(str,_Y("..")) == 0) { + } else if(yaffs_strcmp(str,_Y("..")) == 0) { dir = dir->parent; } else{ dir = yaffs_find_by_name(dir,str); @@ -1048,17 +1077,17 @@ int yaffs_close(int handle) -int yaffsfs_do_read(int handle, void *vbuf, unsigned int nbyte, int isPread, int offset) +int yaffsfs_do_read(int handle, void *vbuf, unsigned int nbyte, int isPread, loff_t offset) { yaffsfs_FileDes *fd = NULL; struct yaffs_obj *obj = NULL; - int pos = 0; - int startPos = 0; - int endPos = 0; + loff_t pos = 0; + loff_t startPos = 0; + loff_t endPos = 0; int nRead = 0; int nToRead = 0; int totalRead = 0; - unsigned int maxRead; + loff_t maxRead; u8 *buf = (u8 *)vbuf; if(!vbuf){ @@ -1165,18 +1194,18 @@ int yaffs_read(int handle, void *buf, unsigned int nbyte) return yaffsfs_do_read(handle, buf, nbyte, 0, 0); } -int yaffs_pread(int handle, void *buf, unsigned int nbyte, unsigned int offset) +int yaffs_pread(int handle, void *buf, unsigned int nbyte, loff_t offset) { return yaffsfs_do_read(handle, buf, nbyte, 1, offset); } -int yaffsfs_do_write(int handle, const void *vbuf, unsigned int nbyte, int isPwrite, int offset) +int yaffsfs_do_write(int handle, const void *vbuf, unsigned int nbyte, int isPwrite, loff_t offset) { yaffsfs_FileDes *fd = NULL; struct yaffs_obj *obj = NULL; - int pos = 0; - int startPos = 0; - int endPos; + loff_t pos = 0; + loff_t startPos = 0; + loff_t endPos; int nWritten = 0; int totalWritten = 0; int write_trhrough = 0; @@ -1279,13 +1308,13 @@ int yaffs_write(int fd, const void *buf, unsigned int nbyte) return yaffsfs_do_write(fd, buf, nbyte, 0, 0); } -int yaffs_pwrite(int fd, const void *buf, unsigned int nbyte, unsigned int offset) +int yaffs_pwrite(int fd, const void *buf, unsigned int nbyte, loff_t offset) { return yaffsfs_do_write(fd, buf, nbyte, 1, offset); } -int yaffs_truncate(const YCHAR *path,off_t new_size) +int yaffs_truncate(const YCHAR *path,loff_t new_size) { struct yaffs_obj *obj = NULL; struct yaffs_obj *dir = NULL; @@ -1323,14 +1352,14 @@ int yaffs_truncate(const YCHAR *path,off_t new_size) else if(new_size < 0 || new_size > YAFFS_MAX_FILE_SIZE) yaffsfs_SetError(-EINVAL); else - result = yaffs_resize_file(obj,new_size); + result = yaffs_resize_file(obj, new_size); yaffsfs_Unlock(); return (result) ? 0 : -1; } -int yaffs_ftruncate(int handle, off_t new_size) +int yaffs_ftruncate(int handle, loff_t new_size) { yaffsfs_FileDes *fd = NULL; struct yaffs_obj *obj = NULL; @@ -1351,19 +1380,19 @@ int yaffs_ftruncate(int handle, off_t new_size) yaffsfs_SetError(-EINVAL); else /* resize the file */ - result = yaffs_resize_file(obj,new_size); + result = yaffs_resize_file(obj, new_size); yaffsfs_Unlock(); return (result) ? 0 : -1; } -off_t yaffs_lseek(int handle, off_t offset, int whence) +loff_t yaffs_lseek(int handle, loff_t offset, int whence) { yaffsfs_FileDes *fd = NULL; struct yaffs_obj *obj = NULL; - int pos = -1; - int fSize = -1; + loff_t pos = -1; + loff_t fSize = -1; yaffsfs_Lock(); fd = yaffsfs_HandleToFileDes(handle); @@ -1430,7 +1459,7 @@ int yaffsfs_DoUnlink(const YCHAR *path,int isDirectory) yaffsfs_SetError(-ELOOP); else if(!dir) yaffsfs_SetError(-ENOENT); - else if(strncmp(name,_Y("."),2) == 0) + else if(yaffs_strncmp(name,_Y("."),2) == 0) yaffsfs_SetError(-EINVAL); else if(!obj) yaffsfs_SetError(-ENOENT); @@ -1518,7 +1547,7 @@ int yaffs_rename(const YCHAR *oldPath, const YCHAR *newPath) } else if(oldLoop || newLoop) { yaffsfs_SetError(-ELOOP); rename_allowed = 0; - } else if (olddir && oldname && strncmp(oldname, _Y("."),2) == 0){ + } else if (olddir && oldname && yaffs_strncmp(oldname, _Y("."),2) == 0){ yaffsfs_SetError(-EINVAL); rename_allowed = 0; }else if(!olddir || !newdir || !obj) { @@ -2379,7 +2408,7 @@ int yaffs_mkdir(const YCHAR *path, mode_t mode) yaffsfs_SetError(-ENOENT); else if(yaffsfs_TooManyObjects(parent->my_dev)) yaffsfs_SetError(-ENFILE); - else if(strnlen(name,5) == 0){ + else if(yaffs_strnlen(name,5) == 0){ /* Trying to make the root itself */ yaffsfs_SetError(-EEXIST); } else if(parent->my_dev->read_only) @@ -2438,7 +2467,7 @@ void * yaffs_getdev(const YCHAR *path) return (void *)dev; } -int yaffs_mount2(const YCHAR *path,int read_only) +int yaffs_mount_common(const YCHAR *path,int read_only, int skip_checkpt) { int retVal=-1; int result=YAFFS_FAIL; @@ -2464,7 +2493,15 @@ int yaffs_mount2(const YCHAR *path,int read_only) if(dev){ if(!dev->is_mounted){ dev->read_only = read_only ? 1 : 0; - result = yaffs_guts_initialise(dev); + if(skip_checkpt) { + u8 skip = dev->param.skip_checkpt_rd; + dev->param.skip_checkpt_rd = 1; + result = yaffs_guts_initialise(dev); + dev->param.skip_checkpt_rd = skip; + } else { + result = yaffs_guts_initialise(dev); + } + if(result == YAFFS_FAIL) yaffsfs_SetError(-ENOMEM); retVal = result ? 0 : -1; @@ -2480,9 +2517,13 @@ int yaffs_mount2(const YCHAR *path,int read_only) } +int yaffs_mount2(const YCHAR *path, int readonly) +{ + return yaffs_mount_common(path, readonly, 0); +} int yaffs_mount(const YCHAR *path) { - return yaffs_mount2(path,0); + return yaffs_mount_common(path, 0, 0); } int yaffs_sync(const YCHAR *path) @@ -2742,29 +2783,29 @@ void yaffs_remove_device(struct yaffs_dev *dev) list_del_init(&dev->dev_list); } +/* Functions to iterate through devices. NB Use with extreme care! */ +static struct list_head *dev_iterator; +void yaffs_dev_rewind(void) +{ + dev_iterator = yaffsfs_deviceList.next; +} +struct yaffs_dev *yaffs_next_dev(void) +{ + struct yaffs_dev *retval; -/* Directory search stuff. */ - -/* - * Directory search context - * - * NB this is an opaque structure. - */ - + if(!dev_iterator) + return NULL; + if(dev_iterator == &yaffsfs_deviceList) + return NULL; -typedef struct -{ - u32 magic; - yaffs_dirent de; /* directory entry being used by this dsc */ - YCHAR name[NAME_MAX+1]; /* name of directory being searched */ - struct yaffs_obj *dirObj; /* ptr to directory being searched */ - struct yaffs_obj *nextReturn; /* obj to be returned by next readddir */ - int offset; - struct list_head others; -} yaffsfs_DirectorySearchContext; + retval = list_entry(dev_iterator, struct yaffs_dev, dev_list); + dev_iterator = dev_iterator->next; + return retval; +} +/* Directory search stuff. */ static struct list_head search_contexts; @@ -2865,15 +2906,20 @@ yaffs_DIR *yaffs_opendir(const YCHAR *dirname) else if(obj->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) yaffsfs_SetError(-ENOTDIR); else { + int i; + + for(i = 0, dsc = NULL; i < YAFFSFS_N_DSC && !dsc; i++) { + if(!yaffsfs_dsc[i].inUse) + dsc = & yaffsfs_dsc[i]; + } - dsc = kmalloc(sizeof(yaffsfs_DirectorySearchContext), 0); dir = (yaffs_DIR *)dsc; if(dsc){ memset(dsc,0,sizeof(yaffsfs_DirectorySearchContext)); - dsc->magic = YAFFS_MAGIC; + dsc->inUse = 1; dsc->dirObj = obj; - strncpy(dsc->name,dirname,NAME_MAX); + yaffs_strncpy(dsc->name,dirname,NAME_MAX); INIT_LIST_HEAD(&dsc->others); if(!search_contexts.next) @@ -2897,17 +2943,17 @@ struct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp) yaffsfs_Lock(); - if(dsc && dsc->magic == YAFFS_MAGIC){ + if(dsc && dsc->inUse){ yaffsfs_SetError(0); if(dsc->nextReturn){ dsc->de.d_ino = yaffs_get_equivalent_obj(dsc->nextReturn)->obj_id; dsc->de.d_dont_use = (unsigned)dsc->nextReturn; dsc->de.d_off = dsc->offset++; yaffs_get_obj_name(dsc->nextReturn,dsc->de.d_name,NAME_MAX); - if(strnlen(dsc->de.d_name,NAME_MAX+1) == 0) + if(yaffs_strnlen(dsc->de.d_name,NAME_MAX+1) == 0) { /* this should not happen! */ - strcpy(dsc->de.d_name,_Y("zz")); + yaffs_strcpy(dsc->de.d_name,_Y("zz")); } dsc->de.d_reclen = sizeof(struct yaffs_dirent); retVal = &dsc->de; @@ -2946,9 +2992,8 @@ int yaffs_closedir(yaffs_DIR *dirp) } yaffsfs_Lock(); - dsc->magic = 0; + dsc->inUse = 0; list_del(&dsc->others); /* unhook from list */ - kfree(dsc); yaffsfs_Unlock(); return 0; } @@ -2983,7 +3028,7 @@ int yaffs_symlink(const YCHAR *oldpath, const YCHAR *newpath) yaffsfs_SetError(-ENOTDIR); else if(loop) yaffsfs_SetError(-ELOOP); - else if( !parent || strnlen(name,5) < 1) + else if( !parent || yaffs_strnlen(name,5) < 1) yaffsfs_SetError(-ENOENT); else if(yaffsfs_TooManyObjects(parent->my_dev)) yaffsfs_SetError(-ENFILE); @@ -3033,7 +3078,7 @@ int yaffs_readlink(const YCHAR *path, YCHAR *buf, int bufsiz) else { YCHAR *alias = obj->variant.symlink_variant.alias; memset(buf,0,bufsiz); - strncpy(buf,alias,bufsiz - 1); + yaffs_strncpy(buf,alias,bufsiz - 1); retVal = 0; } yaffsfs_Unlock();