fs/cromfs: Fix a error in reading partial compressed blocks. The LZF decompressor does not support that operation. Instead we have to decompress full block into a temporary buffer and copy out the parts that we need. To compensate for the performance hit, a caching mechanism was added so that we do not have to read the same block repeatedly. Unrelated: Also updates some README files.

This commit is contained in:
Gregory Nutt
2018-03-24 11:30:35 -06:00
parent e35228ece9
commit 8b4b61f140
11 changed files with 85 additions and 85 deletions
+1
View File
@@ -8,6 +8,7 @@ config FS_CROMFS
default n
depends on !DISABLE_MOUNTPOINT
select FS_READABLE
select LIBC_LZF
---help---
Enable Compessed Read-Only Filesystem (CROMFS) support
+9 -1
View File
@@ -236,13 +236,21 @@ configuration:
CONFIG_LIBC_LZF=y
NOTE: This should be selected automatically when CONFIG_FS_CROMFS
is enabled.
2. Enable the CROMFS file system:
CONFIG_FS_CROMFS=y
3. Enable the apps/examples/cromfs example if you like:
3. Enable the apps/examples/cromfs example:
CONFIG_EXAMPLES_CROMFS=y
Or the apps/examples/elf example if you like:
CONFIG_EXAMPLES_ELF=y
CONFIG_EXAMPLES_ELF_CROMFS=y
Or implement your own custom CROMFS file system that example as a
guideline.
+48 -14
View File
@@ -71,6 +71,8 @@
struct cromfs_file_s
{
FAR const struct cromfs_node_s *ff_node; /* The open file node */
uint32_t ff_offset; /* Cached offset (zero means none) */
uint32_t ff_ulen; /* Length of uncompressed data in cache */
FAR uint8_t *ff_buffer; /* Decompression buffer */
};
@@ -720,31 +722,49 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer,
src = (FAR const uint8_t *)currhdr + LZF_TYPE0_HDR_SIZE;
memcpy(dest, &src[copyoffs], copysize);
finfo("blkoffs=%lu ulen=%u copysize=%u\n",
(unsigned long)blkoffs, ulen, copysize);
}
else
{
unsigned int decomplen;
/* If the source of the data is at the beginning of the compressed
* data buffer, then we can decompress directly into the user buffer.
* data buffer and if the uncompressed data would not overrun the
* buffer, then we can decompress directly into the user buffer.
*/
if (filep->f_pos <= blkoffs)
if (filep->f_pos <= blkoffs && ulen <= remaining)
{
uint32_t voloffs;
copyoffs = 0;
copysize = ulen;
if (copysize > remaining)
/* Get the address and offset in the CROMFS image to obtain
* the data. Check if we already have this offset in the
* cache.
*/
src = (FAR const uint8_t *)currhdr + LZF_TYPE1_HDR_SIZE;
voloffs = cromfs_addr2offset(fs, src);
if (voloffs != ff->ff_offset)
{
copysize = remaining;
unsigned int decomplen;
decomplen = lzf_decompress(src, clen, dest, fs->cv_bsize);
ff->ff_offset = voloffs;
ff->ff_ulen = decomplen;
}
src = (FAR const uint8_t *)currhdr + LZF_TYPE1_HDR_SIZE;
decomplen = lzf_decompress(src, clen, dest, copysize);
DEBUGASSERT(decomplen == copysize);
finfo("voloffs=%lu blkoffs=%lu ulen=%u ff_offset=%u copysize=%u\n",
(unsigned long)voloffs, (unsigned long)blkoffs, ulen,
ff->ff_offset, copysize);
DEBUGASSERT(ff->ff_ulen >= copysize);
}
else
{
unsigned int outsize;
uint32_t voloffs;
/* No, we will need to decompress into the our intermediate
* decompression buffer.
@@ -759,12 +779,26 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer,
copysize = remaining;
}
outsize = copyoffs + copysize;
DEBUGASSERT(outsize <= fs->cv_bsize);
DEBUGASSERT((copyoffs + copysize) <= fs->cv_bsize);
src = (FAR const uint8_t *)currhdr + LZF_TYPE1_HDR_SIZE;
decomplen = lzf_decompress(src, clen, ff->ff_buffer, outsize);
DEBUGASSERT(decomplen == outsize);
voloffs = cromfs_addr2offset(fs, src);
if (voloffs != ff->ff_offset)
{
unsigned int decomplen;
decomplen = lzf_decompress(src, clen, ff->ff_buffer,
fs->cv_bsize);
ff->ff_offset = voloffs;
ff->ff_ulen = decomplen;
}
finfo("voloffs=%lu blkoffs=%lu ulen=%u clen=%u ff_offset=%u "
"copyoffs=%u copysize=%u\n",
(unsigned long)voloffs, (unsigned long)blkoffs, ulen,
clen, ff->ff_offset, copyoffs, copysize);
DEBUGASSERT(ff->ff_ulen >= (copyoffs + copysize));
/* Then copy to user buffer */