/****************************************************************************
 * fs/smartfs/smartfs_utils.c
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.  The
 * ASF licenses this file to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the
 * License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations
 * under the License.
 *
 ****************************************************************************/

/****************************************************************************
 * Included Files
 ****************************************************************************/

#include <nuttx/config.h>

#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>

#include <nuttx/kmalloc.h>
#include <nuttx/fs/fs.h>
#include <nuttx/fs/ioctl.h>

#include "smartfs.h"

/****************************************************************************
 * Pre-processor Definitions
 ****************************************************************************/

#define WORKBUFFER_SIZE 256

/****************************************************************************
 * Private Data
 ****************************************************************************/

#if defined(CONFIG_SMARTFS_MULTI_ROOT_DIRS) || \
  (defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_SMARTFS))
static struct smartfs_mountpt_s *g_mounthead = NULL;
#endif

/****************************************************************************
 * Public Functions
 ****************************************************************************/

/****************************************************************************
 * Name: smartfs_rdle16
 *
 * Description:
 *   Get a (possibly unaligned) 16-bit little endian value.
 *
 * Input Parameters:
 *   val - A pointer to the first byte of the little endian value.
 *
 * Returned Value:
 *   A uint16_t representing the whole 16-bit integer value
 *
 ****************************************************************************/

uint16_t smartfs_rdle16(FAR const void *val)
{
  return (uint16_t)((FAR const uint8_t *)val)[1] << 8 |
    (uint16_t)((FAR const uint8_t *)val)[0];
}

/****************************************************************************
 * Name: smartfs_wrle16
 *
 * Description:
 *   Put a (possibly unaligned) 16-bit little endian value.
 *
 * Input Parameters:
 *   dest - A pointer to the first byte to save the little endian value.
 *   val - The 16-bit value to be saved.
 *
 * Returned Value:
 *   None
 *
 ****************************************************************************/

void smartfs_wrle16(FAR void *dest, uint16_t val)
{
  ((FAR uint8_t *) dest)[0] = val & 0xff; /* Little endian means LS byte first in byte stream */
  ((FAR uint8_t *) dest)[1] = val >> 8;
}

/****************************************************************************
 * Name: smartfs_rdle32
 *
 * Description:
 *   Get a (possibly unaligned) 32-bit little endian value.
 *
 * Input Parameters:
 *   val - A pointer to the first byte of the little endian value.
 *
 * Returned Value:
 *   A uint32_t representing the whole 32-bit integer value
 *
 ****************************************************************************/

uint32_t smartfs_rdle32(FAR const void *val)
{
  /* Little endian means LS halfword first in byte stream */

  return (uint32_t)smartfs_rdle16(&((FAR const uint8_t *)val)[2]) << 16 |
    (uint32_t)smartfs_rdle16(val);
}

/****************************************************************************
 * Name: smartfs_wrle32
 *
 * Description:
 *   Put a (possibly unaligned) 32-bit little endian value.
 *
 * Input Parameters:
 *   dest - A pointer to the first byte to save the little endian value.
 *   val - The 32-bit value to be saved.
 *
 * Returned Value:
 *   None
 *
 ****************************************************************************/

void smartfs_wrle32(uint8_t *dest, uint32_t val)
{
  /* Little endian means LS halfword first in byte stream */

  smartfs_wrle16(dest, (uint16_t)(val & 0xffff));
  smartfs_wrle16(dest + 2, (uint16_t)(val >> 16));
}

/****************************************************************************
 * Name: smartfs_mount
 *
 * Description: This function is called only when the mountpoint is first
 *   established.  It initializes the mountpoint structure and verifies
 *   that a valid SMART filesystem is provided by the block driver.
 *
 *   The caller should hold the mountpoint semaphore
 *
 ****************************************************************************/

int smartfs_mount(struct smartfs_mountpt_s *fs, bool writeable)
{
  FAR struct inode *inode;
  struct geometry geo;
  int ret = OK;
#if defined(CONFIG_SMARTFS_MULTI_ROOT_DIRS)
  struct smartfs_mountpt_s *nextfs;
#endif

  /* Assume that the mount is not successful */

  fs->fs_mounted = false;

  /* Check if there is media available */

  inode = fs->fs_blkdriver;
  if (!inode || !inode->u.i_bops || !inode->u.i_bops->geometry ||
      inode->u.i_bops->geometry(inode, &geo) != OK || !geo.geo_available)
    {
      ret = -ENODEV;
      goto errout;
    }

  /* Make sure that that the media is write-able
   * (if write access is needed)
   */

  if (writeable && !geo.geo_writeenabled)
    {
      ret = -EACCES;
      goto errout;
    }

  /* Get the SMART low-level format information to validate the device has
   * been formatted and scan properly for logical to physical sector mapping.
   */

  ret = FS_IOCTL(fs, BIOC_GETFORMAT, (unsigned long) &fs->fs_llformat);
  if (ret != OK)
    {
      ferr("ERROR: Error getting device low level format: %d\n", ret);
      goto errout;
    }

  /* Validate the low-level format is valid */

  if (!(fs->fs_llformat.flags & SMART_FMT_ISFORMATTED))
    {
      ferr("ERROR: No low-level format found\n");
      ret = -ENODEV;
      goto errout;
    }

  /* Allocate a read/write buffer */

#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
  /* Scan linked list of mounted file systems to find another FS with
   * the same blockdriver.  We will reuse the buffers.
   */

  nextfs = g_mounthead;
  while (nextfs != NULL)
    {
      /* Test if this FS uses the same block driver */

      if (nextfs->fs_blkdriver == fs->fs_blkdriver)
        {
          /* Yep, it's the same block driver.  Reuse the buffers.
           * we can do this because we are protected by the same
           * semaphore.
           */

          fs->fs_rwbuffer = nextfs->fs_rwbuffer;
          fs->fs_workbuffer = nextfs->fs_workbuffer;
          break;
        }

      /* Advance to next FS */

      nextfs = nextfs->fs_next;
    }

  /* If we didn't find a FS above, then allocate some buffers */

  if (nextfs == NULL)
    {
      fs->fs_rwbuffer = kmm_malloc(fs->fs_llformat.availbytes);
      fs->fs_workbuffer = kmm_malloc(WORKBUFFER_SIZE);
    }

  /* Now add ourselves to the linked list of SMART mounts */

  fs->fs_next = g_mounthead;
  g_mounthead = fs;

  /* Set our root directory sector based on the directory entry
   * reported by the block driver (based on which device is
   * associated with this mount.
   */

  fs->fs_rootsector = SMARTFS_ROOT_DIR_SECTOR + fs->fs_llformat.rootdirnum;

#else  /* CONFIG_SMARTFS_MULTI_ROOT_DIRS */
#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_SMARTFS)
  /* Now add ourselves to the linked list of SMART mounts */

  fs->fs_next = g_mounthead;
  g_mounthead = fs;
#endif

  fs->fs_rwbuffer = kmm_malloc(fs->fs_llformat.availbytes);
  fs->fs_workbuffer = kmm_malloc(WORKBUFFER_SIZE);
  fs->fs_rootsector = SMARTFS_ROOT_DIR_SECTOR;

#endif /* CONFIG_SMARTFS_MULTI_ROOT_DIRS */

  /* We did it! */

  fs->fs_mounted = TRUE;

  finfo("SMARTFS:\n");
  finfo("\t    Sector size:     %d\n", fs->fs_llformat.sectorsize);
  finfo("\t    Bytes/sector     %d\n", fs->fs_llformat.availbytes);
  finfo("\t    Num sectors:     %d\n", fs->fs_llformat.nsectors);
  finfo("\t    Free sectors:    %d\n", fs->fs_llformat.nfreesectors);
  finfo("\t    Max filename:    %d\n", CONFIG_SMARTFS_MAXNAMLEN);
#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
  finfo("\t    RootDirEntries:  %d\n", fs->fs_llformat.nrootdirentries);
#endif
  finfo("\t    RootDirSector:   %d\n", fs->fs_rootsector);

errout:
  return ret;
}

/****************************************************************************
 * Name: smartfs_unmount
 *
 * Description: This function is called only when the mountpoint is being
 *   unbound.  If we are serving multiple directories, then we have to
 *   remove ourselves from the mount linked list, and potentially free
 *   the shared buffers.
 *
 *   The caller should hold the mountpoint semaphore
 *
 ****************************************************************************/

int smartfs_unmount(struct smartfs_mountpt_s *fs)
{
  int           ret = OK;
  struct inode *inode;
#if defined(CONFIG_SMARTFS_MULTI_ROOT_DIRS) || \
  (defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_SMARTFS))
  struct smartfs_mountpt_s *nextfs;
  struct smartfs_mountpt_s *prevfs;
  int           count = 0;
  int           found = FALSE;
#endif

#if defined(CONFIG_SMARTFS_MULTI_ROOT_DIRS) || \
  (defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_SMARTFS))
  /* Start at the head of the mounts and search for our entry.  Also
   * count the number of entries that match our blkdriver.
   */

  nextfs = g_mounthead;
  prevfs = NULL;
  while (nextfs != NULL)
    {
      /* Test if this FS's blkdriver matches ours (it could be us) */

      if (nextfs->fs_blkdriver == fs->fs_blkdriver)
        count++;

      /* Test if this entry is our's */

      if (nextfs == fs)
        {
          found = TRUE;
        }

      /* Keep track of the previous entry until our's is found */

      if (!found)
        {
          /* Save this entry as the previous entry */

          prevfs = nextfs;
        }

      /* Advance to the next entry */

      nextfs = nextfs->fs_next;
    }

  /* Ensure we found our FS */

  if (!found)
    {
      /* Our entry not found!  Invalid unmount or bug somewhere */

      return -EINVAL;
    }

  /* If the count is only one, then we need to delete the shared
   * buffers because we are the last ones.
   */

  if (count == 1)
    {
      /* Close the block driver */

      if (fs->fs_blkdriver)
        {
          inode = fs->fs_blkdriver;
          if (inode)
            {
              if (inode->u.i_bops && inode->u.i_bops->close)
                {
                  inode->u.i_bops->close(inode);
                }
            }
        }

      /* Free the buffers */

      kmm_free(fs->fs_rwbuffer);
      kmm_free(fs->fs_workbuffer);

      /* Set the buffer's to invalid value to catch program bugs */

      fs->fs_rwbuffer = (char *) 0xdeadbeef;
      fs->fs_workbuffer = (char *) 0xdeadbeef;
    }

  /* Now removed ourselves from the linked list */

  if (fs == g_mounthead)
    {
      /* We were the first ones.  Set a new head */

      g_mounthead = fs->fs_next;
    }
  else
    {
      /* Remove from the middle of the list somewhere */

      prevfs->fs_next = fs->fs_next;
    }
#else
  if (fs->fs_blkdriver)
    {
     inode = fs->fs_blkdriver;
      if (inode)
        {
          if (inode->u.i_bops && inode->u.i_bops->close)
            {
              inode->u.i_bops->close(inode);
            }
        }
    }

  /* Release the mountpoint private data */

  kmm_free(fs->fs_rwbuffer);
  kmm_free(fs->fs_workbuffer);
#endif

  return ret;
}

/****************************************************************************
 * Name: smartfs_finddirentry
 *
 * Description: Finds an entry in the filesystem as specified by relpath.
 *              If found, the direntry will be populated with information
 *              for accessing the entry.
 *
 *              If the final directory segment of relpath just before the
 *              last segment (the target file/dir) is valid, then the
 *              parentdirsector will indicate the logical sector number of
 *              the parent directory where a new entry should be created,
 *              and the filename pointer will point to the final segment
 *              (i.e. the "filename").
 *
 ****************************************************************************/

int smartfs_finddirentry(struct smartfs_mountpt_s *fs,
        struct smartfs_entry_s *direntry, const char *relpath,
        uint16_t *parentdirsector, const char **filename)
{
  int ret = -ENOENT;
  const char *segment;
  const char *ptr;
  uint16_t    seglen;
  uint16_t    depth = 0;
  uint16_t    dirstack[CONFIG_SMARTFS_DIRDEPTH];
  uint16_t    dirsector;
  uint16_t    entrysize;
  uint16_t    offset;
  struct      smartfs_chain_header_s *header;
  struct      smart_read_write_s readwrite;
  struct      smartfs_entry_header_s *entry;

  /* Set the initial value of the output */

  *parentdirsector = 0xffff;
  *filename = NULL;

  /* Initialize directory level zero as the root sector */

  dirstack[0] = fs->fs_rootsector;
  entrysize = sizeof(struct smartfs_entry_header_s) +
              fs->fs_llformat.namesize;

  /* Test if this is a request for the root directory */

  if (*relpath == '\0')
    {
      direntry->firstsector = fs->fs_rootsector;
      direntry->flags = SMARTFS_DIRENT_TYPE_DIR | 0777;
      direntry->utc = 0;
      direntry->dsector = 0;
      direntry->doffset = 0;
      direntry->dfirst = fs->fs_rootsector;
      direntry->name = NULL;
      direntry->datlen = 0;

      *parentdirsector = 0;    /* Our parent is the format sector I guess */
      return OK;
    }

  /* Parse through each segment of relpath */

  segment = relpath;
  while (segment != NULL && *segment != '\0')
    {
      /* Find the end of this segment.  It will be '/' or NULL. */

      ptr = segment;
      seglen = 0;
      while (*ptr != '/' && *ptr != '\0')
        {
          seglen++;
          ptr++;
        }

      /* Check to avoid buffer overflow */

      if (seglen >= WORKBUFFER_SIZE)
        {
          ret = -ENAMETOOLONG;
          goto errout;
        }

      strlcpy(fs->fs_workbuffer, segment, seglen + 1);

      /* Search for "." and ".." as segment names */

      if (strcmp(fs->fs_workbuffer, ".") == 0)
        {
          /* Just ignore this segment.  Advance ptr if not on NULL */

          if (*ptr == '/')
            {
              ptr++;
            }

          segment = ptr;
          continue;
        }
      else if (strcmp(fs->fs_workbuffer, "..") == 0)
        {
          /* Up one level */

          if (depth == 0)
            {
              /* We went up one level past our mount point! */

              goto errout;
            }

          /* "Pop" to the previous directory level */

          depth--;
          if (*ptr == '/')
            {
              ptr++;
            }

          segment = ptr;
          continue;
        }
      else
        {
          /* Search for the entry in the current directory */

          dirsector = dirstack[depth];

          /* Read the directory */

          offset = 0xffff;

#if CONFIG_SMARTFS_ERASEDSTATE == 0xff
          while (dirsector != 0xffff)
#else
          while (dirsector != 0)
#endif
            {
              /* Read the next directory in the chain */

              readwrite.logsector = dirsector;
              readwrite.count = fs->fs_llformat.availbytes;
              readwrite.buffer = (uint8_t *)fs->fs_rwbuffer;
              readwrite.offset = 0;
              ret = FS_IOCTL(fs, BIOC_READSECT, (unsigned long) &readwrite);
              if (ret < 0)
                {
                  goto errout;
                }

              /* Point to next sector in chain */

              header = (struct smartfs_chain_header_s *) fs->fs_rwbuffer;
              dirsector = SMARTFS_NEXTSECTOR(header);

              /* Search for the entry */

              offset = sizeof(struct smartfs_chain_header_s);
              entry = (struct smartfs_entry_header_s *)
                &fs->fs_rwbuffer[offset];
              while (offset < readwrite.count)
                {
                  /* Test if this entry is valid and active */

#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS
                  if (((smartfs_rdle16(&entry->flags) &
                        SMARTFS_DIRENT_EMPTY) ==
                      (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_EMPTY)) ||
                      ((smartfs_rdle16(&entry->flags)
                        & SMARTFS_DIRENT_ACTIVE) !=
                      (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_ACTIVE)))
#else
                  if (((entry->flags & SMARTFS_DIRENT_EMPTY) ==
                      (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_EMPTY)) ||
                      ((entry->flags & SMARTFS_DIRENT_ACTIVE) !=
                      (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_ACTIVE)))
#endif
                    {
                      /* This entry isn't valid, skip it */

                      offset += entrysize;
                      entry = (struct smartfs_entry_header_s *)
                        &fs->fs_rwbuffer[offset];

                      continue;
                    }

                  /* Test if the name matches */

                  if (strncmp(entry->name, fs->fs_workbuffer,
                      fs->fs_llformat.namesize) == 0)
                    {
                      /* We found it!  If this is the last segment entry,
                       * then report the entry.  If it isn't the last
                       * entry, then validate it is a directory entry and
                       * open it and continue searching.
                       */

                      if (*ptr == '\0')
                        {
                          /* We are at the last segment.  Report the entry */

                          /* Fill in the entry */

#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS
                          direntry->firstsector =
                            smartfs_rdle16(&entry->firstsector);
                          direntry->flags = smartfs_rdle16(&entry->flags);
                          direntry->utc = smartfs_rdle32(&entry->utc);
#else
                          direntry->firstsector = entry->firstsector;
                          direntry->flags = entry->flags;
                          direntry->utc = entry->utc;
#endif
                          direntry->dsector = readwrite.logsector;
                          direntry->doffset = offset;
                          direntry->dfirst = dirstack[depth];
                          if (direntry->name == NULL)
                            {
                              direntry->name = (FAR char *)
                                kmm_malloc(fs->fs_llformat.namesize + 1);
                            }

                          strlcpy(direntry->name, entry->name,
                                  fs->fs_llformat.namesize + 1);
                          direntry->datlen = 0;

                          /* Scan the file's sectors to calculate the length
                           * and perform a rudimentary check.
                           */

#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS
                          if ((smartfs_rdle16(&entry->flags) &
                                SMARTFS_DIRENT_TYPE) ==
                              SMARTFS_DIRENT_TYPE_FILE)
#else
                          if ((entry->flags & SMARTFS_DIRENT_TYPE) ==
                              SMARTFS_DIRENT_TYPE_FILE)
#endif
                            {
#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS
                              dirsector =
                                smartfs_rdle16(&entry->firstsector);
#else
                              dirsector = entry->firstsector;
#endif
                              readwrite.count =
                                sizeof(struct smartfs_chain_header_s);
                              readwrite.buffer = (uint8_t *)fs->fs_rwbuffer;
                              readwrite.offset = 0;

                              while (dirsector != SMARTFS_ERASEDSTATE_16BIT)
                                {
                                  /* Read the next sector of the file */

                                  readwrite.logsector = dirsector;
                                  ret = FS_IOCTL(fs, BIOC_READSECT,
                                                 (unsigned long) &readwrite);
                                  if (ret < 0)
                                    {
                                      ferr("ERROR: Error in sector"
                                           " chain at %d!\n", dirsector);
                                      break;
                                    }

                                  /* Add used bytes to the total and point
                                   * to next sector
                                   */

                                  if (SMARTFS_USED(header) !=
                                      SMARTFS_ERASEDSTATE_16BIT)
                                    {
                                      direntry->datlen +=
                                        SMARTFS_USED(header);
                                    }

                                  dirsector = SMARTFS_NEXTSECTOR(header);
                                }
                            }

                          *parentdirsector = dirstack[depth];
                          *filename = segment;
                          ret = OK;
                          goto errout;
                        }
                      else
                        {
                          /* Validate it's a directory */

#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS
                          if ((smartfs_rdle16(&entry->flags) &
                               SMARTFS_DIRENT_TYPE) !=
                              SMARTFS_DIRENT_TYPE_DIR)
#else
                          if ((entry->flags & SMARTFS_DIRENT_TYPE) !=
                              SMARTFS_DIRENT_TYPE_DIR)
#endif
                            {
                              /* Not a directory!  Report the error */

                              ret = -ENOTDIR;
                              goto errout;
                            }

                          /* "Push" the directory and continue searching */

                          if (depth >= CONFIG_SMARTFS_DIRDEPTH - 1)
                            {
                              /* Directory depth too big */

                              ret = -ENAMETOOLONG;
                              goto errout;
                            }

#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS
                          dirstack[++depth] =
                            smartfs_rdle16(&entry->firstsector);
#else
                          dirstack[++depth] = entry->firstsector;
#endif
                          segment = ptr + 1;
                          break;
                        }
                    }

                  /* Not this entry.  Skip to the next one */

                  offset += entrysize;
                  entry = (struct smartfs_entry_header_s *)
                    &fs->fs_rwbuffer[offset];
                }

              /* Test if a directory entry was found and break if it was */

              if (offset < readwrite.count)
                {
                  break;
                }
            }

          /* If we found a dir entry, then continue searching */

          if (offset < readwrite.count)
            {
              /* Update the segment pointer */

              if (*ptr != '\0')
                {
                  ptr++;
                }

              segment = ptr;
              continue;
            }

          /* Entry not found!  Report the error.  Also, if this is the last
           * segment, then report the parent directory sector.
           */

          if (*ptr == '\0')
            {
              *parentdirsector = dirstack[depth];
              *filename = segment;
            }
          else
            {
              *parentdirsector = 0xffff;
              *filename = NULL;
            }

          ret = -ENOENT;
          goto errout;
        }
    }

errout:
  return ret;
}

/****************************************************************************
 * Name: smartfs_createentry
 *
 * Description: Creates a new entry in the specified parent directory, using
 *              the specified type and name.  If the given sectorno is
 *              0xffff, then a new sector is allocated for the new entry,
 *              otherwise the supplied sectorno is used.
 *
 ****************************************************************************/

int smartfs_createentry(FAR struct smartfs_mountpt_s *fs,
                        uint16_t parentdirsector,
                        FAR const char *filename,
                        uint16_t type, mode_t mode,
                        FAR struct smartfs_entry_s *direntry,
                        uint16_t sectorno,
                        FAR struct smartfs_ofile_s *sf)
{
  struct    smart_read_write_s readwrite;
  int       ret;
  uint16_t  psector;
  uint16_t  nextsector;
  uint16_t  offset;
  uint16_t  found;
  uint16_t  entrysize;
  struct    smartfs_entry_header_s *entry;
  struct    smartfs_chain_header_s *chainheader;
  int       update_chain = 0;
  struct    smart_read_write_s     update_readwrite;
  struct    smartfs_chain_header_s update_header;

  /* Start at the 1st sector in the parent directory */

  psector = parentdirsector;
  found = FALSE;
  entrysize = sizeof(struct smartfs_entry_header_s) +
              fs->fs_llformat.namesize;

  /* Validate the name isn't too long */

  if (strlen(filename) > fs->fs_llformat.namesize)
    {
      return -ENAMETOOLONG;
    }

  /* Read the parent directory sector and find a place to insert
   * the new entry.
   */

  while (1)
    {
      /* Read the next sector */

      readwrite.logsector = psector;
      readwrite.count = fs->fs_llformat.availbytes;
      readwrite.offset = 0;
      readwrite.buffer = (uint8_t *) fs->fs_rwbuffer;
      ret = FS_IOCTL(fs, BIOC_READSECT, (unsigned long) &readwrite);
      if (ret < 0)
        {
          goto errout;
        }

      /* Get the next chained sector */

      chainheader = (struct smartfs_chain_header_s *) fs->fs_rwbuffer;
      nextsector = SMARTFS_NEXTSECTOR(chainheader);

      /* Search for an empty entry in this sector */

      offset = sizeof(struct smartfs_chain_header_s);
      entry = (struct smartfs_entry_header_s *) &fs->fs_rwbuffer[offset];
      while (offset + entrysize < readwrite.count)
        {
          /* Check if this entry is available */

#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS
          if ((smartfs_rdle16(&entry->flags) == SMARTFS_ERASEDSTATE_16BIT) ||
              ((smartfs_rdle16(&entry->flags) &
#else
          if ((entry->flags == SMARTFS_ERASEDSTATE_16BIT) ||
              ((entry->flags &
#endif
                (SMARTFS_DIRENT_EMPTY | SMARTFS_DIRENT_ACTIVE)) ==
               (~SMARTFS_ERASEDSTATE_16BIT &
                (SMARTFS_DIRENT_EMPTY | SMARTFS_DIRENT_ACTIVE))))
            {
              /* We found an empty entry.  Use it. */

              found = TRUE;
              break;
            }

          /* Not available.  Skip to next entry */

          offset += entrysize;
          entry = (struct smartfs_entry_header_s *) &fs->fs_rwbuffer[offset];
        }

      /* If we found an entry, stop the search */

      if (found)
        {
          break;
        }

      /* If there are no more sectors, then we need to add one to make
       * room for the new entry.
       */

      if (nextsector == SMARTFS_ERASEDSTATE_16BIT)
        {
          /* Allocate a new sector and chain it to the last one */

          ret = FS_IOCTL(fs, BIOC_ALLOCSECT, 0xffff);
          if (ret < 0)
            {
              goto errout;
            }

          nextsector = (uint16_t) ret;

          /* Chain the next sector into this sector. */

          *((uint16_t *)update_header.nextsector) = nextsector;
          update_readwrite.logsector = psector;
          update_readwrite.offset = offsetof(struct smartfs_chain_header_s,
                                             nextsector);
          update_readwrite.count = sizeof(uint16_t);
          update_readwrite.buffer = update_header.nextsector;
          update_chain = 1;
        }

      /* Now update to the next sector */

      psector = nextsector;
    }

  /* We found an insertion point.  Create the entry at sector,offset */

#if CONFIG_SMARTFS_ERASEDSTATE == 0xff
#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS
  smartfs_wrle16(&entry->flags, (uint16_t) (SMARTFS_DIRENT_ACTIVE |
        SMARTFS_DIRENT_DELETING | SMARTFS_DIRENT_RESERVED | type | (mode &
        SMARTFS_DIRENT_MODE)));
#else
  entry->flags = (uint16_t) (SMARTFS_DIRENT_ACTIVE |
        SMARTFS_DIRENT_DELETING | SMARTFS_DIRENT_RESERVED | type | (mode &
        SMARTFS_DIRENT_MODE));
#endif
#else   /* CONFIG_SMARTFS_ERASEDSTATE == 0xff */
#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS
  smartfs_wrle16(&entry->flags, (uint16_t) (SMARTFS_DIRENT_EMPTY | type |
        (mode & SMARTFS_DIRENT_MODE)));
#else
  entry->flags = (uint16_t) (SMARTFS_DIRENT_EMPTY | type |
        (mode & SMARTFS_DIRENT_MODE));
#endif
#endif /* CONFIG_SMARTFS_ERASEDSTATE == 0xff */

  if (sectorno == 0xffff)
    {
      /* Allocate a new sector for the file / dir */

      ret = FS_IOCTL(fs, BIOC_ALLOCSECT, 0xffff);
      if (ret < 0)
        {
          goto errout;
        }

      nextsector = (uint16_t) ret;

      /* Set the newly allocated sector's type (file or dir) */

#ifdef CONFIG_SMARTFS_USE_SECTOR_BUFFER
      if (sf)
        {
          /* Using sector buffer and we have an open file context.
           * Just update the sector buffer in the open file context.
           */

          memset(sf->buffer, CONFIG_SMARTFS_ERASEDSTATE,
                 fs->fs_llformat.availbytes);
          chainheader = (struct smartfs_chain_header_s *) sf->buffer;
          chainheader->type = SMARTFS_SECTOR_TYPE_FILE;
          sf->bflags = SMARTFS_BFLAG_DIRTY | SMARTFS_BFLAG_NEWALLOC;
        }
      else
#endif
        {
          if ((type & SMARTFS_DIRENT_TYPE) == SMARTFS_DIRENT_TYPE_DIR)
            {
              chainheader->type = SMARTFS_SECTOR_TYPE_DIR;
            }
          else
            {
              chainheader->type = SMARTFS_SECTOR_TYPE_FILE;
            }

          readwrite.count = 1;
          readwrite.offset = offsetof(struct smartfs_chain_header_s, type);
          readwrite.buffer = (uint8_t *) &chainheader->type;
          readwrite.logsector = nextsector;
          ret = FS_IOCTL(fs, BIOC_WRITESECT, (unsigned long) &readwrite);
          if (ret < 0)
            {
              ferr("ERROR: Error %d setting new sector type for sector %d\n",
                   ret, nextsector);
              goto errout;
            }
        }
    }
  else
    {
      /* Use the provided sector number */

      nextsector = sectorno;
    }

  /* Create the directory entry to be written in the parent's sector */

#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS
  smartfs_wrle16(&entry->firstsector, nextsector);
  smartfs_wrle16(&entry->utc, time(NULL));
#else
  entry->firstsector = nextsector;
  entry->utc = time(NULL);
#endif
  memset(entry->name, 0, fs->fs_llformat.namesize);
  strlcpy(entry->name, filename, fs->fs_llformat.namesize);

  /* Now write the new entry to the parent directory sector */

  readwrite.logsector = psector;
  readwrite.offset = offset;
  readwrite.count = entrysize;
  readwrite.buffer = (uint8_t *) &fs->fs_rwbuffer[offset];
  ret = FS_IOCTL(fs, BIOC_WRITESECT, (unsigned long) &readwrite);
  if (ret < 0)
    {
      goto errout;
    }

  if (update_chain)
    {
      /* Update chain header after the next sector was written */

      ret = FS_IOCTL(fs, BIOC_WRITESECT, (unsigned long) &update_readwrite);
      if (ret < 0)
        {
          ferr("ERROR: Error chaining sector %d\n",
               update_readwrite.logsector);
          goto errout;
        }
    }

  /* Now fill in the entry */

  direntry->firstsector = nextsector;
  direntry->dsector = psector;
  direntry->doffset = offset;
#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS
  direntry->flags = smartfs_rdle16(&entry->flags);
  direntry->utc = smartfs_rdle32(&entry->utc);
#else
  direntry->flags = entry->flags;
  direntry->utc = entry->utc;
#endif
  direntry->datlen = 0;
  if (direntry->name == NULL)
    {
      direntry->name = kmm_malloc(fs->fs_llformat.namesize + 1);
    }

  memset(direntry->name, 0, fs->fs_llformat.namesize + 1);
  strlcpy(direntry->name, filename, fs->fs_llformat.namesize);

  ret = OK;

errout:
  return ret;
}

/****************************************************************************
 * Name: smartfs_deleteentry
 *
 * Description: Deletes an entry from the filesystem (file or dir) by
 *              freeing all the entry's sectors and then marking it inactive
 *              in it's parent's directory sector.  For a directory, it
 *              does not validate the directory is empty, nor does it do
 *              a recursive delete.
 *
 ****************************************************************************/

int smartfs_deleteentry(struct smartfs_mountpt_s *fs,
        struct smartfs_entry_s *entry)
{
  int                             ret;
  uint16_t                        nextsector;
  uint16_t                        sector;
  uint16_t                        count;
  uint16_t                        entrysize;
  uint16_t                        offset;
  struct smartfs_entry_header_s  *direntry;
  struct smartfs_chain_header_s  *header;
  struct smart_read_write_s       readwrite;

  /* Okay, delete the file.  Loop through each sector and release them
   *
   * TODO:  We really should walk the list backward to avoid lost
   *        sectors in the event we lose power. However this requires
   *        allocating a buffer to build the sector list since we don't
   *        store a doubly-linked list of sectors on the device.  We
   *        could test if the sector data buffer is big enough and
   *        just use that, and only allocate a new buffer if the
   *        sector buffer isn't big enough.  Do do this, however, we
   *        need to change the code below as it is using the a few
   *        bytes of the buffer to read in header info.
   */

  nextsector = entry->firstsector;
  header = (struct smartfs_chain_header_s *) fs->fs_rwbuffer;
  readwrite.offset = 0;
  readwrite.count = sizeof(struct smartfs_chain_header_s);
  readwrite.buffer = (uint8_t *) fs->fs_rwbuffer;
  while (nextsector != SMARTFS_ERASEDSTATE_16BIT)
    {
      /* Read the next sector into our buffer */

      sector = nextsector;
      readwrite.logsector = sector;
      ret = FS_IOCTL(fs, BIOC_READSECT, (unsigned long) &readwrite);
      if (ret < 0)
        {
          ferr("ERROR: Error reading sector %d\n", nextsector);
          break;
        }

      /* Release this sector */

      nextsector = SMARTFS_NEXTSECTOR(header);
      ret = FS_IOCTL(fs, BIOC_FREESECT, sector);
    }

  /* Remove the entry from the directory tree */

  readwrite.logsector = entry->dsector;
  readwrite.offset = 0;
  readwrite.count = fs->fs_llformat.availbytes;
  readwrite.buffer = (uint8_t *) fs->fs_rwbuffer;
  ret = FS_IOCTL(fs, BIOC_READSECT, (unsigned long) &readwrite);
  if (ret < 0)
    {
      ferr("ERROR: Error reading directory info at sector %d\n",
           entry->dsector);
      goto errout;
    }

  /* Mark this entry as inactive */

  direntry = (struct smartfs_entry_header_s *)
    &fs->fs_rwbuffer[entry->doffset];
#if CONFIG_SMARTFS_ERASEDSTATE == 0xff
#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS
  smartfs_wrle16(&direntry->flags,
                 smartfs_rdle16(&direntry->flags) & ~SMARTFS_DIRENT_ACTIVE);
#else
  direntry->flags &= ~SMARTFS_DIRENT_ACTIVE;
#endif
#else   /* CONFIG_SMARTFS_ERASEDSTATE == 0xff */
#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS
  smartfs_wrle16(&direntry->flags,
                 smartfs_rdle16(&direntry->flags) | SMARTFS_DIRENT_ACTIVE);
#else
  direntry->flags |= SMARTFS_DIRENT_ACTIVE;
#endif
#endif /* CONFIG_SMARTFS_ERASEDSTATE == 0xff */

  /* Write the updated flags back to the sector */

  readwrite.offset = entry->doffset;
  readwrite.count = sizeof(uint16_t);
  readwrite.buffer = (uint8_t *) &direntry->flags;
  ret = FS_IOCTL(fs, BIOC_WRITESECT, (unsigned long) &readwrite);
  if (ret < 0)
    {
      ferr("ERROR: Error marking entry inactive at sector %d\n",
           entry->dsector);
      goto errout;
    }

  /* Test if any entries in this sector are being used */

  if ((entry->dsector != fs->fs_rootsector) &&
      (entry->dsector != entry->dfirst))
    {
      /* Scan the sector and count used entries */

      count = 0;
      offset = sizeof(struct smartfs_chain_header_s);
      entrysize = sizeof(struct smartfs_entry_header_s) +
                  fs->fs_llformat.namesize;
      while (offset + entrysize < fs->fs_llformat.availbytes)
        {
          /* Test the next entry */

          direntry = (struct smartfs_entry_header_s *)
            &fs->fs_rwbuffer[offset];
#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS
          if (((smartfs_rdle16(&direntry->flags) & SMARTFS_DIRENT_EMPTY) !=
              (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_EMPTY)) &&
              ((smartfs_rdle16(&direntry->flags) & SMARTFS_DIRENT_ACTIVE) ==
              (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_ACTIVE)))
#else
          if (((direntry->flags & SMARTFS_DIRENT_EMPTY) !=
              (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_EMPTY)) &&
              ((direntry->flags & SMARTFS_DIRENT_ACTIVE) ==
              (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_ACTIVE)))
#endif
            {
              /* Count this entry */

              count++;
            }

          /* Advance to next entry */

          offset += entrysize;
        }

      /* Test if the count it zero.
       * If it is, then we will release the sector
       */

      if (count == 0)
        {
          /* Okay, to release the sector, we must find the sector that we
           * are chained to and remove ourselves from the chain.  First
           * save our nextsector value so we can "unchain" ourselves.
           */

          nextsector = SMARTFS_NEXTSECTOR(header);

          /* Now loop through the dir sectors to find ourselves in the
           * chain
           */

          sector = entry->dfirst;
          readwrite.offset = 0;
          readwrite.count = sizeof(struct smartfs_chain_header_s);
          readwrite.buffer = (uint8_t *) fs->fs_rwbuffer;
          while (sector != SMARTFS_ERASEDSTATE_16BIT)
            {
              /* Read the header for the next sector */

              readwrite.logsector = sector;
              ret = FS_IOCTL(fs, BIOC_READSECT, (unsigned long) &readwrite);
              if (ret < 0)
                {
                  ferr("ERROR: Error reading sector %d\n", nextsector);
                  break;
                }

              /* Test if this sector "points" to us */

              if (SMARTFS_NEXTSECTOR(header) == entry->dsector)
                {
                  /* We found ourselves in the chain.  Update the chain. */

                  SMARTFS_SET_NEXTSECTOR(header, nextsector);
                  readwrite.offset = offsetof(struct smartfs_chain_header_s,
                                              nextsector);
                  readwrite.count  = sizeof(uint16_t);
                  readwrite.buffer = header->nextsector;

                  ret = FS_IOCTL(fs, BIOC_WRITESECT,
                                 (unsigned long)&readwrite);
                  if (ret < 0)
                    {
                      ferr("ERROR: Error unchaining sector (%d)\n",
                            nextsector);
                      goto errout;
                    }

                  /* Now release our sector */

                  ret = FS_IOCTL(fs, BIOC_FREESECT,
                                 (unsigned long)entry->dsector);
                  if (ret < 0)
                    {
                      ferr("ERROR: Error freeing sector %d\n",
                            entry->dsector);
                      goto errout;
                    }

                  /* Break out of the loop, we are done! */

                  break;
                }

              /* Chain to the next sector */

              sector = SMARTFS_NEXTSECTOR(header);
            }
        }
    }

  ret = OK;

errout:
  return ret;
}

/****************************************************************************
 * Name: smartfs_countdirentries
 *
 * Description: Counts the number of items in the specified directory entry.
 *              This routine assumes you have validated the entry you are
 *              passing is in fact a directory sector, though it checks
 *              just in case you were stupid :-)
 *
 ****************************************************************************/

int smartfs_countdirentries(struct smartfs_mountpt_s *fs,
        struct smartfs_entry_s *entry)
{
  int                             ret;
  uint16_t                        nextsector;
  uint16_t                        offset;
  uint16_t                        entrysize;
  int                             count;
  struct smartfs_entry_header_s  *direntry;
  struct smartfs_chain_header_s  *header;
  struct smart_read_write_s       readwrite;

  /* Walk through the directory's sectors and count entries */

  count = 0;
  nextsector = entry->firstsector;
  while (nextsector != SMARTFS_ERASEDSTATE_16BIT)
    {
      /* Read the next sector into our buffer */

      readwrite.logsector = nextsector;
      readwrite.offset = 0;
      readwrite.count = fs->fs_llformat.availbytes;
      readwrite.buffer = (uint8_t *) fs->fs_rwbuffer;
      ret = FS_IOCTL(fs, BIOC_READSECT, (unsigned long) &readwrite);
      if (ret < 0)
        {
          ferr("ERROR: Error reading sector %d\n", nextsector);
          break;
        }

      /* Validate this is a directory type sector */

      header = (struct smartfs_chain_header_s *) fs->fs_rwbuffer;
      if (header->type != SMARTFS_SECTOR_TYPE_DIR)
        {
          ferr("ERROR: Sector %d is not a DIR sector!\n", nextsector);
          goto errout;
        }

      /* Loop for all entries in this sector and count them */

      offset = sizeof(struct smartfs_chain_header_s);
      entrysize = sizeof(struct smartfs_entry_header_s) +
        fs->fs_llformat.namesize;
      direntry = (struct smartfs_entry_header_s *) &fs->fs_rwbuffer[offset];
      while (offset + entrysize < readwrite.count)
        {
#ifdef CONFIG_SMARTFS_ALIGNED_ACCESS
          if (((smartfs_rdle16(&direntry->flags) & SMARTFS_DIRENT_EMPTY) !=
              (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_EMPTY)) &&
              ((smartfs_rdle16(&direntry->flags) & SMARTFS_DIRENT_ACTIVE) ==
              (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_ACTIVE)))
#else
          if (((direntry->flags & SMARTFS_DIRENT_EMPTY) !=
              (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_EMPTY)) &&
              ((direntry->flags & SMARTFS_DIRENT_ACTIVE) ==
              (SMARTFS_ERASEDSTATE_16BIT & SMARTFS_DIRENT_ACTIVE)))
#endif
            {
              /* Count this entry */

              count++;
            }

          offset += entrysize;
          direntry = (struct smartfs_entry_header_s *)
            &fs->fs_rwbuffer[offset];
        }

      /* Get the next sector from the header */

      nextsector = SMARTFS_NEXTSECTOR(header);
    }

  ret = count;

errout:
  return ret;
}

/****************************************************************************
 * Name: smartfs_sync_internal
 *
 * Description:
 *   Synchronize the file state on disk to match internal, in-memory state.
 *
 ****************************************************************************/

int smartfs_sync_internal(FAR struct smartfs_mountpt_s *fs,
                          FAR struct smartfs_ofile_s *sf)
{
  FAR struct smartfs_chain_header_s *header;
  struct smart_read_write_s readwrite;
  int ret = OK;

#ifdef CONFIG_SMARTFS_USE_SECTOR_BUFFER
  if (sf->bflags & SMARTFS_BFLAG_DIRTY)
    {
      /* Update the header with the number of bytes written */

      header = (struct smartfs_chain_header_s *)sf->buffer;

      if (SMARTFS_USED(header) == SMARTFS_ERASEDSTATE_16BIT)
        {
          SMARTFS_SET_USED(header, sf->byteswritten);
        }
      else
        {
          SMARTFS_SET_USED(header, SMARTFS_USED(header)
                                   + sf->byteswritten);
        }

      /* Write the entire sector to FLASH */

      readwrite.logsector = sf->currsector;
      readwrite.offset    = 0;
      readwrite.count     = fs->fs_llformat.availbytes;
      readwrite.buffer    = sf->buffer;

      ret = FS_IOCTL(fs, BIOC_WRITESECT, (unsigned long) &readwrite);
      if (ret < 0)
        {
          ferr("ERROR: Error %d writing used bytes for sector %d\n",
               ret, sf->currsector);
          goto errout;
        }

      sf->byteswritten = 0;
      sf->bflags = 0;
    }
#else  /* CONFIG_SMARTFS_USE_SECTOR_BUFFER */

  /* Test if we have written bytes to the current sector that
   * need to be recorded in the chain header's used bytes field.
   */

  if (sf->byteswritten > 0)
    {
      finfo("Syncing sector %d\n", sf->currsector);

      /* Read the existing sector used bytes value */

      readwrite.logsector = sf->currsector;
      readwrite.offset    = 0;
      readwrite.buffer    = (uint8_t *) fs->fs_rwbuffer;
      readwrite.count     = sizeof(struct smartfs_chain_header_s);

      ret = FS_IOCTL(fs, BIOC_READSECT, (unsigned long) &readwrite);
      if (ret < 0)
        {
          ferr("ERROR: Error %d reading sector %d data\n",
               ret, sf->currsector);
          goto errout;
        }

      /* Add new byteswritten to existing value */

      header = (struct smartfs_chain_header_s *) fs->fs_rwbuffer;

      if (SMARTFS_USED(header) == SMARTFS_ERASEDSTATE_16BIT)
        {
          SMARTFS_SET_USED(header, sf->byteswritten);
        }
      else
        {
          SMARTFS_SET_USED(header, SMARTFS_USED(header)
                                   + sf->byteswritten);
        }

      readwrite.offset = offsetof(struct smartfs_chain_header_s, used);
      readwrite.count  = sizeof(uint16_t);
      readwrite.buffer = (uint8_t *) &fs->fs_rwbuffer[readwrite.offset];

      ret = FS_IOCTL(fs, BIOC_WRITESECT, (unsigned long) &readwrite);
      if (ret < 0)
        {
          ferr("ERROR: Error %d writing used bytes for sector %d\n",
               ret, sf->currsector);
          goto errout;
        }

      sf->byteswritten = 0;
    }
#endif /* CONFIG_SMARTFS_USE_SECTOR_BUFFER */

errout:
  return ret;
}

/****************************************************************************
 * Name: smartfs_seek_internal
 *
 * Description:
 *   Performs the logic of the seek function.  This is an internal function
 *   because it does not provide semaphore protection and therefore must be
 *   called from one of the other public interface routines (open, seek,
 *   etc.).
 *
 ****************************************************************************/

off_t smartfs_seek_internal(FAR struct smartfs_mountpt_s *fs,
                            FAR struct smartfs_ofile_s *sf,
                            off_t offset, int whence)
{
  FAR struct smartfs_chain_header_s *header;
  struct smart_read_write_s readwrite;
  off_t newpos;
  off_t sectorstartpos;
  int ret;

  /* Test if this is a seek to get the current file pos */

  if ((whence == SEEK_CUR) && (offset == 0))
    {
      return sf->filepos;
    }

  /* Test if we need to sync the file */

  if (sf->byteswritten > 0)
    {
      /* Perform a sync */

      smartfs_sync_internal(fs, sf);
    }

  /* Calculate the file position to seek to based on current position */

  switch (whence)
  {
    case SEEK_SET:
    default:
      newpos = offset;
      break;

    case SEEK_CUR:
      newpos = sf->filepos + offset;
      break;

    case SEEK_END:
      newpos = sf->entry.datlen + offset;
      break;
  }

  /* Ensure newpos is in range */

  if (newpos < 0)
    {
      newpos = 0;
    }

  if (newpos > sf->entry.datlen)
    {
      newpos = sf->entry.datlen;
    }

  /* Now perform the seek.  Test if we are seeking within the current
   * sector and can skip the search to save time.
   */

  sectorstartpos = sf->filepos - (sf->curroffset - sizeof(struct
        smartfs_chain_header_s));

  if (newpos >= sectorstartpos && newpos < sectorstartpos +
      fs->fs_llformat.availbytes - sizeof(struct smartfs_chain_header_s))
    {
      /* Seeking within the current sector.  Just update the offset */

      sf->curroffset = sizeof(struct smartfs_chain_header_s) +
                       newpos - sectorstartpos;
      sf->filepos    = newpos;

      return newpos;
    }

  /* Nope, we have to search for the sector and offset.  If the new pos is
   * greater than the current pos, then we can start from the beginning of
   * the current sector, otherwise we have to start from the beginning of
   * the file.
   */

  if (newpos > sf->filepos)
    {
      sf->filepos = sectorstartpos;
    }
  else
    {
      sf->currsector = sf->entry.firstsector;
      sf->filepos = 0;
    }

  header = (struct smartfs_chain_header_s *) fs->fs_rwbuffer;
  while ((sf->currsector != SMARTFS_ERASEDSTATE_16BIT) &&
      (sf->filepos + fs->fs_llformat.availbytes -
      sizeof(struct smartfs_chain_header_s) < newpos))
    {
      /* Read the sector's header */

      readwrite.logsector = sf->currsector;
      readwrite.offset    = 0;
      readwrite.count     = sizeof(struct smartfs_chain_header_s);
      readwrite.buffer    = (uint8_t *) fs->fs_rwbuffer;

      ret = FS_IOCTL(fs, BIOC_READSECT, (unsigned long) &readwrite);
      if (ret < 0)
        {
          ferr("ERROR: Error %d reading sector %d header\n",
               ret, sf->currsector);
          goto errout;
        }

      /* Point to next sector and update filepos */

      sf->currsector = SMARTFS_NEXTSECTOR(header);
      sf->filepos += SMARTFS_USED(header);
    }

#ifdef CONFIG_SMARTFS_USE_SECTOR_BUFFER

  /* When using sector buffering, we must read in the last buffer to our
   * sf->buffer in case any changes are made.
   */

  if (sf->currsector != SMARTFS_ERASEDSTATE_16BIT)
    {
      readwrite.logsector = sf->currsector;
      readwrite.offset = 0;
      readwrite.count = fs->fs_llformat.availbytes;
      readwrite.buffer = (uint8_t *) sf->buffer;
      ret = FS_IOCTL(fs, BIOC_READSECT, (unsigned long) &readwrite);
      if (ret < 0)
        {
          ferr("ERROR: Error %d reading sector %d header\n",
               ret, sf->currsector);
          goto errout;
        }
    }
#endif

  /* Now calculate the offset */

  sf->curroffset = sizeof(struct smartfs_chain_header_s) + newpos -
                   sf->filepos;
  sf->filepos = newpos;
  return newpos;

errout:
  return ret;
}

/****************************************************************************
 * Name: smartfs_shrinkfile
 *
 * Description:
 *   Shrink the size of an existing file to the specified length
 *
 ****************************************************************************/

int smartfs_shrinkfile(FAR struct smartfs_mountpt_s *fs,
                       FAR struct smartfs_ofile_s *sf, off_t length)
{
  FAR struct smartfs_chain_header_s *header;
  FAR struct smartfs_entry_s *entry;
  FAR uint8_t *dest;
  struct smart_read_write_s readwrite;
  uint16_t nextsector;
  uint16_t sector;
  off_t remaining;
  off_t destsize;
  off_t available;
  off_t offset;
  int ret;

  /* Walk through the directory's sectors and count entries */

  entry      = &sf->entry;
  nextsector = entry->firstsector;
  header     = (struct smartfs_chain_header_s *)fs->fs_rwbuffer;
  remaining  = length;
  available  = fs->fs_llformat.availbytes -
               sizeof(struct smartfs_chain_header_s);

  while (nextsector != SMARTFS_ERASEDSTATE_16BIT)
    {
      /* Read the next sector into our buffer */

      readwrite.logsector = nextsector;
      readwrite.offset    = 0;
      readwrite.count     = fs->fs_llformat.availbytes;
      readwrite.buffer    = (FAR uint8_t *)fs->fs_rwbuffer;

      ret = FS_IOCTL(fs, BIOC_READSECT, (unsigned long) &readwrite);
      if (ret < 0)
        {
          ferr("ERROR: Error reading sector %d header\n", nextsector);
          return ret;
        }

      /* Get the next chained sector */

      sector = SMARTFS_NEXTSECTOR(header);

#ifdef CONFIG_SMARTFS_USE_SECTOR_BUFFER
      /* When we have a sector buffer in use, simply skip the first sector.
       * It will be handled below.
       */

      if (nextsector == entry->firstsector)
        {
          if (remaining > available)
            {
              remaining -= available;
            }
          else
            {
              remaining = 0;
            }
        }
#endif

      /* Are we retaining the sector it its entirety? */

      if (remaining >= available)
        {
          /* Yes... skip to the next sector */

          remaining -= available;
        }

      /* Are we removing the sector it its entirety? */

      else if (remaining <= 0 && nextsector != entry->firstsector)
        {
          /* Yes.. just release the sector */

          ret = FS_IOCTL(fs, BIOC_FREESECT, (unsigned long)nextsector);
          if (ret < 0)
            {
              ferr("ERROR: Error freeing sector %d\n", nextsector);
              return ret;
            }
        }
      else
        {
          /* No.. Fill our buffer with erased data, retaining any still-
           * valid bytes at the beginning of the buffer.
           *
           * Because of the preceding tests we know that
           * 0 <= remaining < available.  A special case is remaining == 0
           * and nextsector == firstsector.  In that case, we need to
           * overwrite the sector data with the erased state value.  The
           * underlying SMART block driver will detect this and release the
           * old sector and create a new one with the new (blank) data.
           *
           * Otherwise, we need to preserve the header and overwrite some of
           * the data.
           */

          if (remaining == 0)
            {
              dest       = (FAR uint8_t *)fs->fs_rwbuffer;
              destsize   = fs->fs_llformat.availbytes;
            }
          else
            {
              offset     = sizeof(struct smartfs_chain_header_s) + remaining;
              dest       = (FAR uint8_t *)&fs->fs_rwbuffer[offset];
              destsize   = fs->fs_llformat.availbytes - offset;

              SMARTFS_SET_USED(header, remaining);
              SMARTFS_SET_NEXTSECTOR(header, SMARTFS_ERASEDSTATE_16BIT);
              remaining  = 0;
            }

          memset(dest, CONFIG_SMARTFS_ERASEDSTATE, destsize);
          header->type = SMARTFS_SECTOR_TYPE_FILE;

          /* Now write the new sector data */

          readwrite.count = fs->fs_llformat.availbytes;

          ret = FS_IOCTL(fs, BIOC_WRITESECT, (unsigned long)&readwrite);
          if (ret < 0)
            {
              ferr("ERROR: Error blanking 1st sector (%d) of file\n",
                    nextsector);
              return ret;
            }
        }

      /* Now move on to the next sector */

      nextsector = sector;
    }

#ifdef CONFIG_SMARTFS_USE_SECTOR_BUFFER
  /* Now deal with the first sector in the event we are using a sector buffer
   * like we would be if CRC is enabled.
   *
   * Using sector buffer and we have an open file context.  Just update the
   * sector buffer in the open file context.
   */

  if (length < fs->fs_llformat.availbytes)
    {
      /* Read the entire sector */

      readwrite.logsector = entry->firstsector;
      readwrite.offset    = 0;
      readwrite.count     = fs->fs_llformat.availbytes;
      readwrite.buffer    = (uint8_t *)sf->buffer;

      ret = FS_IOCTL(fs, BIOC_READSECT, (unsigned long)&readwrite);
      if (ret < 0)
        {
          return ret;
        }

      /* Retain any valid data at the beginning of the sector, including the
       * header.  Special case length == 0
       */

      if (length == 0)
        {
          dest       = (FAR uint8_t *)sf->buffer;
          destsize   = fs->fs_llformat.availbytes;
        }
      else
        {
          offset     = sizeof(struct smartfs_chain_header_s) + length;
          dest       = (FAR uint8_t *)&sf->buffer[offset];
          destsize   = fs->fs_llformat.availbytes - offset;

          header     = (struct smartfs_chain_header_s *)sf->buffer;

          SMARTFS_SET_USED(header, length);
          SMARTFS_SET_NEXTSECTOR(header, SMARTFS_ERASEDSTATE_16BIT);
        }

      memset(dest, CONFIG_SMARTFS_ERASEDSTATE, destsize);

      header        = (struct smartfs_chain_header_s *)sf->buffer;
      header->type  = SMARTFS_SECTOR_TYPE_FILE;
      sf->bflags    = SMARTFS_BFLAG_DIRTY;
    }
#endif

  entry->datlen = length;
  return OK;
}

/****************************************************************************
 * Name: smartfs_extendfile
 *
 * Description:
 *   Zero-extend the length of a regular file to 'length'.
 *
 ****************************************************************************/

int smartfs_extendfile(FAR struct smartfs_mountpt_s *fs,
                       FAR struct smartfs_ofile_s *sf, off_t length)
{
  struct smart_read_write_s readwrite;
  FAR struct smartfs_chain_header_s *header;
#ifndef CONFIG_SMARTFS_USE_SECTOR_BUFFER
  FAR uint8_t *buffer;
#endif
  off_t remaining;
  off_t savepos;
  off_t oldsize;
  int ret;

  /* We are zero-extending the file.  This is essentially the same as a
   * write except that (1) we write zeros and (2) we don't update the file
   * position.
   */

#ifndef CONFIG_SMARTFS_USE_SECTOR_BUFFER
  /* In order to perform the writes we will have to have a sector buffer.  If
   * SmartFS is not configured with a sector buffer then we will, then we
   * will, unfortunately, need to allocate one.
   */

  buffer = kmm_malloc(SMARTFS_TRUNCBUFFER_SIZE);
  if (buffer == NULL)
    {
      return -ENOMEM;
    }
#endif

  /* Loop until either (1) the file has been fully extended with zeroed data
   * or (2) an error occurs.  We assume we start with the current sector in
   * cache (ff_currentsector).
   */

  oldsize   = sf->entry.datlen;
  remaining = length - oldsize;
  DEBUGASSERT(length > oldsize);

  /* Seek to the end of the file for the append/write operation, remembering
   * the current file position.  It will be restored before returning; the
   * truncate operation must not alter the file position.
   */

  savepos = sf->filepos;
  smartfs_seek_internal(fs, sf, 0, SEEK_END);

  while (remaining > 0)
    {
      /* We will fill up the current sector. Write data to the current
       * sector first.
       */

#ifdef CONFIG_SMARTFS_USE_SECTOR_BUFFER
      readwrite.count = fs->fs_llformat.availbytes - sf->curroffset;
      if (readwrite.count > remaining)
        {
          readwrite.count = remaining;
        }

      memset(&sf->buffer[sf->curroffset], 0, readwrite.count);
      sf->bflags |= SMARTFS_BFLAG_DIRTY;

#else  /* CONFIG_SMARTFS_USE_SECTOR_BUFFER */
      readwrite.offset    = sf->curroffset;
      readwrite.logsector = sf->currsector;
      readwrite.buffer    = buffer;

      /* Select max size that available in the current sector */

      readwrite.count     = fs->fs_llformat.availbytes - sf->curroffset;
      if (readwrite.count > remaining)
        {
          /* Limit the write to the size for our smaller working buffer */

          readwrite.count = SMARTFS_TRUNCBUFFER_SIZE;
        }

      if (readwrite.count > remaining)
        {
          /* Further limit the write to the remaining bytes to write */

          readwrite.count = remaining;
        }

      /* Perform the write */

      if (readwrite.count > 0)
        {
          ret = FS_IOCTL(fs, BIOC_WRITESECT, (unsigned long) &readwrite);
          if (ret < 0)
            {
              ferr("ERROR: Error %d writing sector %d data\n",
                   ret, sf->currsector);
              goto errout_with_buffer;
            }
        }
#endif /* CONFIG_SMARTFS_USE_SECTOR_BUFFER */

      /* Update our control variables */

      sf->entry.datlen += readwrite.count;
      sf->byteswritten += readwrite.count;
      sf->curroffset   += readwrite.count;
      remaining        -= readwrite.count;

      /* Test if we wrote a full sector of data */

#ifdef CONFIG_SMARTFS_USE_SECTOR_BUFFER
      if (sf->curroffset == fs->fs_llformat.availbytes && remaining)
        {
          /* First get a new chained sector */

          ret = FS_IOCTL(fs, BIOC_ALLOCSECT, 0xffff);
          if (ret < 0)
            {
              ferr("ERROR: Error %d allocating new sector\n", ret);
              goto errout_with_buffer;
            }

          /* Copy the new sector to the old one and chain it */

          header = (struct smartfs_chain_header_s *) sf->buffer;
          SMARTFS_SET_NEXTSECTOR(header, ret);

          /* Now sync the file to write this sector out */

          ret = smartfs_sync_internal(fs, sf);
          if (ret != OK)
            {
              goto errout_with_buffer;
            }

          /* Record the new sector in our tracking variables and reset the
           * offset to "zero".
           */

          if (sf->currsector == SMARTFS_NEXTSECTOR(header))
            {
              /* Error allocating logical sector! */

              ferr("ERROR: Duplicate logical sector %d\n", sf->currsector);
            }

          sf->bflags     = SMARTFS_BFLAG_DIRTY;
          sf->currsector = SMARTFS_NEXTSECTOR(header);
          sf->curroffset = sizeof(struct smartfs_chain_header_s);
          memset(sf->buffer, CONFIG_SMARTFS_ERASEDSTATE,
                 fs->fs_llformat.availbytes);
          header->type   = SMARTFS_DIRENT_TYPE_FILE;
        }
#else  /* CONFIG_SMARTFS_USE_SECTOR_BUFFER */

      if (sf->curroffset == fs->fs_llformat.availbytes)
        {
          /* Sync the file to write this sector out */

          ret = smartfs_sync_internal(fs, sf);
          if (ret != OK)
            {
              goto errout_with_buffer;
            }

          /* Allocate a new sector if needed */

          if (remaining > 0)
            {
              /* Allocate a new sector */

              ret = FS_IOCTL(fs, BIOC_ALLOCSECT, 0xffff);
              if (ret < 0)
                {
                  ferr("ERROR: Error %d allocating new sector\n", ret);
                  goto errout_with_buffer;
                }

              /* Copy the new sector to the old one and chain it */

              header = (struct smartfs_chain_header_s *)fs->fs_rwbuffer;
              SMARTFS_SET_NEXTSECTOR(header, ret);

              readwrite.offset = offsetof(struct smartfs_chain_header_s,
                                          nextsector);
              readwrite.buffer = (FAR uint8_t *)header->nextsector;
              readwrite.count  = sizeof(uint16_t);

              ret = FS_IOCTL(fs, BIOC_WRITESECT, (unsigned long) &readwrite);
              if (ret < 0)
                {
                  ferr("ERROR: Error %d writing next sector\n", ret);
                  goto errout_with_buffer;
                }

              /* Record the new sector in our tracking variables and
               * reset the offset to "zero".
               */

              if (sf->currsector == SMARTFS_NEXTSECTOR(header))
                {
                  /* Error allocating logical sector! */

                  ferr("ERROR: Duplicate logical sector %d\n",
                        sf->currsector);
                }

              sf->currsector = SMARTFS_NEXTSECTOR(header);
              sf->curroffset = sizeof(struct smartfs_chain_header_s);
            }
        }
#endif /* CONFIG_SMARTFS_USE_SECTOR_BUFFER */
    }

  /* The file was successfully extended with zeros */

  ret = OK;

errout_with_buffer:
#ifndef CONFIG_SMARTFS_USE_SECTOR_BUFFER
  /* Release the allocated buffer */

  kmm_free(buffer);
#endif
  /* Restore the original file position */

  smartfs_seek_internal(fs, sf, savepos, SEEK_SET);
  return ret;
}

/****************************************************************************
 * Name: smartfs_get_first_mount
 *
 * Description: Returns a pointer to the first mounted smartfs volume.
 *
 ****************************************************************************/

#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_SMARTFS)
FAR struct smartfs_mountpt_s *smartfs_get_first_mount(void)
{
  return g_mounthead;
}
#endif
