mirror of
https://github.com/apache/nuttx.git
synced 2026-06-05 15:58:59 +08:00
fs/cromfs: Fix read logic. tools/genromfs.c: Last node in directory needs to have zero for peer offset. Still some issues with empty directories.
This commit is contained in:
+20
-8
@@ -600,10 +600,20 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
|
|
||||||
if (filep->f_pos > ff->ff_node->cn_size)
|
if (filep->f_pos > ff->ff_node->cn_size)
|
||||||
{
|
{
|
||||||
/* Return the end-of-file indication */
|
/* Start read position is past the end of file. Return the end-of-
|
||||||
|
* file indication.
|
||||||
|
*/
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if ((filep->f_pos + buflen) > ff->ff_node->cn_size)
|
||||||
|
{
|
||||||
|
/* The final read position is past the end of file. Truncate the
|
||||||
|
* read length.
|
||||||
|
*/
|
||||||
|
|
||||||
|
buflen = ff->ff_node->cn_size - filep->f_pos;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find the compressed block containing the current offset, f_pos */
|
/* Find the compressed block containing the current offset, f_pos */
|
||||||
|
|
||||||
@@ -633,7 +643,7 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
/* Go to the next block */
|
/* Go to the next block */
|
||||||
|
|
||||||
currhdr = nexthdr;
|
currhdr = nexthdr;
|
||||||
blkoffs += blksize;
|
blkoffs += ulen;
|
||||||
|
|
||||||
if (currhdr->lzf_type == LZF_TYPE0_HDR)
|
if (currhdr->lzf_type == LZF_TYPE0_HDR)
|
||||||
{
|
{
|
||||||
@@ -641,7 +651,7 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
(FAR struct lzf_type0_header_s *)currhdr;
|
(FAR struct lzf_type0_header_s *)currhdr;
|
||||||
|
|
||||||
ulen = (uint16_t)hdr0->lzf_len[0] << 8 |
|
ulen = (uint16_t)hdr0->lzf_len[0] << 8 |
|
||||||
(uint16_t)hdr0->lzf_len[0];
|
(uint16_t)hdr0->lzf_len[1];
|
||||||
blksize = (size_t)ulen + LZF_TYPE0_HDR_SIZE;
|
blksize = (size_t)ulen + LZF_TYPE0_HDR_SIZE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -650,15 +660,15 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
(FAR struct lzf_type1_header_s *)currhdr;
|
(FAR struct lzf_type1_header_s *)currhdr;
|
||||||
|
|
||||||
ulen = (uint16_t)hdr1->lzf_ulen[0] << 8 |
|
ulen = (uint16_t)hdr1->lzf_ulen[0] << 8 |
|
||||||
(uint16_t)hdr1->lzf_ulen[0];
|
(uint16_t)hdr1->lzf_ulen[1];
|
||||||
clen = (uint16_t)hdr1->lzf_clen[0] << 8 |
|
clen = (uint16_t)hdr1->lzf_clen[0] << 8 |
|
||||||
(uint16_t)hdr1->lzf_clen[0];
|
(uint16_t)hdr1->lzf_clen[1];
|
||||||
blksize = (size_t)clen + LZF_TYPE1_HDR_SIZE;
|
blksize = (size_t)clen + LZF_TYPE1_HDR_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nexthdr = (FAR struct lzf_header_s *)((FAR uint8_t *)currhdr + blksize);
|
nexthdr = (FAR struct lzf_header_s *)((FAR uint8_t *)currhdr + blksize);
|
||||||
}
|
}
|
||||||
while (blkoffs <= fpos && (blkoffs + ulen) > fpos);
|
while (blkoffs < fpos && (blkoffs + ulen) > fpos);
|
||||||
|
|
||||||
/* Check if we need to decompress the next block into the user buffer */
|
/* Check if we need to decompress the next block into the user buffer */
|
||||||
|
|
||||||
@@ -697,7 +707,7 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
|
|
||||||
src = (FAR const uint8_t *)currhdr + LZF_TYPE1_HDR_SIZE;
|
src = (FAR const uint8_t *)currhdr + LZF_TYPE1_HDR_SIZE;
|
||||||
decomplen = lzf_decompress(src, clen, dest, copysize);
|
decomplen = lzf_decompress(src, clen, dest, copysize);
|
||||||
DEBUGASSERT(decomplen = copysize);
|
DEBUGASSERT(decomplen == copysize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -728,13 +738,13 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
memcpy(dest, &ff->ff_buffer[copyoffs], copysize);
|
memcpy(dest, &ff->ff_buffer[copyoffs], copysize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Adjust pointers counts and offset */
|
/* Adjust pointers counts and offset */
|
||||||
|
|
||||||
dest += copysize;
|
dest += copysize;
|
||||||
remaining -= copysize;
|
remaining -= copysize;
|
||||||
fpos += copysize;
|
fpos += copysize;
|
||||||
|
}
|
||||||
|
|
||||||
/* Update the file pointer */
|
/* Update the file pointer */
|
||||||
|
|
||||||
@@ -1021,7 +1031,9 @@ static int cromfs_bind(FAR struct inode *blkdriver, const void *data,
|
|||||||
void **handle)
|
void **handle)
|
||||||
{
|
{
|
||||||
finfo("blkdriver: %p data: %p handle: %p\n", blkdriver, data, handle);
|
finfo("blkdriver: %p data: %p handle: %p\n", blkdriver, data, handle);
|
||||||
|
|
||||||
DEBUGASSERT(blkdriver == NULL && handle != NULL);
|
DEBUGASSERT(blkdriver == NULL && handle != NULL);
|
||||||
|
DEBUGASSERT(g_cromfs_image.cv_magic == CROMFS_MAGIC);
|
||||||
|
|
||||||
/* Return the new file system handle */
|
/* Return the new file system handle */
|
||||||
|
|
||||||
|
|||||||
+30
-16
@@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#define _GNU_SOURCE 1
|
#define _GNU_SOURCE 1
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -238,9 +239,12 @@ static size_t lzf_compress(const uint8_t *inbuffer, unsigned int inlen,
|
|||||||
union lzf_result_u *result);
|
union lzf_result_u *result);
|
||||||
static mode_t get_mode(mode_t mode);
|
static mode_t get_mode(mode_t mode);
|
||||||
static void gen_dirlink(const char *name, size_t tgtoffs);
|
static void gen_dirlink(const char *name, size_t tgtoffs);
|
||||||
static void gen_directory(const char *path, const char *name, mode_t mode);
|
static void gen_directory(const char *path, const char *name, mode_t mode,
|
||||||
static void gen_file(const char *path, const char *name, mode_t mode);
|
bool lastentry);
|
||||||
static void process_direntry(const char *dirpath, struct dirent *direntry);
|
static void gen_file(const char *path, const char *name, mode_t mode,
|
||||||
|
bool lastentry);
|
||||||
|
static void process_direntry(const char *dirpath, struct dirent *direntry,
|
||||||
|
bool lastentry);
|
||||||
static void traverse_directory(const char *dirpath);
|
static void traverse_directory(const char *dirpath);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -866,7 +870,8 @@ static void gen_dirlink(const char *name, size_t tgtoffs)
|
|||||||
g_nnodes++;
|
g_nnodes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_directory(const char *path, const char *name, mode_t mode)
|
static void gen_directory(const char *path, const char *name, mode_t mode,
|
||||||
|
bool lastentry)
|
||||||
{
|
{
|
||||||
struct cromfs_node_s node;
|
struct cromfs_node_s node;
|
||||||
size_t save_offset = g_offset;
|
size_t save_offset = g_offset;
|
||||||
@@ -923,7 +928,7 @@ static void gen_directory(const char *path, const char *name, mode_t mode)
|
|||||||
node.cn_size = 0;
|
node.cn_size = 0;
|
||||||
|
|
||||||
save_offset += namlen;
|
save_offset += namlen;
|
||||||
node.cn_peer = g_offset;
|
node.cn_peer = lastentry ? 0 : g_offset;
|
||||||
node.u.cn_child = save_offset;
|
node.u.cn_child = save_offset;
|
||||||
|
|
||||||
fprintf(g_tmpstream, "\n /* Offset %6lu: Directory %s */\n\n",
|
fprintf(g_tmpstream, "\n /* Offset %6lu: Directory %s */\n\n",
|
||||||
@@ -939,7 +944,8 @@ static void gen_directory(const char *path, const char *name, mode_t mode)
|
|||||||
append_tmpfile(g_tmpstream, subtree_stream);
|
append_tmpfile(g_tmpstream, subtree_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_file(const char *path, const char *name, mode_t mode)
|
static void gen_file(const char *path, const char *name, mode_t mode,
|
||||||
|
bool lastentry)
|
||||||
{
|
{
|
||||||
struct cromfs_node_s node;
|
struct cromfs_node_s node;
|
||||||
union lzf_result_u result;
|
union lzf_result_u result;
|
||||||
@@ -1043,7 +1049,7 @@ static void gen_file(const char *path, const char *name, mode_t mode)
|
|||||||
node.u.cn_blocks = nodeoffs;
|
node.u.cn_blocks = nodeoffs;
|
||||||
|
|
||||||
nodeoffs += blktotal;
|
nodeoffs += blktotal;
|
||||||
node.cn_peer = nodeoffs;
|
node.cn_peer = lastentry ? 0 : nodeoffs;
|
||||||
|
|
||||||
dump_hexbuffer(g_tmpstream, &node, sizeof(struct cromfs_node_s));
|
dump_hexbuffer(g_tmpstream, &node, sizeof(struct cromfs_node_s));
|
||||||
dump_hexbuffer(g_tmpstream, name, namlen);
|
dump_hexbuffer(g_tmpstream, name, namlen);
|
||||||
@@ -1055,7 +1061,8 @@ static void gen_file(const char *path, const char *name, mode_t mode)
|
|||||||
append_tmpfile(g_tmpstream, outstream);
|
append_tmpfile(g_tmpstream, outstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_direntry(const char *dirpath, struct dirent *direntry)
|
static void process_direntry(const char *dirpath, struct dirent *direntry,
|
||||||
|
bool lastentry)
|
||||||
{
|
{
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
char *path;
|
char *path;
|
||||||
@@ -1084,11 +1091,11 @@ static void process_direntry(const char *dirpath, struct dirent *direntry)
|
|||||||
|
|
||||||
else if (S_ISDIR(buf.st_mode))
|
else if (S_ISDIR(buf.st_mode))
|
||||||
{
|
{
|
||||||
gen_directory(path, direntry->d_name, buf.st_mode);
|
gen_directory(path, direntry->d_name, buf.st_mode, lastentry);
|
||||||
}
|
}
|
||||||
else if (S_ISREG(buf.st_mode))
|
else if (S_ISREG(buf.st_mode))
|
||||||
{
|
{
|
||||||
gen_file(path, direntry->d_name, buf.st_mode);
|
gen_file(path, direntry->d_name, buf.st_mode, lastentry);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1102,6 +1109,7 @@ static void traverse_directory(const char *dirpath)
|
|||||||
{
|
{
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
struct dirent *direntry;
|
struct dirent *direntry;
|
||||||
|
struct dirent *nextentry;
|
||||||
|
|
||||||
/* Open the directory */
|
/* Open the directory */
|
||||||
|
|
||||||
@@ -1115,11 +1123,15 @@ static void traverse_directory(const char *dirpath)
|
|||||||
|
|
||||||
/* Visit each entry in the directory */
|
/* Visit each entry in the directory */
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
direntry = readdir(dirp);
|
direntry = readdir(dirp);
|
||||||
if (direntry != NULL)
|
while (direntry != NULL)
|
||||||
{
|
{
|
||||||
|
/* Get the next entry so that we can anticipate the end of the
|
||||||
|
* directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
nextentry = readdir(dirp);
|
||||||
|
|
||||||
/* Skip the '.' and '..' hard links */
|
/* Skip the '.' and '..' hard links */
|
||||||
|
|
||||||
if (strcmp(direntry->d_name, ".") != 0 &&
|
if (strcmp(direntry->d_name, ".") != 0 &&
|
||||||
@@ -1127,12 +1139,14 @@ static void traverse_directory(const char *dirpath)
|
|||||||
{
|
{
|
||||||
/* Process the directory entry */
|
/* Process the directory entry */
|
||||||
|
|
||||||
process_direntry(dirpath, direntry);
|
process_direntry(dirpath, direntry, nextentry == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Skip to the next entry */
|
||||||
|
|
||||||
|
direntry = nextentry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (direntry != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
|
|||||||
Reference in New Issue
Block a user