/*
* YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
*
- * Copyright (C) 2002-2007 Aleph One Ltd.
+ * Copyright (C) 2002-2010 Aleph One Ltd.
* for Toby Churchill Ltd and Brightstar Engineering
*
* Created by Charles Manning <charles@aleph1.co.uk>
#define YAFFSFS_RW_SIZE (1<<YAFFSFS_RW_SHIFT)
-const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.33 2010-02-16 23:24:57 charles Exp $";
+const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.35 2010-02-25 22:38:03 charles Exp $";
// configurationList is the list of devices that are supported
static yaffsfs_DeviceConfiguration *yaffsfs_configurationList;
typedef struct{
__u8 readOnly:1; // this handle is read only
__u8 append:1; // append only
- __u8 exclusive:1; // exclusive
int inodeId:13; // the object
int useCount:16; // Use count for this handle
__u32 position; // current position in file
YCHAR *name;
int handle = -1;
yaffsfs_Handle *h = NULL;
- int alreadyOpen = 0;
- int alreadyExclusive = 0;
int openDenied = 0;
int symDepth = 0;
int errorReported = 0;
- int i;
+ /* O_EXCL only has meaning if O_CREAT is specified */
+ if(!(oflag & O_CREAT))
+ oflag &= ~(O_EXCL);
+ /* O_TRUNC has no meaning if (O_CREAT | O_EXCL) is specified */
+ if( (oflag & O_CREAT) & (oflag & O_EXCL))
+ oflag &= ~(O_TRUNC);
- // todo sanity check oflag (eg. can't have O_TRUNC without WRONLY or RDWR
+ /* Todo: Are there any more flag combos to sanitise ? */
yaffsfs_Lock();
obj = NULL;
if(obj){
- // Check if the object is already in use
- alreadyOpen = alreadyExclusive = 0;
-
- for(i = 0; i < YAFFSFS_N_HANDLES; i++){
- if(i != handle &&
- yaffsfs_handle[i].useCount > 0 &&
- obj == yaffsfs_inode[yaffsfs_handle[i].inodeId].iObj){
- alreadyOpen = 1;
- if(yaffsfs_handle[i].exclusive)
- alreadyExclusive = 1;
- }
- }
- if(((oflag & O_EXCL) && alreadyOpen) || alreadyExclusive)
- openDenied = 1;
+ /* The file already exists */
- // Open should fail if O_CREAT and O_EXCL are specified
+ // Open should fail if O_CREAT and O_EXCL are specified since
+ // the file exists
if((oflag & O_EXCL) && (oflag & O_CREAT)){
openDenied = 1;
yaffsfs_SetError(-EEXIST);
h->inodeId = inodeId;
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;
/* Hook inode to object */
-int yaffsfs_do_read(int fd, void *buf, unsigned int nbyte, int isPread, int offset)
+int yaffsfs_do_read(int fd, void *vbuf, unsigned int nbyte, int isPread, int offset)
{
yaffsfs_Handle *h = NULL;
yaffs_Object *obj = NULL;
int nToRead = 0;
int totalRead = 0;
unsigned int maxRead;
+ __u8 *buf = (__u8 *)vbuf;
yaffsfs_Lock();
h = yaffsfs_GetHandlePointer(fd);
startPos = offset;
else
startPos = h->position;
-
+
+ pos = startPos;
+
if(yaffs_GetObjectFileLength(obj) > pos)
maxRead = yaffs_GetObjectFileLength(obj) - pos;
else
nbyte = maxRead;
- if(nbyte > 0) {
- yaffsfs_GetHandle(fd);
- pos = startPos;
-
- while(nbyte > 0) {
- nToRead = YAFFSFS_RW_SIZE - (pos & (YAFFSFS_RW_SIZE -1));
- if(nToRead > nbyte)
- nToRead = nbyte;
+ yaffsfs_GetHandle(fd);
- nRead = yaffs_ReadDataFromFile(obj,buf,pos,nToRead);
+ while(nbyte > 0) {
+ nToRead = YAFFSFS_RW_SIZE - (pos & (YAFFSFS_RW_SIZE -1));
+ if(nToRead > nbyte)
+ nToRead = nbyte;
+ nRead = yaffs_ReadDataFromFile(obj,buf,pos,nToRead);
- if(nRead > 0){
- totalRead += nRead;
- pos += nRead;
- buf += nRead;
- }
+ if(nRead > 0){
+ totalRead += nRead;
+ pos += nRead;
+ buf += nRead;
+ }
- if(nRead == nToRead)
- nbyte-=nRead;
- else
- nbyte = 0; /* no more to read */
+ if(nRead == nToRead)
+ nbyte-=nRead;
+ else
+ nbyte = 0; /* no more to read */
- if(nbyte > 0){
- yaffsfs_Unlock();
- yaffsfs_Lock();
- }
-
+ if(nbyte > 0){
+ yaffsfs_Unlock();
+ yaffsfs_Lock();
}
- yaffsfs_PutHandle(fd);
- if(!isPread) {
- if(totalRead >= 0)
- h->position = startPos + totalRead;
- else {
+ }
+
+ yaffsfs_PutHandle(fd);
+
+ if(!isPread) {
+ if(totalRead >= 0)
+ h->position = startPos + totalRead;
+ else {
//todo error
- }
}
- } else
- totalRead = 0;
+ }
}
return yaffsfs_do_read(fd, buf, nbyte, 1, offset);
}
-int yaffsfs_do_write(int fd, const void *buf, unsigned int nbyte, int isPwrite, int offset)
+int yaffsfs_do_write(int fd, const void *vbuf, unsigned int nbyte, int isPwrite, int offset)
{
yaffsfs_Handle *h = NULL;
yaffs_Object *obj = NULL;
int totalWritten = 0;
int writeThrough = 0;
int nToWrite = 0;
+ const __u8 *buf = (const __u8 *)vbuf;
yaffsfs_Lock();
h = yaffsfs_GetHandlePointer(fd);
startPos = yaffs_GetObjectFileLength(obj);
else
startPos = h->position;
- if( nbyte > 0){
- yaffsfs_GetHandle(fd);
- pos = startPos;
- while(nbyte > 0) {
- nToWrite = YAFFSFS_RW_SIZE - (pos & (YAFFSFS_RW_SIZE -1));
- if(nToWrite > nbyte)
- nToWrite = nbyte;
-
- nWritten = yaffs_WriteDataToFile(obj,buf,pos,nToWrite,writeThrough);
- if(nWritten > 0){
- totalWritten += nWritten;
- pos += nWritten;
- buf += nWritten;
- }
- if(nWritten == nToWrite)
- nbyte -= nToWrite;
- else
- nbyte = 0;
-
- if(nWritten < 1 && totalWritten < 1){
- yaffsfs_SetError(-ENOSPC);
- totalWritten = -1;
- }
-
- if(nbyte > 0){
- yaffsfs_Unlock();
- yaffsfs_Lock();
- }
+ yaffsfs_GetHandle(fd);
+ pos = startPos;
+ while(nbyte > 0) {
+ nToWrite = YAFFSFS_RW_SIZE - (pos & (YAFFSFS_RW_SIZE -1));
+ if(nToWrite > nbyte)
+ nToWrite = nbyte;
+
+ nWritten = yaffs_WriteDataToFile(obj,buf,pos,nToWrite,writeThrough);
+ if(nWritten > 0){
+ totalWritten += nWritten;
+ pos += nWritten;
+ buf += nWritten;
}
- yaffsfs_PutHandle(fd);
+ if(nWritten == nToWrite)
+ nbyte -= nToWrite;
+ else
+ nbyte = 0;
- if(!isPwrite){
- if(totalWritten > 0)
- h->position = startPos + totalWritten;
- else {
- //todo error
- }
+ if(nWritten < 1 && totalWritten < 1){
+ yaffsfs_SetError(-ENOSPC);
+ totalWritten = -1;
}
- } else
- totalWritten = 0;
+ if(nbyte > 0){
+ yaffsfs_Unlock();
+ yaffsfs_Lock();
+ }
+ }
+
+ yaffsfs_PutHandle(fd);
+
+ if(!isPwrite){
+ if(totalWritten > 0)
+ h->position = startPos + totalWritten;
+ else {
+ //todo error
+ }
+ }
}
yaffsfs_Unlock();
return (totalWritten >= 0) ? totalWritten : -1;
-
}
int yaffs_write(int fd, const void *buf, unsigned int nbyte)
obj = yaffs_GetEquivalentObject(obj);
if(obj && buf){
- buf->st_dev = (int)obj->myDev->genericDevice;
+ buf->st_dev = (int)obj->myDev->context;
buf->st_ino = obj->objectId;
buf->st_mode = obj->yst_mode & ~S_IFMT; // clear out file type bits
yaffsfs_Lock();
dev = yaffsfs_FindDevice(path,&dummy);
if(dev && dev->isMounted){
- retVal = (dev->endBlock - dev->startBlock + 1) - dev->nReservedBlocks;
- retVal *= dev->nChunksPerBlock;
+ retVal = (dev->param.endBlock - dev->param.startBlock + 1) - dev->param.nReservedBlocks;
+ retVal *= dev->param.nChunksPerBlock;
retVal *= dev->nDataBytesPerChunk;
} else
while(cfg && cfg->prefix && cfg->dev){
cfg->dev->isMounted = 0;
- cfg->dev->removeObjectCallback = yaffsfs_RemoveObjectCallback;
+ cfg->dev->param.removeObjectCallback = yaffsfs_RemoveObjectCallback;
cfg++;
}