Esempio n. 1
0
static inline int nxffs_wrname(FAR struct nxffs_volume_s *volume,
                               FAR struct nxffs_entry_s *entry,
                               int namlen)
{
  int ret;

  /* Seek to the inode name position and assure that it is in the volume
   * cache.
   */

  nxffs_ioseek(volume, entry->noffset);
  ret = nxffs_rdcache(volume, volume->ioblock);
  if (ret < 0)
    {
      fdbg("ERROR: Failed to read inode name block %d: %d\n",
           volume->ioblock, -ret);
      return ret;
    }

  /* Copy the inode name to the volume cache and write the inode name block */

  memcpy(&volume->cache[volume->iooffset], entry->name, namlen);
  ret = nxffs_wrcache(volume);
  if (ret < 0)
    {
      fdbg("ERROR: Failed to write inode header block %d: %d\n",
           volume->ioblock, -ret);
    }

  return ret;
}
Esempio n. 2
0
int nxffs_wrinode(FAR struct nxffs_volume_s *volume,
                  FAR struct nxffs_entry_s *entry)
{
  FAR struct nxffs_inode_s *inode;
  uint32_t crc;
  int namlen;
  int ret;

  /* Seek to the inode header position and assure that it is in the volume
   * cache.
   */

  nxffs_ioseek(volume, entry->hoffset);
  ret = nxffs_rdcache(volume, volume->ioblock);
  if (ret < 0)
    {
      fdbg("ERROR: Failed to read inode header block %d: %d\n",
           volume->ioblock, -ret);
      goto errout;
    }

  /* Get the length of the inode name */

  namlen = strlen(entry->name);
  DEBUGASSERT(namlen < CONFIG_NXFFS_MAXNAMLEN); /* This was verified earlier */

  /* Initialize the inode header */

  inode = (FAR struct nxffs_inode_s *)&volume->cache[volume->iooffset];
  memcpy(inode->magic, g_inodemagic, NXFFS_MAGICSIZE);

  inode->state  = CONFIG_NXFFS_ERASEDSTATE;
  inode->namlen = namlen;

  nxffs_wrle32(inode->noffs,  entry->noffset);
  nxffs_wrle32(inode->doffs,  entry->doffset);
  nxffs_wrle32(inode->utc,    entry->utc);
  nxffs_wrle32(inode->crc,    0);
  nxffs_wrle32(inode->datlen, entry->datlen);

  /* Calculate the CRC */

  crc = crc32((FAR const uint8_t *)inode, SIZEOF_NXFFS_INODE_HDR);
  crc = crc32part((FAR const uint8_t *)entry->name, namlen, crc);

  /* Finish the inode header */

  inode->state = INODE_STATE_FILE;
  nxffs_wrle32(inode->crc, crc);

  /* Write the block with the inode header */

  ret = nxffs_wrcache(volume);
  if (ret < 0)
    {
      fdbg("ERROR: Failed to write inode header block %d: %d\n",
           volume->ioblock, -ret);
    }

  /* The volume is now available for other writers */

errout:
  sem_post(&volume->wrsem);
  return ret;
}
int nxffs_wrblkhdr(FAR struct nxffs_volume_s *volume,
                   FAR struct nxffs_wrfile_s *wrfile)
{
  FAR struct nxffs_data_s *dathdr;
  int ret;

  /* Write the data block header to memory */

  nxffs_ioseek(volume, wrfile->doffset);
  dathdr = (FAR struct nxffs_data_s *)&volume->cache[volume->iooffset];
  memcpy(dathdr->magic, g_datamagic, NXFFS_MAGICSIZE);
  nxffs_wrle32(dathdr->crc, 0);
  nxffs_wrle16(dathdr->datlen, wrfile->datlen);

  /* Update the entire data block CRC (including the header) */

  wrfile->crc = crc32(&volume->cache[volume->iooffset], wrfile->datlen + SIZEOF_NXFFS_DATA_HDR);
  nxffs_wrle32(dathdr->crc, wrfile->crc);

  /* And write the data block to FLASH */

  ret = nxffs_wrcache(volume);
  if (ret < 0)
    {
      fdbg("ERROR: nxffs_wrcache failed: %d\n", -ret);
      goto errout;
    }

  /* After the block has been successfully written to flash, update the inode
   * statistics and reset the write state.
   *
   * volume:
   *   froffset - The offset the next free FLASH region.  Set to just after
   *     the inode data block that we just wrote.  This is where we will
   *     begin the search for the next inode header or data block.
   */

  volume->froffset = (wrfile->doffset + wrfile->datlen + SIZEOF_NXFFS_DATA_HDR);

  /* wrfile->file.entry:
   *   datlen:  Total file length accumulated so far.  When the file is
   *     closed, this will hold the file length.
   *   doffset: Offset to the first data block.  Only the offset to the
   *     first data block is saved.
   */

  wrfile->ofile.entry.datlen += wrfile->datlen;
  if (wrfile->ofile.entry.doffset == 0)
    {
      wrfile->ofile.entry.doffset = wrfile->doffset;
    }

  /* Return success */

  ret = OK;

errout:
  wrfile->crc     = 0;
  wrfile->doffset = 0;
  wrfile->datlen  = 0;
  return ret;
}
Esempio n. 4
0
int nxffs_rminode(FAR struct nxffs_volume_s *volume, FAR const char *name)
{
  FAR struct nxffs_ofile_s *ofile;
  FAR struct nxffs_inode_s *inode;
  struct nxffs_entry_s entry;
  int ret;

  /* Check if the file is open */

  ofile = nxffs_findofile(volume, name);
  if (ofile)
    {
      /* We can't remove the inode if it is open */

      fdbg("Inode '%s' is open\n", name);
      ret = -EBUSY;
      goto errout;
    }

  /* Find the NXFFS inode */

  ret = nxffs_findinode(volume, name, &entry);
  if (ret < 0)
    {
      fdbg("Inode '%s' not found\n", name);
      goto errout;
    }

  /* Set the position to the FLASH offset of the file header (nxffs_findinode
   * should have left the block in the cache).
   */

  nxffs_ioseek(volume, entry.hoffset);

  /* Make sure that the block is in the cache */

  ret = nxffs_rdcache(volume, volume->ioblock);
  if (ret < 0)
    {
      fdbg("Failed to read data into cache: %d\n", ret);
      goto errout_with_entry;
    }

  /* Change the file status... it is no longer valid */

  inode = (FAR struct nxffs_inode_s *)&volume->cache[volume->iooffset];
  inode->state = INODE_STATE_DELETED;

  /* Then write the cached block back to FLASH */

  ret = nxffs_wrcache(volume);
  if (ret < 0)
    {
      fdbg("Failed to read data into cache: %d\n", ret);
    }

errout_with_entry:
  nxffs_freeentry(&entry);
errout:
  return ret;
}
static inline ssize_t nxffs_wrappend(FAR struct nxffs_volume_s *volume,
                                     FAR struct nxffs_wrfile_s *wrfile,
                                     FAR const char *buffer, size_t buflen)
{
  ssize_t maxsize;
  size_t nbytestowrite;
  ssize_t nbytesleft;
  off_t offset;
  int ret;

  /* Get the offset to the start of unwritten data */

  offset = volume->iooffset + wrfile->datlen + SIZEOF_NXFFS_DATA_HDR;

  /* Determine that maximum amount of data that can be written to this
   * block.
   */

  maxsize = volume->geo.blocksize - offset;
  DEBUGASSERT(maxsize > 0);

  /* But don't try to write over any unerased bytes */

  maxsize = nxffs_erased(&volume->cache[offset], maxsize);

  /* Write as many bytes as we can into the data buffer */

  nbytestowrite = MIN(maxsize, buflen);
  nbytesleft    = maxsize - nbytestowrite;

  if (nbytestowrite > 0)
    {
      /* Copy the data into the volume write cache */

      memcpy(&volume->cache[offset], buffer, nbytestowrite);

      /* Increment the number of bytes written to the data block */

      wrfile->datlen += nbytestowrite;

      /* Re-calculate the CRC */

      offset = volume->iooffset + SIZEOF_NXFFS_DATA_HDR;
      wrfile->crc = crc32(&volume->cache[offset], wrfile->datlen);

      /* And write the partial write block to FLASH -- unless the data
       * block is full.  In that case, the block will be written below.
       */

      if (nbytesleft > 0)
        {
          ret = nxffs_wrcache(volume);
          if (ret < 0)
            {
              fdbg("ERROR: nxffs_wrcache failed: %d\n", -ret);
              return ret;
            }
        }
    }

  /* Check if the data block is now full */

  if (nbytesleft <= 0)
    {
      /* The data block is full, write the block to FLASH */

      ret = nxffs_wrblkhdr(volume, wrfile);
      if (ret < 0)
        {
          fdbg("ERROR: nxffs_wrblkdhr failed: %d\n", -ret);
          return ret;
        }
    }

  /* Return the number of bytes written to FLASH this time */

  return nbytestowrite;
}