diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-05-02 16:14:20 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-05-02 16:14:20 +0000 |
commit | bbeba1fded523a5e2f7d71f3ad003a8c7c5c9351 (patch) | |
tree | 60a0d60420ac62e366ee61bc30a60c6743378d18 | |
parent | 6e723db07e440e19453f35e8e3a3850e3b4d7373 (diff) | |
download | nuttx-bbeba1fded523a5e2f7d71f3ad003a8c7c5c9351.tar.gz nuttx-bbeba1fded523a5e2f7d71f3ad003a8c7c5c9351.tar.bz2 nuttx-bbeba1fded523a5e2f7d71f3ad003a8c7c5c9351.zip |
More NXFFS bugfixes
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3551 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r-- | apps/examples/nxffs/nxffs_main.c | 22 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs.h | 27 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_cache.c | 62 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_inode.c | 26 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_open.c | 20 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_read.c | 30 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_write.c | 6 |
7 files changed, 68 insertions, 125 deletions
diff --git a/apps/examples/nxffs/nxffs_main.c b/apps/examples/nxffs/nxffs_main.c index 8c12825fa..5b17bdba0 100644 --- a/apps/examples/nxffs/nxffs_main.c +++ b/apps/examples/nxffs/nxffs_main.c @@ -228,7 +228,7 @@ static inline int nxffs_wrfile(FAR struct nxffs_filedesc_s *file) nxffs_randname(file); nxffs_randfile(file); - fd = open(file->name, O_WRONLY, 0666); + fd = open(file->name, O_WRONLY | O_CREAT | O_EXCL, 0666); if (fd < 0) { fprintf(stderr, "Failed to open file for writing: %d\n", errno); @@ -254,7 +254,7 @@ static inline int nxffs_wrfile(FAR struct nxffs_filedesc_s *file) nbyteswritten = write(fd, &g_fileimage[offset], nbytestowrite); if (nbyteswritten < 0) { - fprintf(stderr, "Failed to write file: %d\n", errno); + fprintf(stderr, "ERROR: Failed to write file: %d\n", errno); fprintf(stderr, " File name: %s\n", file->name); fprintf(stderr, " File size: %d\n", file->len); fprintf(stderr, " Write offset: %d\n", offset); @@ -265,7 +265,7 @@ static inline int nxffs_wrfile(FAR struct nxffs_filedesc_s *file) } else if (nbyteswritten != nbytestowrite) { - fprintf(stderr, "Partial write:\n"); + fprintf(stderr, "ERROR: Partial write:\n"); fprintf(stderr, " File name: %s\n", file->name); fprintf(stderr, " File size: %d\n", file->len); fprintf(stderr, " Write offset: %d\n", offset); @@ -328,7 +328,7 @@ static ssize_t nxffs_rdblock(int fd, FAR struct nxffs_filedesc_s *file, nbytesread = read(fd, &g_fileimage[offset], len); if (nbytesread < 0) { - fprintf(stderr, "Failed to read file: %d\n", errno); + fprintf(stderr, "ERROR: Failed to read file: %d\n", errno); fprintf(stderr, " File name: %s\n", file->name); fprintf(stderr, " File size: %d\n", file->len); fprintf(stderr, " Read offset: %d\n", offset); @@ -338,7 +338,7 @@ static ssize_t nxffs_rdblock(int fd, FAR struct nxffs_filedesc_s *file, else if (nbytesread == 0) { #if 0 /* No... we do this on purpose sometimes */ - fprintf(stderr, "Unexpected end-of-file:\n"); + fprintf(stderr, "ERROR: Unexpected end-of-file:\n"); fprintf(stderr, " File name: %s\n", file->name); fprintf(stderr, " File size: %d\n", file->len); fprintf(stderr, " Read offset: %d\n", offset); @@ -348,7 +348,7 @@ static ssize_t nxffs_rdblock(int fd, FAR struct nxffs_filedesc_s *file, } else if (nbytesread != len) { - fprintf(stderr, "Partial read:\n"); + fprintf(stderr, "ERROR: Partial read:\n"); fprintf(stderr, " File name: %s\n", file->name); fprintf(stderr, " File size: %d\n", file->len); fprintf(stderr, " Read offset: %d\n", offset); @@ -374,7 +374,7 @@ static inline int nxffs_rdfile(FAR struct nxffs_filedesc_s *file) fd = open(file->name, O_RDONLY); if (fd < 0) { - fprintf(stderr, "Failed to open file for reading: %d\n", errno); + fprintf(stderr, "ERROR: Failed to open file for reading: %d\n", errno); fprintf(stderr, " File name: %s\n", file->name); fprintf(stderr, " File size: %d\n", file->len); return ERROR; @@ -399,7 +399,7 @@ static inline int nxffs_rdfile(FAR struct nxffs_filedesc_s *file) crc = crc32(g_fileimage, file->len); if (crc != file->crc) { - fprintf(stderr, "Bad CRC: %d vs %d\n", crc, file->crc); + fprintf(stderr, "ERROR: Bad CRC: %d vs %d\n", crc, file->crc); fprintf(stderr, " File name: %s\n", file->name); fprintf(stderr, " File size: %d\n", file->len); close(fd); @@ -411,7 +411,7 @@ static inline int nxffs_rdfile(FAR struct nxffs_filedesc_s *file) nbytesread = nxffs_rdblock(fd, file, ntotalread, 1024) ; if (nbytesread > 0) { - fprintf(stderr, "Read past the end of file\n"); + fprintf(stderr, "ERROR: Read past the end of file\n"); fprintf(stderr, " File name: %s\n", file->name); fprintf(stderr, " File size: %d\n", file->len); fprintf(stderr, " Bytes read: %d\n", nbytesread); @@ -452,7 +452,7 @@ static int nxffs_verifyfs(void) } else { - fprintf(stderr, "Failed to read a file: %d\n", i); + fprintf(stderr, "ERROR: Failed to read a file: %d\n", i); fprintf(stderr, " File name: %s\n", file->name); fprintf(stderr, " File size: %d\n", file->len); return ERROR; @@ -541,7 +541,7 @@ int user_start(int argc, char *argv[]) ret = nxffs_verifyfs(); if (ret < 0) { - fprintf(stderr, "Failed to verify files\n"); + fprintf(stderr, "ERROR: Failed to verify files\n"); fprintf(stderr, " Number of files: %d\n", g_nfiles); fprintf(stderr, " Number deleted: %d\n", g_ndeleted); } diff --git a/nuttx/fs/nxffs/nxffs.h b/nuttx/fs/nxffs/nxffs.h index 912e0db92..48311f3ec 100644 --- a/nuttx/fs/nxffs/nxffs.h +++ b/nuttx/fs/nxffs/nxffs.h @@ -247,7 +247,7 @@ struct nxffs_ofile_s { struct nxffs_ofile_s *flink; /* Supports a singly linked list */ int16_t crefs; /* Reference count */ - mode_t mode; /* Open mode */ + mode_t oflags; /* Open mode */ struct nxffs_entry_s entry; /* Describes the NXFFS inode entry */ }; @@ -552,31 +552,6 @@ extern off_t nxffs_iotell(FAR struct nxffs_volume_s *volume); extern int nxffs_getc(FAR struct nxffs_volume_s *volume); /**************************************************************************** - * Name: nxffs_rddata - * - * Description: - * Read a sequence of data bytes from the FLASH memory. This function - * allows the data in the formatted FLASH blocks to be read as a continuous - * byte stream, skipping over bad blocks and block headers as necessary. - * - * Input Parameters: - * volume - Describes the NXFFS volume. The paramters ioblock and iooffset - * in the volume structure determine the behavior of nxffs_getc(). - * buffer - A pointer to memory to receive the data read from FLASH. - * buflen - The maximum number of bytes to read from FLASH. - * - * Returned Value: - * The number of bytes read is returned on success. Otherwise, a negated - * errno indicating the nature of the failure. - * - * Defined in nxffs_cache.c - * - ****************************************************************************/ - -extern ssize_t nxffs_rddata(FAR struct nxffs_volume_s *volume, - FAR uint8_t *buffer, size_t buflen); - -/**************************************************************************** * Name: nxffs_freeentry * * Description: diff --git a/nuttx/fs/nxffs/nxffs_cache.c b/nuttx/fs/nxffs/nxffs_cache.c index f97d94c70..d88973813 100644 --- a/nuttx/fs/nxffs/nxffs_cache.c +++ b/nuttx/fs/nxffs/nxffs_cache.c @@ -234,7 +234,20 @@ int nxffs_getc(FAR struct nxffs_volume_s *volume) if (volume->iooffset >= volume->geo.blocksize) { - volume->ioblock++; + /* Check for attempt to read past the end of FLASH */ + + off_t nextblock = volume->ioblock + 1; + if (nextblock >= volume->nblocks) + { + fdbg("End of FLASH encountered\n"); + return -ENOSPC; + } + + /* Set up the seek to the data just after the header in the + * next block. + */ + + volume->ioblock = nextblock; volume->iooffset = SIZEOF_NXFFS_BLOCK_HDR; } @@ -251,7 +264,7 @@ int nxffs_getc(FAR struct nxffs_volume_s *volume) return ret; } } - while (ret == -ENOENT); + while (ret != OK); /* Return the the character at this offset. Note that on return, * iooffset could point to the byte outside of the current block. @@ -261,48 +274,3 @@ int nxffs_getc(FAR struct nxffs_volume_s *volume) volume->iooffset++; return ret; } - -/**************************************************************************** - * Name: nxffs_rddata - * - * Description: - * Read a sequence of data bytes from the FLASH memory. This function - * allows the data in the formatted FLASH blocks to be read as a continuous - * byte stream, skipping over bad blocks and block headers as necessary. - * - * Input Parameters: - * volume - Describes the NXFFS volume. The paramters ioblock and iooffset - * in the volume structure determine the behavior of nxffs_getc(). - * buffer - A pointer to memory to receive the data read from FLASH. - * buflen - The maximum number of bytes to read from FLASH. - * - * Returned Value: - * The number of bytes read is returned on success. Otherwise, a negated - * errno indicating the nature of the failure. - * - ****************************************************************************/ - -ssize_t nxffs_rddata(FAR struct nxffs_volume_s *volume, - FAR uint8_t *buffer, size_t buflen) -{ - size_t nbytes; - int ch; - - for (nbytes = buflen; nbytes > 0; nbytes--) - { - /* Read the next character (which could be in the next block) */ - - ch = nxffs_getc(volume); - if (ch < 0) - { - fdbg("Failed to read byte: %d\n", -ch); - return ch; - } - - /* Add the next character to the user buffer */ - - *buffer++ = (uint8_t)ch; - } - - return buflen; -} diff --git a/nuttx/fs/nxffs/nxffs_inode.c b/nuttx/fs/nxffs/nxffs_inode.c index 1e982c90d..3f8891f90 100644 --- a/nuttx/fs/nxffs/nxffs_inode.c +++ b/nuttx/fs/nxffs/nxffs_inode.c @@ -102,12 +102,7 @@ static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset, /* Read the header at the FLASH offset */ nxffs_ioseek(volume, offset); - ret = nxffs_rddata(volume, (FAR uint8_t *)&inode, SIZEOF_NXFFS_INODE_HDR); - if (ret < 0) - { - fdbg("Failed to read inode, offset %d: %d\n", offset, -ret); - return -EIO; - } + memcpy(&inode, &volume->cache[volume->iooffset], SIZEOF_NXFFS_INODE_HDR); /* Check if the file is marked as deleted. */ @@ -141,15 +136,24 @@ static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset, return -ENOMEM; } - /* Read the file name from the expected offset in FLASH */ + /* Seek to the expected location of the name in FLASH */ nxffs_ioseek(volume, entry->noffset); - ret = nxffs_rddata(volume, (FAR uint8_t*)entry->name, namlen); + + /* Make sure that the block is in memory (the name may not be in the + * same block as the inode header. + */ + + ret = nxffs_rdcache(volume, volume->ioblock, 1); if (ret < 0) { - fdbg("Failed to read inode, offset %d: %d\n", offset, -ret); - return -EIO; + fdbg("nxffsx_rdcache failed: %d\n", -ret); + return ret; } + + /* Read the file name from the expected offset in FLASH */ + + memcpy(entry->name, &volume->cache[volume->iooffset], namlen); entry->name[namlen] = '\0'; /* Finish the CRC calculation and verify the entry */ @@ -350,7 +354,7 @@ int nxffs_findinode(FAR struct nxffs_volume_s *volume, FAR const char *name, ret = nxffs_nextentry(volume, offset, entry); if (ret < 0) { - fdbg("No inode found: %d\n", -ret); + fvdbg("No inode found: %d\n", -ret); return ret; } diff --git a/nuttx/fs/nxffs/nxffs_open.c b/nuttx/fs/nxffs/nxffs_open.c index 0c101b78e..183062b9f 100644 --- a/nuttx/fs/nxffs/nxffs_open.c +++ b/nuttx/fs/nxffs/nxffs_open.c @@ -325,7 +325,7 @@ static inline int nxffs_namerased(FAR struct nxffs_volume_s *volume, ****************************************************************************/ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume, - FAR const char *name, mode_t mode, + FAR const char *name, mode_t oflags, FAR struct nxffs_ofile_s **ppofile) { FAR struct nxffs_wrfile_s *wrfile; @@ -370,7 +370,7 @@ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume, * exclusively. */ - if ((mode & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) + if ((oflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) { fdbg("File exists, can't create O_EXCL\n"); ret = -EEXIST; @@ -382,7 +382,7 @@ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume, * we will not re-create the file unless O_CREAT is also specified. */ - else if ((mode & (O_CREAT|O_TRUNC)) == (O_CREAT|O_TRUNC)) + else if ((oflags & (O_CREAT|O_TRUNC)) == (O_CREAT|O_TRUNC)) { /* Just schedule the removal the file and fall through to re-create it. * Note that the old file of the same name will not actually be removed @@ -408,7 +408,7 @@ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume, * it). Now, make sure that we were asked to created it. */ - if ((mode & O_CREAT) == 0) + if ((oflags & O_CREAT) == 0) { fdbg("Not asked to create the file\n"); ret = -ENOENT; @@ -445,7 +445,7 @@ static inline int nxffs_wropen(FAR struct nxffs_volume_s *volume, /* Initialize the open file state structure */ wrfile->ofile.crefs = 1; - wrfile->ofile.mode = O_WROK; + wrfile->ofile.oflags = oflags; wrfile->ofile.entry.utc = time(NULL); wrfile->truncate = truncate; @@ -637,7 +637,7 @@ static inline int nxffs_rdopen(FAR struct nxffs_volume_s *volume, * Limitation: Files cannot be open both for reading and writing. */ - if ((ofile->mode & O_WROK) != 0) + if ((ofile->oflags & O_WROK) != 0) { fdbg("File is open for writing\n"); ret = -ENOSYS; @@ -669,8 +669,8 @@ static inline int nxffs_rdopen(FAR struct nxffs_volume_s *volume, /* Initialize the open file state structure */ - ofile->crefs = 1; - ofile->mode = O_RDOK; + ofile->crefs = 1; + ofile->oflags = O_RDOK; /* Find the file on this volume associated with this file name */ @@ -1011,7 +1011,7 @@ int nxffs_open(FAR struct file *filep, FAR const char *relpath, return -EINVAL; case O_WROK: - ret = nxffs_wropen(volume, relpath, mode, &ofile); + ret = nxffs_wropen(volume, relpath, oflags, &ofile); break; case O_RDOK: @@ -1088,7 +1088,7 @@ int nxffs_close(FAR struct file *filep) /* Handle special finalization of the write operation. */ - if (ofile->mode == O_WROK) + if ((ofile->oflags & O_WROK) != 0) { ret = nxffs_wrclose(volume, (FAR struct nxffs_wrfile_s *)ofile); } diff --git a/nuttx/fs/nxffs/nxffs_read.c b/nuttx/fs/nxffs/nxffs_read.c index bfc4270b4..bb400e232 100644 --- a/nuttx/fs/nxffs/nxffs_read.c +++ b/nuttx/fs/nxffs/nxffs_read.c @@ -102,22 +102,23 @@ static int nxffs_rdblkhdr(FAR struct nxffs_volume_s *volume, off_t offset, uint32_t crc; uint16_t doffset; uint16_t dlen; - int ret; /* Read the header at the FLASH offset */ nxffs_ioseek(volume, offset); - ret = nxffs_rddata(volume, (FAR uint8_t *)&blkhdr, SIZEOF_NXFFS_DATA_HDR); - if (ret < 0) - { - fdbg("Failed to read data block header, offset %d: %d\n", offset, -ret); - return -EIO; - } doffset = volume->iooffset; + memcpy(&blkhdr, &volume->cache[doffset], SIZEOF_NXFFS_DATA_HDR); /* Extract the data length */ dlen = nxffs_rdle16(blkhdr.datlen); + + /* Get the offset to the beginning of the data */ + + doffset += SIZEOF_NXFFS_DATA_HDR; + + /* Make sure that all of the data fits within the block */ + if ((uint32_t)doffset + (uint32_t)dlen > (uint32_t)volume->geo.blocksize) { fdbg("Data length=%d is unreasonable at offset=%d\n", dlen, doffset); @@ -131,6 +132,7 @@ static int nxffs_rdblkhdr(FAR struct nxffs_volume_s *volume, off_t offset, nxffs_wrle32(blkhdr.crc, 0); crc = crc32((FAR const uint8_t *)&blkhdr, SIZEOF_NXFFS_DATA_HDR); crc = crc32part(&volume->cache[doffset], dlen, crc); + if (crc != ecrc) { fdbg("CRC failure\n"); @@ -349,7 +351,6 @@ ssize_t nxffs_read(FAR struct file *filep, FAR char *buffer, size_t buflen) ssize_t total; size_t available; size_t readsize; - ssize_t nread; int ret; fvdbg("Read %d bytes from offset %d\n", buflen, filep->f_pos); @@ -381,7 +382,7 @@ ssize_t nxffs_read(FAR struct file *filep, FAR char *buffer, size_t buflen) /* Check if the file was opened with read access */ - if ((ofile->mode & O_RDOK) == 0) + if ((ofile->oflags & O_RDOK) == 0) { fdbg("File not open for read access\n"); ret = -EACCES; @@ -426,17 +427,12 @@ ssize_t nxffs_read(FAR struct file *filep, FAR char *buffer, size_t buflen) /* Read data from that file offset */ - nread = nxffs_rddata(volume, (FAR uint8_t *)&buffer[total], readsize); - if (nread < 0) - { - ret = nread; - goto errout_with_semaphore; - } + memcpy(&buffer[total], &volume->cache[volume->iooffset], readsize); /* Update the file offset */ - filep->f_pos += nread; - total += nread; + filep->f_pos += readsize; + total += readsize; } sem_post(&volume->exclsem); diff --git a/nuttx/fs/nxffs/nxffs_write.c b/nuttx/fs/nxffs/nxffs_write.c index 2dcd91654..b675e6154 100644 --- a/nuttx/fs/nxffs/nxffs_write.c +++ b/nuttx/fs/nxffs/nxffs_write.c @@ -482,7 +482,7 @@ ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer, size_t bufle /* Check if the file was opened with write access */ - if ((wrfile->ofile.mode & O_WROK) == 0) + if ((wrfile->ofile.oflags & O_WROK) == 0) { fdbg("File not open for write access\n"); ret = -EACCES; @@ -495,7 +495,7 @@ ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer, size_t bufle for (total = 0; total < buflen; ) { - remaining = buflen- total; + remaining = buflen - total; /* Have we already allocated the data block? */ @@ -620,7 +620,7 @@ int nxffs_wrreserve(FAR struct nxffs_volume_s *volume, size_t size) * already at the final block. */ - if (volume->ioblock + 1 >= volume->geo.neraseblocks) + if (volume->ioblock + 1 >= volume->nblocks) { /* Return -ENOSPC to indicate that the volume is full */ |