diff options
Diffstat (limited to 'nuttx/fs/nxffs/nxffs_inode.c')
-rw-r--r-- | nuttx/fs/nxffs/nxffs_inode.c | 502 |
1 files changed, 0 insertions, 502 deletions
diff --git a/nuttx/fs/nxffs/nxffs_inode.c b/nuttx/fs/nxffs/nxffs_inode.c deleted file mode 100644 index 505a6c686..000000000 --- a/nuttx/fs/nxffs/nxffs_inode.c +++ /dev/null @@ -1,502 +0,0 @@ -/**************************************************************************** - * fs/nxffs/nxffs_inode.c - * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * References: Linux/Documentation/filesystems/romfs.txt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include <nuttx/config.h> - -#include <string.h> -#include <crc32.h> -#include <assert.h> -#include <errno.h> -#include <debug.h> - -#include <nuttx/kmalloc.h> -#include <nuttx/mtd.h> - -#include "nxffs.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: nxffs_rdentry - * - * Description: - * Read the inode entry at this offset. Called only from nxffs_nextentry(). - * - * Input Parameters: - * volume - Describes the current volume. - * offset - The byte offset from the beginning of FLASH where the inode - * header is expected. - * entry - A memory location to return the expanded inode header - * information. - * - * Returned Value: - * 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, - FAR struct nxffs_entry_s *entry) -{ - struct nxffs_inode_s inode; - uint32_t ecrc; - uint32_t crc; - uint8_t state; - int namlen; - int ret; - - DEBUGASSERT(volume && entry); - memset(entry, 0, sizeof(struct nxffs_entry_s)); - - /* Read the header at the FLASH offset */ - - nxffs_ioseek(volume, offset); - memcpy(&inode, &volume->cache[volume->iooffset], SIZEOF_NXFFS_INODE_HDR); - - /* Check if the file state is recognized. */ - - state = inode.state; - if (state != INODE_STATE_FILE && state != INODE_STATE_DELETED) - { - /* 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 */ - - entry->hoffset = offset; - entry->noffset = nxffs_rdle32(inode.noffs); - entry->doffset = nxffs_rdle32(inode.doffs); - entry->utc = nxffs_rdle32(inode.utc); - entry->datlen = nxffs_rdle32(inode.datlen); - - /* Modify the packed header and perform the (partial) CRC calculation */ - - ecrc = nxffs_rdle32(inode.crc); - inode.state = CONFIG_NXFFS_ERASEDSTATE; - memset(inode.crc, 0, 4); - crc = crc32((FAR const uint8_t *)&inode, SIZEOF_NXFFS_INODE_HDR); - - /* Allocate memory to hold the variable-length file name */ - - namlen = inode.namlen; - entry->name = (FAR char *)kmalloc(namlen + 1); - if (!entry->name) - { - fdbg("Failed to allocate name, namlen: %d\n", namlen); - ret = -ENOMEM; - goto errout_no_offset; - } - - /* Seek to the expected location of the name in FLASH */ - - nxffs_ioseek(volume, entry->noffset); - - /* 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); - if (ret < 0) - { - fdbg("nxffsx_rdcache failed: %d\n", -ret); - goto errout_with_name; - } - - /* 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 */ - - crc = crc32part((FAR const uint8_t *)entry->name, namlen, crc); - 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 are good so we can use this information to advance - * further in FLASH memory and reduce the search time. - */ - - offset = nxffs_inodeend(volume, entry); - nxffs_freeentry(entry); - 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; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: nxffs_freeentry - * - * Description: - * The inode values returned by nxffs_nextentry() include allocated memory - * (specifically, the file name string). This function should be called - * to dispose of that memory when the inode entry is no longer needed. - * - * Note that the nxffs_entry_s containing structure is not freed. The - * caller may call kfree upon return of this function if necessary to - * free the entry container. - * - * Input parameters: - * entry - The entry to be freed. - * - * Returned Value: - * None - * - ****************************************************************************/ - -void nxffs_freeentry(FAR struct nxffs_entry_s *entry) -{ - if (entry->name) - { - kfree(entry->name); - entry->name = NULL; - } -} - -/**************************************************************************** - * Name: nxffs_nextentry - * - * Description: - * Search for the next valid inode starting at the provided FLASH offset. - * - * Input Parameters: - * volume - Describes the NXFFS volume. - * offset - The FLASH memory offset to begin searching. - * entry - A pointer to memory provided by the caller in which to return - * the inode description. - * - * Returned Value: - * Zero is returned on success. Otherwise, a negated errno is returned - * that indicates the nature of the failure. - * - ****************************************************************************/ - -int nxffs_nextentry(FAR struct nxffs_volume_s *volume, off_t offset, - FAR struct nxffs_entry_s *entry) -{ - int nmagic; - int ch; - int nerased; - int ret; - - /* Seek to the first FLASH offset provided by the caller. */ - - nxffs_ioseek(volume, offset); - - /* Then begin searching */ - - nerased = 0; - nmagic = 0; - for (;;) - { - /* Read the next character */ - - ch = nxffs_getc(volume, SIZEOF_NXFFS_INODE_HDR - nmagic); - if (ch < 0) - { - fvdbg("nxffs_getc failed: %d\n", -ch); - return ch; - } - - /* Check for another erased byte */ - - else if (ch == CONFIG_NXFFS_ERASEDSTATE) - { - /* If we have encountered NXFFS_NERASED number of consecutive - * erased bytes, then presume we have reached the end of valid - * data. - */ - - if (++nerased >= NXFFS_NERASED) - { - fvdbg("No entry found\n"); - return -ENOENT; - } - } - else - { - nerased = 0; - - /* Check for the magic sequence indicating the start of an NXFFS - * inode. There is the possibility of this magic sequnce occurring - * in FLASH data. However, the header CRC should distinguish - * between real NXFFS inode headers and such false alarms. - */ - - if (ch != g_inodemagic[nmagic]) - { - /* Ooops... this is the not the right character for the magic - * Sequence. Check if we need to restart or to cancel the sequence: - */ - - if (ch == g_inodemagic[0]) - { - nmagic = 1; - } - else - { - nmagic = 0; - } - } - else if (nmagic < NXFFS_MAGICSIZE - 1) - { - /* We have one more character in the magic sequence */ - - nmagic++; - } - - /* We have found the magic sequence in the FLASH data that may - * indicate the beginning of an NXFFS inode. - */ - - else - { - /* The the FLASH offset where we found the matching magic number */ - - offset = nxffs_iotell(volume) - NXFFS_MAGICSIZE; - - /* Try to extract the inode header from that position */ - - ret = nxffs_rdentry(volume, offset, entry); - if (ret == OK) - { - fvdbg("Found a valid fileheader, offset: %d\n", offset); - return OK; - } - - /* False alarm.. keep looking */ - - nmagic = 0; - } - } - } - - /* We won't get here, but to keep some compilers happy: */ - - return -ENOENT; -} - -/**************************************************************************** - * Name: nxffs_findinode - * - * Description: - * Search for an inode with the provided name starting with the first - * valid inode and proceeding to the end FLASH or until the matching - * inode is found. - * - * Input Parameters: - * volume - Describes the NXFFS volume - * name - The name of the inode to find - * entry - The location to return information about the inode. - * - * Returned Value: - * Zero is returned on success. Otherwise, a negated errno is returned - * that indicates the nature of the failure. - * - ****************************************************************************/ - -int nxffs_findinode(FAR struct nxffs_volume_s *volume, FAR const char *name, - FAR struct nxffs_entry_s *entry) -{ - off_t offset; - int ret; - - /* Start with the first valid inode that was discovered when the volume - * was created (or modified after the last file system re-packing). - */ - - offset = volume->inoffset; - - /* Loop, checking each NXFFS inode until either: (1) we find the NXFFS inode - * with the matching name, or (2) we reach the end of data written on the - * media. - */ - - for (;;) - { - /* Get the next, valid NXFFS inode entry */ - - ret = nxffs_nextentry(volume, offset, entry); - if (ret < 0) - { - fvdbg("No inode found: %d\n", -ret); - return ret; - } - - /* Is this the NXFFS inode we are looking for? */ - - else if (strcmp(name, entry->name) == 0) - { - /* Yes, return success with the entry data in 'entry' */ - - return OK; - } - - /* Discard this entry and try the next one. Here we set the - * next offset using the raw 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. - */ - - offset = nxffs_inodeend(volume, entry); - nxffs_freeentry(entry); - } - - /* We won't get here, but for some compilers: */ - - 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. It is the physcal size - * of the block minus the minimum number of headers: block sna data - */ - - uint16_t maxsize = volume->geo.blocksize - SIZEOF_NXFFS_BLOCK_HDR - 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); -} - - |