diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-05-02 18:38:11 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-05-02 18:38:11 +0000 |
commit | 7270511ae42b378850af972739b448de62085b5d (patch) | |
tree | 572e9f2fe93da4e640eb5503a972a3cf01f6c56e | |
parent | bbeba1fded523a5e2f7d71f3ad003a8c7c5c9351 (diff) | |
download | nuttx-7270511ae42b378850af972739b448de62085b5d.tar.gz nuttx-7270511ae42b378850af972739b448de62085b5d.tar.bz2 nuttx-7270511ae42b378850af972739b448de62085b5d.zip |
NXFFS file deletion is functional
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3552 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r-- | apps/examples/nxffs/nxffs_main.c | 91 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_dump.c | 68 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_inode.c | 57 | ||||
-rw-r--r-- | nuttx/fs/nxffs/nxffs_unlink.c | 4 |
4 files changed, 183 insertions, 37 deletions
diff --git a/apps/examples/nxffs/nxffs_main.c b/apps/examples/nxffs/nxffs_main.c index 5b17bdba0..738e8ecf8 100644 --- a/apps/examples/nxffs/nxffs_main.c +++ b/apps/examples/nxffs/nxffs_main.c @@ -374,9 +374,12 @@ static inline int nxffs_rdfile(FAR struct nxffs_filedesc_s *file) fd = open(file->name, O_RDONLY); if (fd < 0) { - 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); + if (!file->deleted) + { + 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; } @@ -482,6 +485,63 @@ static int nxffs_verifyfs(void) } /**************************************************************************** + * Name: nxffs_delfiles + ****************************************************************************/ + +static int nxffs_delfiles(void) +{ + FAR struct nxffs_filedesc_s *file; + int ndel; + int ret; + int i; + int j; + + /* How many files should we delete? */ + + ndel = (rand() % (g_nfiles - g_ndeleted)) + 1; + + /* Now pick which files to delete */ + + for (i = 0; i < ndel; i++) + { + /* Guess a file index */ + + int ndx = (rand() % (g_nfiles - g_ndeleted)); + + /* And delete the next undeleted file after that random index */ + + for (j = ndx + 1; j != ndx; j++) + { + if (j >= CONFIG_EXAMPLES_NXFFS_MAXOPEN) + { + j = 0; + } + + file = &g_files[j]; + if (file->name && !file->deleted) + { + ret = unlink(file->name); + if (ret < 0) + { + fprintf(stderr, "ERROR: Unlink %d failed: %d\n", i+1, errno); + fprintf(stderr, " File name: %s\n", file->name); + fprintf(stderr, " File size: %d\n", file->len); + fprintf(stderr, " File index: %d\n", j); + } + else + { + file->deleted = true; + g_ndeleted++; + break; + } + } + } + } + + return OK; +} + +/**************************************************************************** * Public Functions ****************************************************************************/ @@ -546,6 +606,31 @@ int user_start(int argc, char *argv[]) fprintf(stderr, " Number deleted: %d\n", g_ndeleted); } + /* Delete some files */ + + ret = nxffs_delfiles(); + if (ret < 0) + { + fprintf(stderr, "ERROR: Failed to delete files\n"); + } + else + { + fprintf(stderr, "Deleted some files\n"); + } + fprintf(stderr, " Number of files: %d\n", g_nfiles); + fprintf(stderr, " Number deleted: %d\n", g_ndeleted); + nxffs_dump(mtd); + + /* Verify all files written to FLASH */ + + ret = nxffs_verifyfs(); + if (ret < 0) + { + 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); + } + return 0; } diff --git a/nuttx/fs/nxffs/nxffs_dump.c b/nuttx/fs/nxffs/nxffs_dump.c index 5534af749..fc60e8a5d 100644 --- a/nuttx/fs/nxffs/nxffs_dump.c +++ b/nuttx/fs/nxffs/nxffs_dump.c @@ -55,6 +55,12 @@ /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +/* Re-define fdbg so that the output does not have so much diagnostic info. + * This should still, however, always agree with the defintion in debug.h. + */ + +#undef fdbg +#define fdbg lib_rawprintf /**************************************************************************** * Private Types @@ -73,6 +79,10 @@ struct nxffs_blkinfo_s * Private Data ****************************************************************************/ +static const char g_hdrformat[] = " BLOCK:OFFS TYPE STATE LENGTH\n"; +static const char g_format[] = " %5d:%-5d %s %s %5d\n"; +static const char g_blkformat[] = "--%5d:%-5d %s %s %5d\n"; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -161,8 +171,7 @@ static inline ssize_t nxffs_analyzeinode(FAR struct nxffs_blkinfo_s *blkinfo, { /* Not than we cannot verify the inode header */ - fdbg(" Block %d:%d: Unverifiable inode, datlen: %d\n", - blkinfo->block, offset, datlen); + fdbg(g_format, blkinfo->block, offset, "INODE", "UNVERFD", datlen); return ERROR; } @@ -186,8 +195,7 @@ static inline ssize_t nxffs_analyzeinode(FAR struct nxffs_blkinfo_s *blkinfo, if (crc != ecrc) { - fdbg(" Block %d:%d: Potential inode with bad CRC, datlen: %d\n", - blkinfo->block, offset, datlen); + fdbg(g_format, blkinfo->block, offset, "INODE", "CRC ", datlen); return ERROR; } @@ -195,18 +203,15 @@ static inline ssize_t nxffs_analyzeinode(FAR struct nxffs_blkinfo_s *blkinfo, if (state == INODE_STATE_FILE) { - fdbg(" Block %d:%d: Verified FILE inode, datlen: %d\n", - blkinfo->block, offset, datlen); + fdbg(g_format, blkinfo->block, offset, "INODE", "OK ", datlen); } else if (state == INODE_STATE_DELETED) { - fdbg(" Block %d:%d: Verified DELETED inode, datlen: %d\n", - blkinfo->block, offset, datlen); + fdbg(g_format, blkinfo->block, offset, "INODE", "DELETED", datlen); } else { - fdbg(" Block %d:%d: Verified inode with CORRUPTED state, datlen: %d\n", - blkinfo->block, offset, datlen); + fdbg(g_format, blkinfo->block, offset, "INODE", "CORRUPT", datlen); } return noffs + inode.namlen - offset; } @@ -253,15 +258,13 @@ static inline ssize_t nxffs_analyzedata(FAR struct nxffs_blkinfo_s *blkinfo, if (crc != ecrc) { - fdbg(" Block %d:%d: Potential data block with bad CRC, datlen: %d\n", - blkinfo->block, offset, datlen); + fdbg(g_format, blkinfo->block, offset, "DATA ", "CRC ", datlen); return ERROR; } /* If must be a good header */ - fdbg(" Block %d:%d: Verified data block, datlen: %d\n", - blkinfo->block, offset, datlen); + fdbg(g_format, blkinfo->block, offset, "DATA ", "OK ", datlen); return SIZEOF_NXFFS_DATA_HDR + datlen; } #endif @@ -282,7 +285,6 @@ static inline void nxffs_analyze(FAR struct nxffs_blkinfo_s *blkinfo) int hdrndx; int datndx; int inndx; - int nerased; int i; /* Verify that there is a header on the block */ @@ -290,15 +292,34 @@ static inline void nxffs_analyze(FAR struct nxffs_blkinfo_s *blkinfo) blkhdr = (FAR struct nxffs_block_s *)blkinfo->buffer; if (memcmp(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE) != 0) { - fdbg(" Block %d:0: ERROR -- no header\n", blkinfo->block); + fdbg(g_blkformat, blkinfo->block, 0, "BLOCK", "NO FRMT", + blkinfo->geo.blocksize); + } + else if (blkhdr->state == BLOCK_STATE_GOOD) + { + size_t datsize = blkinfo->geo.blocksize - SIZEOF_NXFFS_BLOCK_HDR; + size_t nerased = nxffs_erased(blkinfo->buffer + SIZEOF_NXFFS_BLOCK_HDR, datsize); + if (nerased == datsize) + { + fdbg(g_blkformat, blkinfo->block, 0, "BLOCK", "ERASED ", + blkinfo->geo.blocksize); + return; + } + else + { + fdbg(g_blkformat, blkinfo->block, 0, "BLOCK", "IN USE ", + blkinfo->geo.blocksize); + } } else if (blkhdr->state == BLOCK_STATE_BAD) { - fdbg(" Block %d:0: BAD\n", blkinfo->block); + fdbg(g_blkformat, blkinfo->block, 0, "BLOCK", "BAD ", + blkinfo->geo.blocksize); } - else if (blkhdr->state != BLOCK_STATE_GOOD) + else { - fdbg(" Block %d:0: ERROR -- bad state\n", blkinfo->block); + fdbg(g_blkformat, blkinfo->block, 0, "BLOCK", "CORRUPT", + blkinfo->geo.blocksize); } /* Serach for Inode and data block headers. */ @@ -310,11 +331,7 @@ static inline void nxffs_analyze(FAR struct nxffs_blkinfo_s *blkinfo) { uint8_t ch = blkinfo->buffer[i]; - if (ch == CONFIG_NXFFS_ERASEDSTATE) - { - nerased++; - } - else if (ch == g_inodemagic[inndx]) + if (ch == g_inodemagic[inndx]) { inndx++; datndx = 0; @@ -402,8 +419,9 @@ int nxffs_dump(FAR struct mtd_dev_s *mtd) /* Now read every block on the device */ fdbg("NXFFS Dump:\n"); - blkinfo.nblocks = blkinfo.geo.erasesize * blkinfo.geo.neraseblocks / blkinfo.geo.blocksize; + fdbg(g_hdrformat); + blkinfo.nblocks = blkinfo.geo.erasesize * blkinfo.geo.neraseblocks / blkinfo.geo.blocksize; for (blkinfo.block = 0, blkinfo.offset = 0; blkinfo.block < blkinfo.nblocks; blkinfo.block++, blkinfo.offset += blkinfo.geo.blocksize) diff --git a/nuttx/fs/nxffs/nxffs_inode.c b/nuttx/fs/nxffs/nxffs_inode.c index 3f8891f90..02ac3ca05 100644 --- a/nuttx/fs/nxffs/nxffs_inode.c +++ b/nuttx/fs/nxffs/nxffs_inode.c @@ -82,9 +82,11 @@ * information. * * Returned Value: - * Zero on success. Otherwise, a negater errno value is returned + * Zero on success. Otherwise, a negated errno value is returned * indicating the nature of the failure. * + * On return, the + * ****************************************************************************/ static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset, @@ -93,6 +95,7 @@ static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset, struct nxffs_inode_s inode; uint32_t ecrc; uint32_t crc; + uint8_t state; int namlen; int ret; @@ -104,11 +107,15 @@ static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset, nxffs_ioseek(volume, offset); memcpy(&inode, &volume->cache[volume->iooffset], SIZEOF_NXFFS_INODE_HDR); - /* Check if the file is marked as deleted. */ + /* Check if the file state is recognized. */ - if (inode.state != INODE_STATE_FILE) + state = inode.state; + if (state != INODE_STATE_FILE && state != INODE_STATE_DELETED) { - return -ENOENT; + /* This can't be a valid inode.. don't bother with the rest */ + + ret = -ENOENT; + goto errout_no_offset; } /* Copy the packed header into the user-friendly buffer */ @@ -133,7 +140,8 @@ static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset, if (!entry->name) { fdbg("Failed to allocate name, namlen: %d\n", namlen); - return -ENOMEM; + ret = -ENOMEM; + goto errout_no_offset; } /* Seek to the expected location of the name in FLASH */ @@ -148,7 +156,7 @@ static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset, if (ret < 0) { fdbg("nxffsx_rdcache failed: %d\n", -ret); - return ret; + goto errout_with_name; } /* Read the file name from the expected offset in FLASH */ @@ -162,10 +170,45 @@ static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset, if (crc != ecrc) { fdbg("CRC entry: %08x CRC calculated: %08x\n", ecrc, crc); + ret = -EIO; + goto errout_with_name; + } + + /* We have a good inode header.. but it still could a deleted file. + * Check the file state. + */ + + 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 + * further in FLASH memory and reduce the search time. + */ + + offset = entry->doffset + entry->datlen + SIZEOF_NXFFS_DATA_HDR; nxffs_freeentry(entry); - return -EIO; + ret = -ENOENT; + goto errout; } + + /* Everything is good.. leave the offset pointing to the valid inode + * header. + */ + return OK; + + /* On errors where we are suspicious of the validity of the inode header, + * we need to increment the file position to just after the "good" magic + * word. + */ + +errout_with_name: + nxffs_freeentry(entry); +errout_no_offset: + offset += NXFFS_MAGICSIZE; +errout: + nxffs_ioseek(volume, offset); + return ret; } /**************************************************************************** diff --git a/nuttx/fs/nxffs/nxffs_unlink.c b/nuttx/fs/nxffs/nxffs_unlink.c index 47abf61dd..ba474b46e 100644 --- a/nuttx/fs/nxffs/nxffs_unlink.c +++ b/nuttx/fs/nxffs/nxffs_unlink.c @@ -102,7 +102,7 @@ int nxffs_rminode(FAR struct nxffs_volume_s *volume, FAR const char *name) { /* We can't remove the inode if it is open */ - fdbg("Inode is open\n"); + fdbg("Inode '%s' is open\n", name); return -EBUSY; } @@ -111,7 +111,7 @@ int nxffs_rminode(FAR struct nxffs_volume_s *volume, FAR const char *name) ret = nxffs_findinode(volume, name, &entry); if (ret < 0) { - fdbg("Inode '%s' not found\n"); + fdbg("Inode '%s' not found\n", name); return ret; } |