Signed-off-by: Charles Manning <cdhmanning@gmail.com>
* NAND Simulator for testing YAFFS
*/
* NAND Simulator for testing YAFFS
*/
#include "yramsim.h"
#include "yaffs_guts.h"
#include "yramsim.h"
#include "yaffs_guts.h"
-static int yramsim_rd_chunk (struct yaffs_dev *dev, unsigned pageId,
- unsigned char *data, unsigned dataLength,
- unsigned char *spare, unsigned spareLength,
- int *eccStatus)
+static int yramsim_rd_chunk (struct yaffs_dev *dev, int pageId,
+ u8 *data, int dataLength,
+ u8 *spare, int spareLength,
+ enum yaffs_ecc_result *ecc_result)
{
SimData *sim = DevToSim(dev);
Block **blockList = sim->blockList;
{
SimData *sim = DevToSim(dev);
Block **blockList = sim->blockList;
pageOffset >= PAGES_PER_BLOCK ||
dataLength >DATA_SIZE ||
spareLength > SPARE_SIZE ||
pageOffset >= PAGES_PER_BLOCK ||
dataLength >DATA_SIZE ||
spareLength > SPARE_SIZE ||
!blockList[blockId]->blockOk){
!blockList[blockId]->blockOk){
}
d = blockList[blockId]->page[pageOffset];
}
d = blockList[blockId]->page[pageOffset];
if(spare)
memcpy(spare,s,spareLength);
if(spare)
memcpy(spare,s,spareLength);
- *eccStatus = 0; /* 0 = no error, -1 = unfixable error, 1 = fixable */
+ if (ecc_result)
+ *ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
-static int yramsim_wr_chunk (struct yaffs_dev *dev,unsigned pageId,
- const unsigned char *data, unsigned dataLength,
- const unsigned char *spare, unsigned spareLength)
+static int yramsim_wr_chunk (struct yaffs_dev *dev, int pageId,
+ const u8 *data, int dataLength,
+ const u8 *spare, int spareLength)
{
SimData *sim = DevToSim(dev);
Block **blockList = sim->blockList;
{
SimData *sim = DevToSim(dev);
Block **blockList = sim->blockList;
dataLength >DATA_SIZE ||
spareLength > SPARE_SIZE ||
!blockList[blockId]->blockOk){
dataLength >DATA_SIZE ||
spareLength > SPARE_SIZE ||
!blockList[blockId]->blockOk){
}
d = blockList[blockId]->page[pageOffset];
}
d = blockList[blockId]->page[pageOffset];
if(spare)
memcpy(s,spare,spareLength);
if(spare)
memcpy(s,spare,spareLength);
-static int yramsim_erase(struct yaffs_dev *dev,unsigned blockId)
+static int yramsim_erase(struct yaffs_dev *dev, int blockId)
{
SimData *sim = DevToSim(dev);
{
SimData *sim = DevToSim(dev);
return yramsim_erase_internal(sim,blockId,0);
}
return yramsim_erase_internal(sim,blockId,0);
}
-static int yramsim_check_block_bad(struct yaffs_dev *dev,unsigned blockId)
+static int yramsim_check_block_bad(struct yaffs_dev *dev, int blockId)
{
SimData *sim = DevToSim(dev);
Block **blockList = sim->blockList;
{
SimData *sim = DevToSim(dev);
Block **blockList = sim->blockList;
return blockList[blockId]->blockOk ? YAFFS_OK : YAFFS_FAIL;
}
return blockList[blockId]->blockOk ? YAFFS_OK : YAFFS_FAIL;
}
-static int yramsim_mark_block_bad(struct yaffs_dev *dev,unsigned blockId)
+static int yramsim_mark_block_bad(struct yaffs_dev *dev, int blockId)
{
SimData *sim = DevToSim(dev);
Block **blockList = sim->blockList;
if(blockId >= sim->nBlocks){
{
SimData *sim = DevToSim(dev);
Block **blockList = sim->blockList;
if(blockId >= sim->nBlocks){
}
blockList[blockId]->blockOk = 0;
}
blockList[blockId]->blockOk = 0;
fd = &yaffsfs_fd[fdId];
fd->handleCount--;
if (fd->handleCount < 1) {
fd = &yaffsfs_fd[fdId];
fd->handleCount--;
if (fd->handleCount < 1) {
yaffsfs_closedir_no_lock(fd->v.dir);
yaffsfs_closedir_no_lock(fd->v.dir);
if (fd->inodeId >= 0) {
yaffsfs_PutInode(fd->inodeId);
fd->inodeId = -1;
if (fd->inodeId >= 0) {
yaffsfs_PutInode(fd->inodeId);
fd->inodeId = -1;
int notDir = 0;
int loop = 0;
int is_dir = 0;
int notDir = 0;
int loop = 0;
int is_dir = 0;
if (yaffsfs_CheckMemRegion(path, 0, 0)< 0) {
yaffsfs_SetError(-EFAULT);
if (yaffsfs_CheckMemRegion(path, 0, 0)< 0) {
yaffsfs_SetError(-EFAULT);
if (handle < 0) {
yaffsfs_SetError(-ENFILE);
if (handle < 0) {
yaffsfs_SetError(-ENFILE);
+ errorReported = __LINE__;
} else {
fd = yaffsfs_HandleToFileDes(handle);
} else {
fd = yaffsfs_HandleToFileDes(handle);
/* A directory can't be opened except for read */
if ( is_dir &&
/* A directory can't be opened except for read */
if ( is_dir &&
- (writeRequested || !readRequested ||
- (oflag & ~O_RDONLY))) {
- openDenied = 1;
+ (writeRequested || !readRequested || rwflags != O_RDONLY)) {
+ openDenied = __LINE__;
yaffsfs_SetError(-EISDIR);
yaffsfs_SetError(-EISDIR);
+ errorReported = __LINE__;
}
if(is_dir) {
dsc = yaffsfs_opendir_reldir_no_lock(reldir, path);
if (!dsc) {
}
if(is_dir) {
dsc = yaffsfs_opendir_reldir_no_lock(reldir, path);
if (!dsc) {
yaffsfs_SetError(-ENFILE);
yaffsfs_SetError(-ENFILE);
+ errorReported = __LINE__;
*/
if (!errorReported &&
(oflag & O_EXCL) && (oflag & O_CREAT)) {
*/
if (!errorReported &&
(oflag & O_EXCL) && (oflag & O_CREAT)) {
yaffsfs_SetError(-EEXIST);
yaffsfs_SetError(-EEXIST);
+ errorReported = __LINE__;
}
/* Check file permissions */
if (readRequested && !(obj->yst_mode & S_IRUSR))
}
/* Check file permissions */
if (readRequested && !(obj->yst_mode & S_IRUSR))
if (writeRequested && !(obj->yst_mode & S_IWUSR))
if (writeRequested && !(obj->yst_mode & S_IWUSR))
if (!errorReported && writeRequested &&
obj->my_dev->read_only) {
if (!errorReported && writeRequested &&
obj->my_dev->read_only) {
yaffsfs_SetError(-EROFS);
yaffsfs_SetError(-EROFS);
+ errorReported = __LINE__;
}
if (openDenied && !errorReported) {
yaffsfs_SetError(-EACCES);
}
if (openDenied && !errorReported) {
yaffsfs_SetError(-EACCES);
+ errorReported = __LINE__;
}
/* Check sharing of an existing object. */
}
/* Check sharing of an existing object. */
(!shareRead && alreadyReading) ||
(!sharedWriteAllowed && writeRequested) ||
(!shareWrite && alreadyWriting)) {
(!shareRead && alreadyReading) ||
(!sharedWriteAllowed && writeRequested) ||
(!shareWrite && alreadyWriting)) {
yaffsfs_SetError(-EBUSY);
yaffsfs_SetError(-EBUSY);
+ errorReported = __LINE__;
¬Dir, &loop);
if (!dir && notDir) {
yaffsfs_SetError(-ENOTDIR);
¬Dir, &loop);
if (!dir && notDir) {
yaffsfs_SetError(-ENOTDIR);
+ errorReported = __LINE__;
} else if (loop) {
yaffsfs_SetError(-ELOOP);
} else if (loop) {
yaffsfs_SetError(-ELOOP);
+ errorReported = __LINE__;
} else if (!dir) {
yaffsfs_SetError(-ENOENT);
} else if (!dir) {
yaffsfs_SetError(-ENOENT);
+ errorReported = __LINE__;
/* Let's see if we can create this file */
if (dir->my_dev->read_only) {
yaffsfs_SetError(-EROFS);
/* Let's see if we can create this file */
if (dir->my_dev->read_only) {
yaffsfs_SetError(-EROFS);
+ errorReported = __LINE__;
} else if (yaffsfs_TooManyObjects(dir->my_dev)) {
yaffsfs_SetError(-ENFILE);
} else if (yaffsfs_TooManyObjects(dir->my_dev)) {
yaffsfs_SetError(-ENFILE);
+ errorReported = __LINE__;
} else
obj = yaffs_create_file(dir, name, mode, 0, 0);
if (!obj && !errorReported) {
yaffsfs_SetError(-ENOSPC);
} else
obj = yaffs_create_file(dir, name, mode, 0, 0);
if (!obj && !errorReported) {
yaffsfs_SetError(-ENOSPC);
+ errorReported = __LINE__;
}
}
if (!obj && dir && !errorReported && !(oflag & O_CREAT)) {
yaffsfs_SetError(-ENOENT);
}
}
if (!obj && dir && !errorReported && !(oflag & O_CREAT)) {
yaffsfs_SetError(-ENOENT);
+ errorReported = __LINE__;
}
if (obj && !openDenied) {
}
if (obj && !openDenied) {
if (!is_dir && (oflag & O_TRUNC) && fd->writing)
yaffs_resize_file(obj, 0);
} else {
if (!is_dir && (oflag & O_TRUNC) && fd->writing)
yaffs_resize_file(obj, 0);
} else {
+ if (dsc)
+ yaffsfs_closedir_no_lock(dsc);
+ dsc = NULL;
yaffsfs_PutHandle(handle);
if (!errorReported)
yaffsfs_SetError(0); /* Problem */
yaffsfs_PutHandle(handle);
if (!errorReported)
yaffsfs_SetError(0); /* Problem */
yaffsfs_SetError(-EBADF);
else if (obj->my_dev->read_only)
yaffsfs_SetError(-EROFS);
yaffsfs_SetError(-EBADF);
else if (obj->my_dev->read_only)
yaffsfs_SetError(-EROFS);
- else if (!isDirectory &&
- obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY)
- yaffsfs_SetError(-EISDIR);
- else if (isDirectory &&
- obj->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
- yaffsfs_SetError(-ENOTDIR);
- else if (isDirectory && obj == obj->my_dev->root_dir)
+ else if (obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY &&
+ !(list_empty(&obj->variant.dir_variant.children)))
+ yaffsfs_SetError(-ENOTEMPTY);
+ else if (obj == obj->my_dev->root_dir)
yaffsfs_SetError(-EBUSY); /* Can't rmdir a root */
yaffsfs_SetError(-EBUSY); /* Can't rmdir a root */
- else if (yaffs_unlink_obj(oobj) == YAFFS_OK)
+ else if (yaffs_unlink_obj(obj) == YAFFS_OK)
retVal = 0;
yaffsfs_Unlock();
retVal = 0;
yaffsfs_Unlock();
+int yaffs_fgetfl(int fd, int *flags)
+{
+ struct yaffsfs_FileDes *fdp = yaffsfs_HandleToFileDes(fd);
+ int retVal;
+
+ yaffsfs_Lock();
+
+ if(!flags || !fdp) {
+ yaffsfs_SetError(-EINVAL);
+ retVal = -1;
+ } else {
+ if (fdp->reading && fdp->writing)
+ *flags = O_RDWR;
+ else if (fdp->writing)
+ *flags = O_WRONLY;
+ else
+ *flags = O_RDONLY;
+ retVal = 0;
+ }
+
+ yaffsfs_Unlock();
+ return retVal;
+}
+
static int rename_file_over_dir(struct yaffs_obj *obj, struct yaffs_obj *newobj)
{
static int rename_file_over_dir(struct yaffs_obj *obj, struct yaffs_obj *newobj)
{
+int yaffs_fgetfl(int fd, int *flags);
+
int yaffs_read(int fd, void *buf, unsigned int nbyte) ;
int yaffs_write(int fd, const void *buf, unsigned int nbyte) ;
int yaffs_read(int fd, void *buf, unsigned int nbyte) ;
int yaffs_write(int fd, const void *buf, unsigned int nbyte) ;
-static int yaffs_unlink_obj(struct yaffs_obj *obj)
+int yaffs_unlink_obj(struct yaffs_obj *obj)
{
if (obj && obj->unlink_allowed)
return yaffs_unlink_worker(obj);
{
if (obj && obj->unlink_allowed)
return yaffs_unlink_worker(obj);