#include "yramsim.h"
-#include "yaffs_nandif.h"
+#include "yaffs_guts.h"
#define DATA_SIZE 2048
static SimData *DevToSim(struct yaffs_dev *dev)
{
- struct ynandif_Geometry *geom =
- (struct ynandif_Geometry *)(dev->driver_context);
- SimData * sim = (SimData*)(geom->privateData);
- return sim;
+ return (SimData*)(dev->driver_context);
}
if(spare)
memcpy(spare,s,spareLength);
- *eccStatus = 0; // 0 = no error, -1 = unfixable error, 1 = fixable
+ *eccStatus = 0; /* 0 = no error, -1 = unfixable error, 1 = fixable */
return 1;
}
return yramsim_erase_internal(sim,blockId,0);
}
-static int yramsim_check_block_ok(struct yaffs_dev *dev,unsigned blockId)
+static int yramsim_check_block_bad(struct yaffs_dev *dev,unsigned blockId)
{
SimData *sim = DevToSim(dev);
Block **blockList = sim->blockList;
if(blockId >= sim->nBlocks){
- return 0;
+ return YAFFS_FAIL;
}
- return blockList[blockId]->blockOk ? 1 : 0;
+ return blockList[blockId]->blockOk ? YAFFS_OK : YAFFS_FAIL;
}
static int yramsim_mark_block_bad(struct yaffs_dev *dev,unsigned blockId)
u32 start_block, u32 end_block)
{
SimData *sim;
- struct ynandif_Geometry *g;
+ struct yaffs_dev *dev;
+ struct yaffs_param *p;
+ struct yaffs_driver *d;
sim = yramsim_alloc_sim_data(devId, nBlocks);
- g = malloc(sizeof(*g));
+ dev = malloc(sizeof(*dev));
- if(!sim || !g){
- if(g)
- free(g);
+ if(!sim || !dev){
+ free(sim);
+ free(dev);
return NULL;
}
+
+ memset(dev, 0, sizeof(*dev));
if(start_block >= sim->nBlocks)
start_block = 0;
if(end_block == 0 || end_block >= sim->nBlocks)
end_block = sim->nBlocks - 1;
- memset(g,0,sizeof(*g));
- g->start_block = start_block;
- g->end_block = end_block;
- g->dataSize = DATA_SIZE;
- g->spareSize= SPARE_SIZE;
- g->pagesPerBlock = PAGES_PER_BLOCK;
- g->hasECC = 1;
- g->inband_tags = 0;
- g->useYaffs2 = 1;
- g->initialise = yramsim_initialise;
- g->deinitialise = yramsim_deinitialise;
- g->readChunk = yramsim_rd_chunk,
- g->writeChunk = yramsim_wr_chunk,
- g->eraseBlock = yramsim_erase,
- g->checkBlockOk = yramsim_check_block_ok,
- g->markBlockBad = yramsim_mark_block_bad,
- g->privateData = (void *)sim;
-
- return yaffs_add_dev_from_geometry(name,g);
+ p = &dev->param;
+ p->name = strdup(name);
+ p->start_block = start_block;
+ p->end_block = end_block;
+ p->total_bytes_per_chunk = DATA_SIZE;
+ p->spare_bytes_per_chunk= SPARE_SIZE;
+ p->chunks_per_block = PAGES_PER_BLOCK;
+ p->n_reserved_blocks = 2;
+ p->use_nand_ecc = 1;
+ p->inband_tags = 0;
+ p->is_yaffs2 = 1;
+
+ d= &dev->drv;
+ d->drv_initialise_fn = yramsim_initialise;
+ d->drv_deinitialise_fn = yramsim_deinitialise;
+ d->drv_read_chunk_fn = yramsim_rd_chunk;
+ d->drv_write_chunk_fn = yramsim_wr_chunk;
+ d->drv_erase_fn = yramsim_erase;
+ d->drv_check_bad_fn = yramsim_check_block_bad;
+ d->drv_mark_bad_fn = yramsim_mark_block_bad;
+
+ dev->driver_context= (void *)sim;
+
+ return dev;
}
}
/* Check file permissions */
- if (readRequested && !(obj->yst_mode & S_IREAD))
+ if (readRequested && !(obj->yst_mode & S_IRUSR))
openDenied = 1;
- if (writeRequested && !(obj->yst_mode & S_IWRITE))
+ if (writeRequested && !(obj->yst_mode & S_IWUSR))
openDenied = 1;
if (!errorReported && writeRequested &&
return yaffs_unlink_reldir(NULL, path);
}
+int yaffs_funlink(int fd)
+{
+ struct yaffs_obj *obj;
+ int retVal = -1;
+
+ yaffsfs_Lock();
+ obj = yaffsfs_HandleToObject(fd);
+
+ if (!obj)
+ 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)
+ yaffsfs_SetError(-EBUSY); /* Can't rmdir a root */
+ else if (yaffs_unlink_obj(oobj) == YAFFS_OK)
+ retVal = 0;
+
+ yaffsfs_Unlock();
+
+ return retVal;
+}
+
+
static int rename_file_over_dir(struct yaffs_obj *obj, struct yaffs_obj *newobj)
{
if (obj && obj->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY &&
else {
int access_ok = 1;
- if ((amode & R_OK) && !(obj->yst_mode & S_IREAD))
+ if ((amode & R_OK) && !(obj->yst_mode & S_IRUSR))
access_ok = 0;
- if ((amode & W_OK) && !(obj->yst_mode & S_IWRITE))
+ if ((amode & W_OK) && !(obj->yst_mode & S_IWUSR))
access_ok = 0;
- if ((amode & X_OK) && !(obj->yst_mode & S_IEXEC))
+ if ((amode & X_OK) && !(obj->yst_mode & S_IXUSR))
access_ok = 0;
if (!access_ok)
return yaffs_mount_common(NULL, path, 0, 0);
}
-int yaffs_sync_common(struct yaffs_dev *dev, const YCHAR *path)
+static int yaffs_sync_common(struct yaffs_dev *dev,
+ const YCHAR *path,
+ int do_checkpt)
{
int retVal = -1;
YCHAR *dummy;
else {
yaffs_flush_whole_cache(dev, 0);
- yaffs_checkpoint_save(dev);
+ if (do_checkpt)
+ yaffs_checkpoint_save(dev);
retVal = 0;
}
return retVal;
}
+int yaffs_sync_files_reldev(struct yaffs_dev *dev)
+{
+ return yaffs_sync_common(dev, NULL, 0);
+}
+
+int yaffs_sync_files(const YCHAR *path)
+{
+ return yaffs_sync_common(NULL, path, 0);
+}
+
int yaffs_sync_reldev(struct yaffs_dev *dev)
{
- return yaffs_sync_common(dev, NULL);
+ return yaffs_sync_common(dev, NULL, 1);
}
int yaffs_sync(const YCHAR *path)
{
- return yaffs_sync_common(NULL, path);
+ return yaffs_sync_common(NULL, path, 1);
}
return 0;
}
+
int yaffs_closedir(yaffs_DIR *dirp)
{
int ret;
return 0;
}
+struct yaffs_obj * yaffs_get_obj_from_fd(int handle)
+{
+ return yaffsfs_HandleToObject(handle);
+}
+
int yaffs_dump_dev_reldir(struct yaffs_obj *reldir, const YCHAR *path)
{
#if 1
int yaffs_pread(int fd, void *buf, unsigned int nbyte, Y_LOFF_T offset);
int yaffs_pwrite(int fd, const void *buf, unsigned int nbyte, Y_LOFF_T offset);
-Y_LOFF_T yaffs_lseek(int fd, Y_LOFF_T offset, int whence) ;
+Y_LOFF_T yaffs_lseek(int fd, Y_LOFF_T offset, int whence);
int yaffs_truncate(const YCHAR *path, Y_LOFF_T new_size);
int yaffs_ftruncate(int fd, Y_LOFF_T new_size);
-int yaffs_unlink(const YCHAR *path) ;
+int yaffs_unlink(const YCHAR *path);
+int yaffs_funlink(int fd);
+
int yaffs_rename(const YCHAR *oldPath, const YCHAR *newPath) ;
int yaffs_stat(const YCHAR *path, struct yaffs_stat *buf) ;
int force_unmount_flag,
int remount_flag);
-int yaffs_sync(const YCHAR *path) ;
+/*
+ * yaffs_sync() does a full sync, including checkpoint.
+ * yaffs_sync_files() just flushes the cache and does not write a checkpoint.
+ */
+int yaffs_sync(const YCHAR *path);
+int yaffs_sync_files(const YCHAR *path) ;
int yaffs_symlink(const YCHAR *oldpath, const YCHAR *newpath);
int yaffs_readlink(const YCHAR *path, YCHAR *buf, int bufsiz);
/* Function variants that use a relative device */
struct yaffs_dev;
+int yaffs_mount_reldev(struct yaffs_dev *dev);
int yaffs_open_sharing_reldev(struct yaffs_dev *dev, const YCHAR *path, int oflag, int mode, int sharing);
int yaffs_open_reldev(struct yaffs_dev *dev,const YCHAR *path, int oflag, int mode);
int yaffs_truncate_reldev(struct yaffs_dev *dev, const YCHAR *path, Y_LOFF_T new_size);
Y_LOFF_T yaffs_freespace_reldev(struct yaffs_dev *dev);
Y_LOFF_T yaffs_totalspace_reldev(struct yaffs_dev *dev);
+/*
+ * yaffs_sync_reldev() does a full sync, including checkpoint.
+ * yaffs_sync_files_reldev() just flushes the cache and does not write a checkpoint.
+ */
int yaffs_sync_reldev(struct yaffs_dev *dev);
+int yaffs_sync_files_reldev(struct yaffs_dev *dev);
+
int yaffs_unmount_reldev(struct yaffs_dev *dev);
int yaffs_unmount2_reldev(struct yaffs_dev *dev, int force);
int yaffs_remount_reldev(struct yaffs_dev *dev, int force, int read_only);
+/*
+ * Non standard function to get at objects.
+ */
+struct yaffs_obj * yaffs_get_obj_from_fd(int handle);
/* Some non-standard functions to use fds to access directories */
struct yaffs_dirent *yaffs_readdir_fd(int fd);
-#ifndef S_IREAD
-#define S_IREAD 0000400
+#ifndef S_IRUSR
+#define S_IRUSR 0000400
#endif
-#ifndef S_IWRITE
-#define S_IWRITE 0000200
+#ifndef S_IWUSR
+#define S_IWUSR 0000200
#endif
#ifndef S_IEXEC
#define S_IEXEC 0000100
#endif
+#else
+#include <errno.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#endif
+
+#endif
+
+/* Create some less common define values if they don't exist */
#ifndef XATTR_CREATE
#define XATTR_CREATE 1
#endif
#define F_OK 0
#endif
-#else
-#include <errno.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#endif
-
+#ifndef S_ISSOCK
+#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
#endif
#ifndef Y_DUMP_STACK