mirror of
https://github.com/apache/nuttx.git
synced 2026-06-01 16:59:28 +08:00
Swap size of cache and pack buffers
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3554 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
+4
-7
@@ -285,7 +285,6 @@ struct nxffs_volume_s
|
|||||||
sem_t wrsem; /* Enforces single writer restriction */
|
sem_t wrsem; /* Enforces single writer restriction */
|
||||||
struct mtd_geometry_s geo; /* Device geometry */
|
struct mtd_geometry_s geo; /* Device geometry */
|
||||||
uint8_t blkper; /* R/W blocks per erase block */
|
uint8_t blkper; /* R/W blocks per erase block */
|
||||||
uint8_t ncached; /* Number of blocks in cache */
|
|
||||||
uint16_t iooffset; /* Next offset in read/write access (in ioblock) */
|
uint16_t iooffset; /* Next offset in read/write access (in ioblock) */
|
||||||
off_t inoffset; /* Offset to the first valid inode header */
|
off_t inoffset; /* Offset to the first valid inode header */
|
||||||
off_t froffset; /* Offset to the first free byte */
|
off_t froffset; /* Offset to the first free byte */
|
||||||
@@ -293,8 +292,8 @@ struct nxffs_volume_s
|
|||||||
off_t ioblock; /* Current block number being accessed */
|
off_t ioblock; /* Current block number being accessed */
|
||||||
off_t cblock; /* Starting block number in cache */
|
off_t cblock; /* Starting block number in cache */
|
||||||
FAR struct nxffs_ofile_s *ofiles; /* A singly-linked list of open files */
|
FAR struct nxffs_ofile_s *ofiles; /* A singly-linked list of open files */
|
||||||
FAR uint8_t *cache; /* Allocated erase block */
|
FAR uint8_t *cache; /* On cached erase block for general I/O */
|
||||||
FAR uint8_t *pack; /* Extra I/O block buffer to support packing */
|
FAR uint8_t *pack; /* A full erase block to support packing */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This structure describes the state of the blocks on the NXFFS volume */
|
/* This structure describes the state of the blocks on the NXFFS volume */
|
||||||
@@ -466,12 +465,11 @@ extern size_t nxffs_erased(FAR const uint8_t *buffer, size_t buflen);
|
|||||||
* Name: nxffs_rdcache
|
* Name: nxffs_rdcache
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Read one or more logical blocks into the volume cache memory.
|
* Read one I/O block into the volume cache memory.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* volume - Describes the current volume
|
* volume - Describes the current volume
|
||||||
* block - The first logical block to read
|
* block - The first logical block to read
|
||||||
* nblocks - The number of logical blocks to be read.
|
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Negated errnos are returned only in the case of MTD reported failures.
|
* Negated errnos are returned only in the case of MTD reported failures.
|
||||||
@@ -481,8 +479,7 @@ extern size_t nxffs_erased(FAR const uint8_t *buffer, size_t buflen);
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
extern int nxffs_rdcache(FAR struct nxffs_volume_s *volume, off_t block,
|
extern int nxffs_rdcache(FAR struct nxffs_volume_s *volume, off_t block);
|
||||||
uint8_t nblocks);
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: nxffs_wrcache
|
* Name: nxffs_wrcache
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ int nxffs_verifyblock(FAR struct nxffs_volume_s *volume, off_t block)
|
|||||||
|
|
||||||
/* Make sure the the block is in the cache */
|
/* Make sure the the block is in the cache */
|
||||||
|
|
||||||
ret = nxffs_rdcache(volume, block, 1);
|
ret = nxffs_rdcache(volume, block);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
fdbg("Failed to read data into cache: %d\n", ret);
|
fdbg("Failed to read data into cache: %d\n", ret);
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#include <nuttx/mtd.h>
|
#include <nuttx/mtd.h>
|
||||||
@@ -91,7 +92,7 @@ int nxffs_blockstats(FAR struct nxffs_volume_s *volume,
|
|||||||
FAR struct nxffs_blkstats_s *stats)
|
FAR struct nxffs_blkstats_s *stats)
|
||||||
{
|
{
|
||||||
FAR uint8_t *bptr; /* Pointer to next block data */
|
FAR uint8_t *bptr; /* Pointer to next block data */
|
||||||
off_t eblock; /* Erase block number */
|
off_t ioblock; /* I/O block number */
|
||||||
int lblock; /* Logical block index */
|
int lblock; /* Logical block index */
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -99,22 +100,20 @@ int nxffs_blockstats(FAR struct nxffs_volume_s *volume,
|
|||||||
|
|
||||||
memset(stats, 0, sizeof(struct nxffs_blkstats_s));
|
memset(stats, 0, sizeof(struct nxffs_blkstats_s));
|
||||||
|
|
||||||
for (eblock = 0; eblock < volume->geo.neraseblocks; eblock++)
|
for (ioblock = 0; ioblock < volume->nblocks; ioblock += volume->blkper)
|
||||||
{
|
{
|
||||||
/* Read the full erase block */
|
/* Read the full erase block */
|
||||||
|
|
||||||
volume->ioblock = eblock * volume->blkper;
|
ret = MTD_BREAD(volume->mtd, ioblock, volume->blkper, volume->pack);
|
||||||
volume->iooffset = 0;
|
if (ret < volume->blkper)
|
||||||
ret = nxffs_rdcache(volume, volume->ioblock, volume->blkper);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
{
|
||||||
fdbg("Failed to read erase block %d: %d\n", eblock, -ret);
|
fdbg("Failed to read erase block %d: %d\n", ioblock / volume->blkper, -ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process each logical block */
|
/* Process each logical block */
|
||||||
|
|
||||||
for (bptr = volume->cache, lblock = 0;
|
for (bptr = volume->pack, lblock = 0;
|
||||||
lblock < volume->blkper;
|
lblock < volume->blkper;
|
||||||
bptr += volume->geo.blocksize, lblock++)
|
bptr += volume->geo.blocksize, lblock++)
|
||||||
{
|
{
|
||||||
|
|||||||
+10
-29
@@ -73,12 +73,11 @@
|
|||||||
* Name: nxffs_rdcache
|
* Name: nxffs_rdcache
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Read one or more logical blocks into the volume block cache memory.
|
* Read one I/O block into the volume block cache memory.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* volume - Describes the current volume
|
* volume - Describes the current volume
|
||||||
* block - The first logical block to read
|
* block - The first logical block to read
|
||||||
* nblocks - The number of logical blocks to be read.
|
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Negated errnos are returned only in the case of MTD reported failures.
|
* Negated errnos are returned only in the case of MTD reported failures.
|
||||||
@@ -86,31 +85,26 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int nxffs_rdcache(FAR struct nxffs_volume_s *volume, off_t block,
|
int nxffs_rdcache(FAR struct nxffs_volume_s *volume, off_t block)
|
||||||
uint8_t nblocks)
|
|
||||||
{
|
{
|
||||||
size_t nxfrd;
|
size_t nxfrd;
|
||||||
|
|
||||||
DEBUGASSERT(nblocks <= volume->blkper);
|
|
||||||
|
|
||||||
/* Check if the requested data is already in the cache */
|
/* Check if the requested data is already in the cache */
|
||||||
|
|
||||||
if (block != volume->cblock || nblocks > volume->ncached)
|
if (block != volume->cblock)
|
||||||
{
|
{
|
||||||
/* Read the specified blocks into cache */
|
/* Read the specified blocks into cache */
|
||||||
|
|
||||||
nxfrd = MTD_BREAD(volume->mtd, block, nblocks, volume->cache);
|
nxfrd = MTD_BREAD(volume->mtd, block, 1, volume->cache);
|
||||||
if (nxfrd != nblocks)
|
if (nxfrd != 1)
|
||||||
{
|
{
|
||||||
fvdbg("Read block %d-%d failed: %d\n",
|
fvdbg("Read block %d failed: %d\n", block, nxfrd);
|
||||||
block, block + nblocks - 1, nxfrd);
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember what is in the cache */
|
/* Remember what is in the cache */
|
||||||
|
|
||||||
volume->cblock = block;
|
volume->cblock = block;
|
||||||
volume->ncached = nblocks;
|
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -133,18 +127,12 @@ int nxffs_wrcache(FAR struct nxffs_volume_s *volume)
|
|||||||
{
|
{
|
||||||
size_t nxfrd;
|
size_t nxfrd;
|
||||||
|
|
||||||
/* Check if there are blocks in the cache */
|
/* Write the current block from the cache */
|
||||||
|
|
||||||
if (volume->ncached > 0)
|
nxfrd = MTD_BWRITE(volume->mtd, volume->cblock, 1, volume->cache);
|
||||||
|
if (nxfrd != 1)
|
||||||
{
|
{
|
||||||
/* Read the specified blocks into cache */
|
fdbg("Write block %d failed: %d\n", volume->cblock, nxfrd);
|
||||||
|
|
||||||
nxfrd = MTD_BWRITE(volume->mtd, volume->cblock, volume->ncached,
|
|
||||||
volume->cache);
|
|
||||||
if (nxfrd != volume->ncached)
|
|
||||||
{
|
|
||||||
fdbg("Write block %d-%d failed: %d\n",
|
|
||||||
volume->cblock, volume->cblock + volume->ncached - 1, nxfrd);
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,13 +141,6 @@ int nxffs_wrcache(FAR struct nxffs_volume_s *volume)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Probably won't get here because there is almost always something in
|
|
||||||
* the cache
|
|
||||||
*/
|
|
||||||
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: nxffs_ioseek
|
* Name: nxffs_ioseek
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ int nxffs_initialize(FAR struct mtd_dev_s *mtd)
|
|||||||
/* Initialize the NXFFS volume structure */
|
/* Initialize the NXFFS volume structure */
|
||||||
|
|
||||||
volume->mtd = mtd;
|
volume->mtd = mtd;
|
||||||
|
volume->cblock = (off_t)-1;
|
||||||
sem_init(&volume->exclsem, 0, 1);
|
sem_init(&volume->exclsem, 0, 1);
|
||||||
sem_init(&volume->wrsem, 0, 1);
|
sem_init(&volume->wrsem, 0, 1);
|
||||||
|
|
||||||
@@ -197,9 +198,9 @@ int nxffs_initialize(FAR struct mtd_dev_s *mtd)
|
|||||||
goto errout_with_volume;
|
goto errout_with_volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate one, in-memory erase block buffer */
|
/* Allocate one I/O block buffer to general files system access */
|
||||||
|
|
||||||
volume->cache = (FAR uint8_t *)kmalloc(volume->geo.erasesize);
|
volume->cache = (FAR uint8_t *)kmalloc(volume->geo.blocksize);
|
||||||
if (!volume->cache)
|
if (!volume->cache)
|
||||||
{
|
{
|
||||||
fdbg("Failed to allocate an erase block buffer\n");
|
fdbg("Failed to allocate an erase block buffer\n");
|
||||||
@@ -207,12 +208,12 @@ int nxffs_initialize(FAR struct mtd_dev_s *mtd)
|
|||||||
goto errout_with_volume;
|
goto errout_with_volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pre-allocate one additional I/O block buffer to support filesystem
|
/* Pre-allocate one, full, in-memory erase block. This is needed for filesystem
|
||||||
* packing. This buffer is not needed often, but is best to have pre-
|
* packing (but is useful in other places as well). This buffer is not needed
|
||||||
* allocated and in-place.
|
* often, but is best to have pre-allocated and in-place.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
volume->pack = (FAR uint8_t *)kmalloc(volume->geo.blocksize);
|
volume->pack = (FAR uint8_t *)kmalloc(volume->geo.erasesize);
|
||||||
if (!volume->pack)
|
if (!volume->pack)
|
||||||
{
|
{
|
||||||
fdbg("Failed to allocate an I/O block buffer\n");
|
fdbg("Failed to allocate an I/O block buffer\n");
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset,
|
|||||||
* same block as the inode header.
|
* same block as the inode header.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = nxffs_rdcache(volume, volume->ioblock, 1);
|
ret = nxffs_rdcache(volume, volume->ioblock);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
fdbg("nxffsx_rdcache failed: %d\n", -ret);
|
fdbg("nxffsx_rdcache failed: %d\n", -ret);
|
||||||
|
|||||||
+10
-6
@@ -841,10 +841,11 @@ static int nxffs_wrclose(FAR struct nxffs_volume_s *volume,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
nxffs_ioseek(volume, wrfile->ofile.entry.hoffset);
|
nxffs_ioseek(volume, wrfile->ofile.entry.hoffset);
|
||||||
ret = nxffs_rdcache(volume, volume->ioblock, 1);
|
ret = nxffs_rdcache(volume, volume->ioblock);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
fdbg("Failed to read inode header block %d: %d\n", volume->ioblock, -ret);
|
fdbg("Failed to read inode header block %d: %d\n",
|
||||||
|
volume->ioblock, -ret);
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -889,7 +890,8 @@ static int nxffs_wrclose(FAR struct nxffs_volume_s *volume,
|
|||||||
ret = nxffs_wrcache(volume);
|
ret = nxffs_wrcache(volume);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
fdbg("Failed to write inode header block %d: %d\n", volume->ioblock, -ret);
|
fdbg("Failed to write inode header block %d: %d\n",
|
||||||
|
volume->ioblock, -ret);
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -897,10 +899,11 @@ static int nxffs_wrclose(FAR struct nxffs_volume_s *volume,
|
|||||||
|
|
||||||
volume->ioblock = namblock;
|
volume->ioblock = namblock;
|
||||||
volume->iooffset = namoffset;
|
volume->iooffset = namoffset;
|
||||||
ret = nxffs_rdcache(volume, volume->ioblock, 1);
|
ret = nxffs_rdcache(volume, volume->ioblock);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
fdbg("Failed to read inode name block %d: %d\n", volume->ioblock, -ret);
|
fdbg("Failed to read inode name block %d: %d\n",
|
||||||
|
volume->ioblock, -ret);
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -911,7 +914,8 @@ static int nxffs_wrclose(FAR struct nxffs_volume_s *volume,
|
|||||||
ret = nxffs_wrcache(volume);
|
ret = nxffs_wrcache(volume);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
fdbg("Failed to write inode header block %d: %d\n", volume->ioblock, -ret);
|
fdbg("Failed to write inode header block %d: %d\n",
|
||||||
|
volume->ioblock, -ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The volume is now available for other writers */
|
/* The volume is now available for other writers */
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ static int nxffs_format(FAR struct nxffs_volume_s *volume)
|
|||||||
|
|
||||||
/* Create an image of one properly formatted erase sector */
|
/* Create an image of one properly formatted erase sector */
|
||||||
|
|
||||||
memset(volume->cache, CONFIG_NXFFS_ERASEDSTATE, volume->geo.erasesize);
|
memset(volume->pack, CONFIG_NXFFS_ERASEDSTATE, volume->geo.erasesize);
|
||||||
for (blkptr = volume->cache, i = 0;
|
for (blkptr = volume->pack, i = 0;
|
||||||
i < volume->blkper;
|
i < volume->blkper;
|
||||||
blkptr += volume->geo.blocksize, i++)
|
blkptr += volume->geo.blocksize, i++)
|
||||||
{
|
{
|
||||||
@@ -118,7 +118,7 @@ static int nxffs_format(FAR struct nxffs_volume_s *volume)
|
|||||||
/* Write the formatted image to the erase block */
|
/* Write the formatted image to the erase block */
|
||||||
|
|
||||||
lblock = eblock * volume->blkper;
|
lblock = eblock * volume->blkper;
|
||||||
nxfrd = MTD_BWRITE(volume->mtd, lblock, volume->blkper, volume->cache);
|
nxfrd = MTD_BWRITE(volume->mtd, lblock, volume->blkper, volume->pack);
|
||||||
if (nxfrd != volume->blkper)
|
if (nxfrd != volume->blkper)
|
||||||
{
|
{
|
||||||
fdbg("Write erase block %d failed: %d\n", lblock, nxfrd);
|
fdbg("Write erase block %d failed: %d\n", lblock, nxfrd);
|
||||||
@@ -162,7 +162,7 @@ static int nxffs_badblocks(FAR struct nxffs_volume_s *volume)
|
|||||||
/* Read the entire erase block */
|
/* Read the entire erase block */
|
||||||
|
|
||||||
lblock = eblock * volume->blkper;
|
lblock = eblock * volume->blkper;
|
||||||
nxfrd = MTD_BREAD(volume->mtd, lblock, volume->blkper, volume->cache);
|
nxfrd = MTD_BREAD(volume->mtd, lblock, volume->blkper, volume->pack);
|
||||||
if (nxfrd != volume->blkper)
|
if (nxfrd != volume->blkper)
|
||||||
{
|
{
|
||||||
fdbg("Read erase block %d failed: %d\n", lblock, nxfrd);
|
fdbg("Read erase block %d failed: %d\n", lblock, nxfrd);
|
||||||
@@ -172,7 +172,7 @@ static int nxffs_badblocks(FAR struct nxffs_volume_s *volume)
|
|||||||
/* Process each logical block */
|
/* Process each logical block */
|
||||||
|
|
||||||
modified = false;
|
modified = false;
|
||||||
for (blkptr = volume->cache, i = 0;
|
for (blkptr = volume->pack, i = 0;
|
||||||
i < volume->blkper;
|
i < volume->blkper;
|
||||||
blkptr += volume->geo.blocksize, i++)
|
blkptr += volume->geo.blocksize, i++)
|
||||||
{
|
{
|
||||||
@@ -211,7 +211,7 @@ static int nxffs_badblocks(FAR struct nxffs_volume_s *volume)
|
|||||||
|
|
||||||
/* If the erase block was modified, then re-write it */
|
/* If the erase block was modified, then re-write it */
|
||||||
|
|
||||||
nxfrd = MTD_BWRITE(volume->mtd, lblock, volume->blkper, volume->cache);
|
nxfrd = MTD_BWRITE(volume->mtd, lblock, volume->blkper, volume->pack);
|
||||||
if (nxfrd != volume->blkper)
|
if (nxfrd != volume->blkper)
|
||||||
{
|
{
|
||||||
fdbg("Write erase block %d failed: %d\n", lblock, nxfrd);
|
fdbg("Write erase block %d failed: %d\n", lblock, nxfrd);
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ int nxffs_rminode(FAR struct nxffs_volume_s *volume, FAR const char *name)
|
|||||||
|
|
||||||
/* Make sure the the block is in the cache */
|
/* Make sure the the block is in the cache */
|
||||||
|
|
||||||
ret = nxffs_rdcache(volume, volume->ioblock, 1);
|
ret = nxffs_rdcache(volume, volume->ioblock);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
fdbg("Failed to read data into cache: %d\n", ret);
|
fdbg("Failed to read data into cache: %d\n", ret);
|
||||||
|
|||||||
@@ -703,10 +703,10 @@ int nxffs_wrverify(FAR struct nxffs_volume_s *volume, size_t size)
|
|||||||
{
|
{
|
||||||
/* Make sure that the block is in memory */
|
/* Make sure that the block is in memory */
|
||||||
|
|
||||||
ret = nxffs_rdcache(volume, volume->ioblock, 1);
|
ret = nxffs_rdcache(volume, volume->ioblock);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
fdbg("nxffsx_rdcache failed: %d\n", -ret);
|
fdbg("Failed to read block %d: %d\n", volume->ioblock, -ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user