aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sqfs/dir_reader.h10
-rw-r--r--lib/common/src/read_tree.c24
-rw-r--r--lib/sqfs/src/dir_reader.c56
3 files changed, 45 insertions, 45 deletions
diff --git a/include/sqfs/dir_reader.h b/include/sqfs/dir_reader.h
index 0f1f231..1c95e30 100644
--- a/include/sqfs/dir_reader.h
+++ b/include/sqfs/dir_reader.h
@@ -204,6 +204,7 @@ SQFS_API sqfs_dir_reader_t *sqfs_dir_reader_create(const sqfs_super_t *super,
*/
SQFS_API int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd,
const sqfs_inode_generic_t *inode,
+ sqfs_dir_reader_state_t *state,
sqfs_u32 flags);
/**
@@ -217,9 +218,6 @@ SQFS_API int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd,
* because the end of the listing was reached. A negative value indicates an
* error.
*
- * After calling this function, you can use @ref sqfs_dir_reader_get_inode to
- * read the full inode structure that the current entry referes to.
- *
* @param rd A pointer to a directory reader.
* @param out Returns a pointer to a directory entry on success that can be
* freed with a single @ref sqfs_free call.
@@ -228,20 +226,22 @@ SQFS_API int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd,
* number if the end of the current directory listing has been reached.
*/
SQFS_API int sqfs_dir_reader_read(sqfs_dir_reader_t *rd,
+ sqfs_dir_reader_state_t *state,
sqfs_dir_node_t **out);
/**
- * @brief Read the inode that the current directory entry points to.
+ * @brief Resolve and deserialize an inode using an inode reference
*
* @memberof sqfs_dir_reader_t
*
* @param rd A pointer to a directory reader.
+ * @param ref An inode reference.
* @param out Returns a pointer to a generic inode that can be freed with a
* single @ref sqfs_free call.
*
* @return Zero on success, an @ref SQFS_ERROR value on failure.
*/
-SQFS_API int sqfs_dir_reader_get_inode(sqfs_dir_reader_t *rd,
+SQFS_API int sqfs_dir_reader_get_inode(sqfs_dir_reader_t *rd, sqfs_u64 ref,
sqfs_inode_generic_t **inode);
/**
diff --git a/lib/common/src/read_tree.c b/lib/common/src/read_tree.c
index 5d089e5..2879ff4 100644
--- a/lib/common/src/read_tree.c
+++ b/lib/common/src/read_tree.c
@@ -63,6 +63,7 @@ static sqfs_tree_node_t *create_node(sqfs_inode_generic_t *inode,
}
static int fill_dir(sqfs_dir_reader_t *dr, sqfs_tree_node_t *root,
+ sqfs_dir_reader_state_t *state,
unsigned int flags)
{
sqfs_tree_node_t *n, *prev, **tail;
@@ -73,7 +74,7 @@ static int fill_dir(sqfs_dir_reader_t *dr, sqfs_tree_node_t *root,
tail = &root->children;
for (;;) {
- err = sqfs_dir_reader_read(dr, &ent);
+ err = sqfs_dir_reader_read(dr, state, &ent);
if (err > 0)
break;
if (err < 0)
@@ -84,7 +85,7 @@ static int fill_dir(sqfs_dir_reader_t *dr, sqfs_tree_node_t *root,
continue;
}
- err = sqfs_dir_reader_get_inode(dr, &inode);
+ err = sqfs_dir_reader_get_inode(dr, state->ent_ref, &inode);
if (err) {
free(ent);
return err;
@@ -115,13 +116,16 @@ static int fill_dir(sqfs_dir_reader_t *dr, sqfs_tree_node_t *root,
while (n != NULL) {
if (n->inode->base.type == SQFS_INODE_DIR ||
n->inode->base.type == SQFS_INODE_EXT_DIR) {
+ sqfs_dir_reader_state_t nstate;
+
if (!(flags & SQFS_TREE_NO_RECURSE)) {
err = sqfs_dir_reader_open_dir(dr, n->inode,
+ &nstate,
SQFS_DIR_OPEN_NO_DOT_ENTRIES);
if (err)
return err;
- err = fill_dir(dr, n, flags);
+ err = fill_dir(dr, n, &nstate, flags);
if (err)
return err;
}
@@ -192,13 +196,15 @@ int sqfs_dir_reader_get_full_hierarchy(sqfs_dir_reader_t *rd,
inode = NULL;
while (path != NULL && *path != '\0') {
+ sqfs_dir_reader_state_t state;
+
if (*path == '/') {
while (*path == '/')
++path;
continue;
}
- ret = sqfs_dir_reader_open_dir(rd, tail->inode,
+ ret = sqfs_dir_reader_open_dir(rd, tail->inode, &state,
SQFS_DIR_OPEN_NO_DOT_ENTRIES);
if (ret)
goto fail;
@@ -206,7 +212,7 @@ int sqfs_dir_reader_get_full_hierarchy(sqfs_dir_reader_t *rd,
ptr = strchrnul(path, '/');
for (;;) {
- ret = sqfs_dir_reader_read(rd, &ent);
+ ret = sqfs_dir_reader_read(rd, &state, &ent);
if (ret < 0)
goto fail;
if (ret > 0) {
@@ -221,7 +227,7 @@ int sqfs_dir_reader_get_full_hierarchy(sqfs_dir_reader_t *rd,
free(ent);
}
- ret = sqfs_dir_reader_get_inode(rd, &inode);
+ ret = sqfs_dir_reader_get_inode(rd, state.ent_ref, &inode);
if (ret) {
free(ent);
goto fail;
@@ -251,12 +257,14 @@ int sqfs_dir_reader_get_full_hierarchy(sqfs_dir_reader_t *rd,
if (tail->inode->base.type == SQFS_INODE_DIR ||
tail->inode->base.type == SQFS_INODE_EXT_DIR) {
- ret = sqfs_dir_reader_open_dir(rd, tail->inode,
+ sqfs_dir_reader_state_t state;
+
+ ret = sqfs_dir_reader_open_dir(rd, tail->inode, &state,
SQFS_DIR_OPEN_NO_DOT_ENTRIES);
if (ret)
goto fail;
- ret = fill_dir(rd, tail, flags);
+ ret = fill_dir(rd, tail, &state, flags);
if (ret)
goto fail;
}
diff --git a/lib/sqfs/src/dir_reader.c b/lib/sqfs/src/dir_reader.c
index c904f35..2b6d0e8 100644
--- a/lib/sqfs/src/dir_reader.c
+++ b/lib/sqfs/src/dir_reader.c
@@ -36,8 +36,6 @@ struct sqfs_dir_reader_t {
sqfs_u32 flags;
rbtree_t dcache;
-
- sqfs_dir_reader_state_t state;
};
static int dcache_key_compare(const void *ctx, const void *l, const void *r)
@@ -189,6 +187,7 @@ fail_dcache:
int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd,
const sqfs_inode_generic_t *inode,
+ sqfs_dir_reader_state_t *state,
sqfs_u32 flags)
{
sqfs_u32 parent;
@@ -197,7 +196,9 @@ int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd,
if (flags & (~SQFS_DIR_OPEN_ALL_FLAGS))
return SQFS_ERROR_UNSUPPORTED;
- ret = sqfs_readdir_state_init(&rd->state.cursor, &rd->super, inode);
+ memset(state, 0, sizeof(*state));
+
+ ret = sqfs_readdir_state_init(&state->cursor, &rd->super, inode);
if (ret)
return ret;
@@ -209,21 +210,21 @@ int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd,
parent = inode->data.dir.parent_inode;
}
- if (dcache_find(rd, inode->base.inode_number, &rd->state.cur_ref))
+ if (dcache_find(rd, inode->base.inode_number, &state->cur_ref))
return SQFS_ERROR_NO_ENTRY;
- if (rd->state.cur_ref == rd->super.root_inode_ref) {
- rd->state.parent_ref = rd->state.cur_ref;
- } else if (dcache_find(rd, parent, &rd->state.parent_ref)) {
+ if (state->cur_ref == rd->super.root_inode_ref) {
+ state->parent_ref = state->cur_ref;
+ } else if (dcache_find(rd, parent, &state->parent_ref)) {
return SQFS_ERROR_NO_ENTRY;
}
- rd->state.state = DIR_STATE_OPENED;
+ state->state = DIR_STATE_OPENED;
} else {
- rd->state.state = DIR_STATE_ENTRIES;
+ state->state = DIR_STATE_ENTRIES;
}
- rd->state.start_state = rd->state.state;
+ state->start_state = state->state;
return 0;
}
@@ -245,23 +246,24 @@ static int mk_dummy_entry(const char *str, sqfs_dir_node_t **out)
return 0;
}
-int sqfs_dir_reader_read(sqfs_dir_reader_t *rd, sqfs_dir_node_t **out)
+int sqfs_dir_reader_read(sqfs_dir_reader_t *rd, sqfs_dir_reader_state_t *state,
+ sqfs_dir_node_t **out)
{
int err;
- switch (rd->state.state) {
+ switch (state->state) {
case DIR_STATE_OPENED:
err = mk_dummy_entry(".", out);
if (err == 0) {
- rd->state.state = DIR_STATE_DOT;
- rd->state.ent_ref = rd->state.cur_ref;
+ state->state = DIR_STATE_DOT;
+ state->ent_ref = state->cur_ref;
}
return err;
case DIR_STATE_DOT:
err = mk_dummy_entry("..", out);
if (err == 0) {
- rd->state.state = DIR_STATE_ENTRIES;
- rd->state.ent_ref = rd->state.parent_ref;
+ state->state = DIR_STATE_ENTRIES;
+ state->ent_ref = state->parent_ref;
}
return err;
case DIR_STATE_ENTRIES:
@@ -270,35 +272,25 @@ int sqfs_dir_reader_read(sqfs_dir_reader_t *rd, sqfs_dir_node_t **out)
return SQFS_ERROR_SEQUENCE;
}
- return sqfs_meta_reader_readdir(rd->meta_dir, &rd->state.cursor,
- out, NULL, &rd->state.ent_ref);
+ return sqfs_meta_reader_readdir(rd->meta_dir, &state->cursor,
+ out, NULL, &state->ent_ref);
}
-int sqfs_dir_reader_get_inode(sqfs_dir_reader_t *rd,
+int sqfs_dir_reader_get_inode(sqfs_dir_reader_t *rd, sqfs_u64 ref,
sqfs_inode_generic_t **inode)
{
int ret;
ret = sqfs_meta_reader_read_inode(rd->meta_inode, &rd->super,
- rd->state.ent_ref >> 16,
- rd->state.ent_ref & 0x0FFFF, inode);
+ ref >> 16, ref & 0x0FFFF, inode);
if (ret != 0)
return ret;
- return dcache_add(rd, *inode, rd->state.ent_ref);
+ return dcache_add(rd, *inode, ref);
}
int sqfs_dir_reader_get_root_inode(sqfs_dir_reader_t *rd,
sqfs_inode_generic_t **inode)
{
- sqfs_u64 block_start = rd->super.root_inode_ref >> 16;
- sqfs_u16 offset = rd->super.root_inode_ref & 0xFFFF;
- int ret;
-
- ret = sqfs_meta_reader_read_inode(rd->meta_inode, &rd->super,
- block_start, offset, inode);
- if (ret != 0)
- return ret;
-
- return dcache_add(rd, *inode, rd->super.root_inode_ref);
+ return sqfs_dir_reader_get_inode(rd, rd->super.root_inode_ref, inode);
}