diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-05-05 18:21:44 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-05-05 18:21:44 +0000 |
commit | fe8430b28928dd36a9d881b4f02ce56d91dec6a0 (patch) | |
tree | 4aac5e15a1f92756064fb8cbc477ea761457b536 /nuttx | |
parent | 697ebec39680857ebbf7537e38a88b1370b7c23f (diff) | |
download | px4-nuttx-fe8430b28928dd36a9d881b4f02ce56d91dec6a0.tar.gz px4-nuttx-fe8430b28928dd36a9d881b4f02ce56d91dec6a0.tar.bz2 px4-nuttx-fe8430b28928dd36a9d881b4f02ce56d91dec6a0.zip |
NXFFS is basically functional -- more testing needed
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3565 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx')
-rw-r--r-- | nuttx/fs/nxffs/nxffs.h | 28 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_dirent.c | 11 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_initialize.c | 13 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_inode.c | 64 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_pack.c | 169 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_read.c | 6 |
6 files changed, 191 insertions, 100 deletions
diff --git a/nuttx/fs/nxffs/nxffs.h b/nuttx/fs/nxffs/nxffs.h index 735e4fc0a..262c8577e 100644 --- a/nuttx/fs/nxffs/nxffs.h +++ b/nuttx/fs/nxffs/nxffs.h @@ -177,7 +177,6 @@ #define NXFFS_MINDATA 16 - /* Internal definitions *****************************************************/ /* If we encounter this number of erased bytes, we assume that all of the * flash beyond this point is erased. @@ -641,6 +640,33 @@ extern int nxffs_findinode(FAR struct nxffs_volume_s *volume, FAR struct nxffs_entry_s *entry); /**************************************************************************** + * Name: nxffs_inodeend + * + * Description: + * Return an *approximiate* FLASH offset to end of the inode data. The + * returned value is guaranteed to be be less then or equal to the offset + * of the thing-of-interest in FLASH. Parsing for interesting things + * can begin at that point. + * + * Assumption: The inode header has been verified by the caller and is + * known to contain valid data. + * + * Input Parameters: + * volume - Describes the NXFFS volume + * entry - Describes the inode. + * + * Returned Value: + * A FLASH offset to the (approximate) end of the inode data. No errors + * are detected. + * + * Defined in nxffs_inode.c + * + ****************************************************************************/ + +extern off_t nxffs_inodeend(FAR struct nxffs_volume_s *volume, + FAR struct nxffs_entry_s *entry); + +/**************************************************************************** * Name: nxffs_verifyblock * * Description: diff --git a/nuttx/fs/nxffs/nxffs_dirent.c b/nuttx/fs/nxffs/nxffs_dirent.c index bd53ffe0c..40ae8662f 100644 --- a/nuttx/fs/nxffs/nxffs_dirent.c +++ b/nuttx/fs/nxffs/nxffs_dirent.c @@ -166,14 +166,9 @@ int nxffs_readdir(FAR struct inode *mountpt, FAR struct fs_dirent_s *dir) dir->fd_dir.d_type = DTYPE_FILE; strncpy(dir->fd_dir.d_name, entry.name, NAME_MAX+1); - /* Discard this entry and set the next offset using the rw data - * length as the offset increment. This is, of course, not accurate - * because it does not account for the data headers that enclose the - * data. But it is guaranteed to be less than or equal to the - * correct offset and, hence, better then searching byte-for-byte. - */ - - dir->u.nxffs.nx_offset = entry.doffset + entry.datlen; + /* Discard this entry and set the next offset. */ + + dir->u.nxffs.nx_offset = nxffs_inodeend(volume, &entry); nxffs_freeentry(&entry); ret = OK; } diff --git a/nuttx/fs/nxffs/nxffs_initialize.c b/nuttx/fs/nxffs/nxffs_initialize.c index c040fa649..7fd1d51fc 100644 --- a/nuttx/fs/nxffs/nxffs_initialize.c +++ b/nuttx/fs/nxffs/nxffs_initialize.c @@ -361,14 +361,9 @@ int nxffs_limits(FAR struct nxffs_volume_s *volume) volume->inoffset = entry.hoffset; fvdbg("First inode at offset %d\n", volume->inoffset); - /* Discard this entry and set the next offset using the rw data - * length as the offset increment. This is, of course, not accurate - * because it does not account for the data headers that enclose the - * data. But it is guaranteed to be less than or equal to the - * correct offset and, hence, better then searching byte-for-byte. - */ + /* Discard this entry and set the next offset. */ - offset = entry.doffset + entry.datlen; + offset = nxffs_inodeend(volume, &entry); nxffs_freeentry(&entry); } @@ -378,9 +373,9 @@ int nxffs_limits(FAR struct nxffs_volume_s *volume) { while ((ret = nxffs_nextentry(volume, offset, &entry)) == OK) { - /* Discard the entry and guess the next offset (see comments above). */ + /* Discard the entry and guess the next offset. */ - offset = entry.doffset + entry.datlen; + offset = nxffs_inodeend(volume, &entry); nxffs_freeentry(&entry); } fvdbg("Last inode before offset %d\n", offset); diff --git a/nuttx/fs/nxffs/nxffs_inode.c b/nuttx/fs/nxffs/nxffs_inode.c index 361b5df7e..121c1f6db 100644 --- a/nuttx/fs/nxffs/nxffs_inode.c +++ b/nuttx/fs/nxffs/nxffs_inode.c @@ -181,11 +181,11 @@ static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset, if (state != INODE_STATE_FILE) { /* It is a deleted file. But still, the data offset and the - * start size is good so we can use this information to advance + * start size are good so we can use this information to advance * further in FLASH memory and reduce the search time. */ - offset = entry->doffset + entry->datlen + SIZEOF_NXFFS_DATA_HDR; + offset = nxffs_inodeend(volume, entry); nxffs_freeentry(entry); ret = -ENOENT; goto errout; @@ -432,7 +432,7 @@ int nxffs_findinode(FAR struct nxffs_volume_s *volume, FAR const char *name, * byte-for-byte. */ - offset = entry->doffset + entry->datlen; + offset = nxffs_inodeend(volume, entry); nxffs_freeentry(entry); } @@ -440,3 +440,61 @@ int nxffs_findinode(FAR struct nxffs_volume_s *volume, FAR const char *name, return -ENOENT; } + +/**************************************************************************** + * Name: nxffs_inodeend + * + * Description: + * Return an *approximiate* FLASH offset to end of the inode data. The + * returned value is guaranteed to be be less then or equal to the offset + * of the thing-of-interest in FLASH. Parsing for interesting things + * can begin at that point. + * + * Assumption: The inode header has been verified by the caller and is + * known to contain valid data. + * + * Input Parameters: + * volume - Describes the NXFFS volume + * entry - Describes the inode. + * + * Returned Value: + * A FLASH offset to the (approximate) end of the inode data. No errors + * are detected. + * + ****************************************************************************/ + +off_t nxffs_inodeend(FAR struct nxffs_volume_s *volume, + FAR struct nxffs_entry_s *entry) +{ + /* A zero length file will have no data blocks */ + + if (entry->doffset) + { + /* This is the maximum size of one data block */ + + uint16_t maxsize = volume->geo.blocksize - SIZEOF_NXFFS_DATA_HDR; + + /* This is the minimum number of blocks require to span all of the + * inode data. One additional block could possibly be required -- we + * could make this accurate by looking at the size of the first, perhaps + * partial, data block. + */ + + off_t minblocks = (entry->datlen + maxsize - 1) / maxsize; + + /* And this is our best, simple guess at the end of the inode data */ + + return entry->doffset + entry->datlen + minblocks * SIZEOF_NXFFS_DATA_HDR; + } + + /* Otherwise, return an offset that accounts only for the inode header and + * the inode name. + */ + + /* All valid inodes will have a name associated with them */ + + DEBUGASSERT(entry->noffset); + return entry->noffset + strlen(entry->name); +} + + diff --git a/nuttx/fs/nxffs/nxffs_pack.c b/nuttx/fs/nxffs/nxffs_pack.c index d4a7d5f39..212d2b429 100644 --- a/nuttx/fs/nxffs/nxffs_pack.c +++ b/nuttx/fs/nxffs/nxffs_pack.c @@ -399,7 +399,8 @@ static inline int nxffs_startpos(FAR struct nxffs_volume_s *volume, * Input Parameters: * volume - The volume to be packed * pack - The volume packing state structure. - * offset - FLASH offset to the data block header + * offset - FLASH offset to the data block header (will be zero for zero- + * files. * * Returned Values: * Zero on success; Otherwise, a negated errno value is returned to @@ -410,22 +411,27 @@ static inline int nxffs_startpos(FAR struct nxffs_volume_s *volume, static int nxffs_srcsetup(FAR struct nxffs_volume_s *volume, FAR struct nxffs_pack_s *pack, off_t offset) { - int ret; - - /* No, start with the first data block */ + /* Start with the first data block */ pack->src.blkoffset = offset; pack->src.blkpos = 0; - /* Seek to the data block header, read and verify the block header */ + /* Zero-length files have no valid data block offset */ - ret = nxffs_rdblkhdr(volume, offset, &pack->src.blklen); - if (ret < 0) + if (offset > 0) { - fdbg("Failed to verify the data block header: %d\n", -ret); + /* Seek to the data block header, read and verify the block header */ + + int ret = nxffs_rdblkhdr(volume, offset, &pack->src.blklen); + if (ret < 0) + { + fdbg("Failed to verify the data block header: %d\n", -ret); + } + return ret; } - return ret; + DEBUGASSERT(pack->src.entry.datlen == 0); + return OK; } /**************************************************************************** @@ -449,6 +455,7 @@ static int nxffs_destsetup(FAR struct nxffs_volume_s *volume, { size_t mindata; int namlen; + int ret; /* The destination can be in one of three of states: * @@ -516,66 +523,77 @@ static int nxffs_destsetup(FAR struct nxffs_volume_s *volume, /* State 3: Inode header not-written, inode name written. Still need the position * of the first data block. + * + * Deal with the special case where the source inode is a zero length file + * with no data blocks to be transferred. */ - if (pack->dest.entry.doffset == 0) + if (pack->src.entry.doffset > 0) { - /* Will the data block header plus a minimal amount of data fit in this - * block? (or the whole file if the file is very small). - */ - - mindata = MIN(NXFFS_MINDATA, pack->dest.entry.datlen); - if (pack->iooffset + SIZEOF_NXFFS_DATA_HDR + mindata > volume->geo.blocksize) + if (pack->dest.entry.doffset == 0) { - /* No.. return an indication that we are at the end of the block - * and try again later. + /* Will the data block header plus a minimal amount of data fit in this + * block? (or the whole file if the file is very small). */ - return -ENOSPC; - } + mindata = MIN(NXFFS_MINDATA, pack->dest.entry.datlen); + if (pack->iooffset + SIZEOF_NXFFS_DATA_HDR + mindata > volume->geo.blocksize) + { + /* No.. return an indication that we are at the end of the block + * and try again later. + */ - /* Yes.. reserve space for the data block header */ + ret = -ENOSPC; + goto errout; + } - pack->dest.entry.doffset = nxffs_packtell(volume, pack); - pack->iooffset += SIZEOF_NXFFS_DATA_HDR; + /* Yes.. reserve space for the data block header */ - /* Initialize the output data stream to start with the first data block */ + pack->dest.entry.doffset = nxffs_packtell(volume, pack); + pack->iooffset += SIZEOF_NXFFS_DATA_HDR; - pack->dest.blkoffset = pack->dest.entry.doffset; - pack->dest.blklen = 0; - pack->dest.blkpos = 0; - } + /* Initialize the output data stream to start with the first data block */ - /* State 4: Starting a new block. Verify that there is space in the current - * block for another (minimal sized) block - */ + pack->dest.blkoffset = pack->dest.entry.doffset; + pack->dest.blklen = 0; + pack->dest.blkpos = 0; + } - if (pack->dest.blkoffset == 0) - { - /* Will the data block header plus a minimal amount of data fit in this - * block? (or the whole file if the file is very small). + /* State 4: Starting a new block. Verify that there is space in the current + * block for another (minimal sized) block */ - mindata = MIN(NXFFS_MINDATA, pack->dest.entry.datlen); - if (pack->iooffset + SIZEOF_NXFFS_DATA_HDR + mindata > volume->geo.blocksize) + if (pack->dest.blkoffset == 0) { - /* No.. return an indication that we are at the end of the block - * and try again later. + /* Will the data block header plus a minimal amount of data fit in this + * block? (or the whole file if the file is very small). */ - return -ENOSPC; - } + mindata = MIN(NXFFS_MINDATA, pack->dest.entry.datlen); + if (pack->iooffset + SIZEOF_NXFFS_DATA_HDR + mindata > volume->geo.blocksize) + { + /* No.. return an indication that we are at the end of the block + * and try again later. + */ + + ret = -ENOSPC; + goto errout; + } - /* Yes.. reserve space for the data block header */ + /* Yes.. reserve space for the data block header */ - pack->dest.blkoffset = nxffs_packtell(volume, pack); - pack->iooffset += SIZEOF_NXFFS_DATA_HDR; - pack->dest.blklen = 0; - pack->dest.blkpos = 0; + pack->dest.blkoffset = nxffs_packtell(volume, pack); + pack->iooffset += SIZEOF_NXFFS_DATA_HDR; + pack->dest.blklen = 0; + pack->dest.blkpos = 0; + } } + ret = OK; + +errout: volume->froffset = nxffs_packtell(volume, pack); - return OK; + return ret; } /**************************************************************************** @@ -806,19 +824,22 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume, /* Transfer the smaller of the two amounts data */ uint16_t xfrlen = MIN(srclen, destlen); - nxffs_ioseek(volume, pack->src.blkoffset + SIZEOF_NXFFS_DATA_HDR + pack->src.blkpos); - memcpy(&pack->iobuffer[pack->iooffset], &volume->cache[volume->iooffset], xfrlen); - - /* Increment counts and offset for this data transfer */ - - pack->src.fpos += xfrlen; /* Source data offsets */ - pack->src.blkpos += xfrlen; - pack->dest.fpos += xfrlen; /* Destination data offsets */ - pack->dest.blkpos += xfrlen; - pack->dest.blklen += xfrlen; /* Destination data block size */ - pack->iooffset += xfrlen; /* Destination I/O block offset */ - volume->iooffset += xfrlen; /* Source I/O block offset */ - volume->froffset += xfrlen; /* Free FLASH offset */ + if (xfrlen > 0) + { + nxffs_ioseek(volume, pack->src.blkoffset + SIZEOF_NXFFS_DATA_HDR + pack->src.blkpos); + memcpy(&pack->iobuffer[pack->iooffset], &volume->cache[volume->iooffset], xfrlen); + + /* Increment counts and offset for this data transfer */ + + pack->src.fpos += xfrlen; /* Source data offsets */ + pack->src.blkpos += xfrlen; + pack->dest.fpos += xfrlen; /* Destination data offsets */ + pack->dest.blkpos += xfrlen; + pack->dest.blklen += xfrlen; /* Destination data block size */ + pack->iooffset += xfrlen; /* Destination I/O block offset */ + volume->iooffset += xfrlen; /* Source I/O block offset */ + volume->froffset += xfrlen; /* Free FLASH offset */ + } /* Now, either the (1) src block has been fully transferred, (2) all * of the source data has been transferred, or (3) the the destination @@ -839,7 +860,9 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume, /* Find the next valid source inode */ offset = pack->src.blkoffset + pack->src.blklen; - ret = nxffs_nextentry(volume, offset, &pack->src.entry); + memset(&pack->src, 0, sizeof(struct nxffs_packstream_s)); + + ret = nxffs_nextentry(volume, offset, &pack->src.entry); if (ret < 0) { /* No more valid inode entries. Just return an end-of-flash error @@ -859,16 +882,11 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume, /* Setup the dest stream */ - pack->dest.entry.hoffset = 0; - pack->dest.entry.noffset = 0; - pack->dest.entry.doffset = 0; - pack->dest.entry.name = pack->src.entry.name; - pack->dest.entry.utc = pack->src.entry.utc; - pack->dest.entry.datlen = pack->src.entry.datlen; - pack->dest.blkoffset = 0; - pack->dest.blklen = 0; - pack->dest.blkpos = 0; - pack->src.entry.name = NULL; + memset(&pack->dest, 0, sizeof(struct nxffs_packstream_s)); + pack->dest.entry.name = pack->src.entry.name; + pack->dest.entry.utc = pack->src.entry.utc; + pack->dest.entry.datlen = pack->src.entry.datlen; + pack->src.entry.name = NULL; /* Is there sufficient space at the end of the I/O block to hold * the inode header? @@ -883,14 +901,7 @@ static inline int nxffs_packblock(FAR struct nxffs_volume_s *volume, return OK; } - /* Set the current inode header off to the current position and reserve - * the memory. - */ - - pack->dest.entry.hoffset = nxffs_packtell(volume, pack); - pack->iooffset += SIZEOF_NXFFS_INODE_HDR; - - /* Then configure the destination stream */ + /* Configure the destination stream */ ret = nxffs_destsetup(volume, pack); if (ret < 0) diff --git a/nuttx/fs/nxffs/nxffs_read.c b/nuttx/fs/nxffs/nxffs_read.c index f52e21859..cf9bf78e0 100644 --- a/nuttx/fs/nxffs/nxffs_read.c +++ b/nuttx/fs/nxffs/nxffs_read.c @@ -101,6 +101,12 @@ static ssize_t nxffs_rdseek(FAR struct nxffs_volume_s *volume, */ offset = entry->doffset; + if (offset == 0) + { + /* Zero length files will have no data blocks */ + + return -ENOSPC; + } /* Loop until we read the data block containing the desired position */ |