aboutsummaryrefslogtreecommitdiff
path: root/lib/sqfs/dir_reader
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqfs/dir_reader')
-rw-r--r--lib/sqfs/dir_reader/dcache.c73
-rw-r--r--lib/sqfs/dir_reader/dir_reader.c99
-rw-r--r--lib/sqfs/dir_reader/internal.h14
3 files changed, 65 insertions, 121 deletions
diff --git a/lib/sqfs/dir_reader/dcache.c b/lib/sqfs/dir_reader/dcache.c
deleted file mode 100644
index 47fbf73..0000000
--- a/lib/sqfs/dir_reader/dcache.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* SPDX-License-Identifier: LGPL-3.0-or-later */
-/*
- * dcache.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#define SQFS_BUILDING_DLL
-#include "internal.h"
-
-static int dcache_key_compare(const void *ctx, const void *l, const void *r)
-{
- sqfs_u32 lhs = *((const sqfs_u32 *)l), rhs = *((const sqfs_u32 *)r);
- (void)ctx;
-
- return lhs < rhs ? -1 : (lhs > rhs ? 1 : 0);
-}
-
-int sqfs_dir_reader_dcache_init(sqfs_dir_reader_t *rd, sqfs_u32 flags)
-{
- if (!(flags & SQFS_DIR_READER_DOT_ENTRIES))
- return 0;
-
- return rbtree_init(&rd->dcache, sizeof(sqfs_u32), sizeof(sqfs_u64),
- dcache_key_compare);
-}
-
-int sqfs_dir_reader_dcache_init_copy(sqfs_dir_reader_t *copy,
- const sqfs_dir_reader_t *rd)
-{
- if (!(rd->flags & SQFS_DIR_READER_DOT_ENTRIES))
- return 0;
-
- return rbtree_copy(&rd->dcache, &copy->dcache);
-}
-
-void sqfs_dir_reader_dcache_cleanup(sqfs_dir_reader_t *rd)
-{
- if (!(rd->flags & SQFS_DIR_READER_DOT_ENTRIES))
- return;
-
- rbtree_cleanup(&rd->dcache);
-}
-
-int sqfs_dir_reader_dcache_add(sqfs_dir_reader_t *rd,
- sqfs_u32 inode, sqfs_u64 ref)
-{
- rbtree_node_t *node;
-
- if (!(rd->flags & SQFS_DIR_READER_DOT_ENTRIES))
- return 0;
-
- node = rbtree_lookup(&rd->dcache, &inode);
- if (node != NULL)
- return 0;
-
- return rbtree_insert(&rd->dcache, &inode, &ref);
-}
-
-int sqfs_dir_reader_dcache_find(sqfs_dir_reader_t *rd,
- sqfs_u32 inode, sqfs_u64 *ref)
-{
- rbtree_node_t *node;
-
- if (!(rd->flags & SQFS_DIR_READER_DOT_ENTRIES))
- return SQFS_ERROR_NO_ENTRY;
-
- node = rbtree_lookup(&rd->dcache, &inode);
- if (node == NULL)
- return SQFS_ERROR_NO_ENTRY;
-
- *ref = *((sqfs_u64 *)rbtree_node_value(node));
- return 0;
-}
diff --git a/lib/sqfs/dir_reader/dir_reader.c b/lib/sqfs/dir_reader/dir_reader.c
index 5ed0eff..d09e901 100644
--- a/lib/sqfs/dir_reader/dir_reader.c
+++ b/lib/sqfs/dir_reader/dir_reader.c
@@ -7,11 +7,55 @@
#define SQFS_BUILDING_DLL
#include "internal.h"
+static int dcache_key_compare(const void *ctx, const void *l, const void *r)
+{
+ sqfs_u32 lhs = *((const sqfs_u32 *)l), rhs = *((const sqfs_u32 *)r);
+ (void)ctx;
+
+ return lhs < rhs ? -1 : (lhs > rhs ? 1 : 0);
+}
+
+static int dcache_add(sqfs_dir_reader_t *rd,
+ const sqfs_inode_generic_t *inode, sqfs_u64 ref)
+{
+ sqfs_u32 inum = inode->base.inode_number;
+
+ if (!(rd->flags & SQFS_DIR_READER_DOT_ENTRIES))
+ return 0;
+
+ if (inode->base.type != SQFS_INODE_DIR &&
+ inode->base.type != SQFS_INODE_EXT_DIR) {
+ return 0;
+ }
+
+ if (rbtree_lookup(&rd->dcache, &inum) != NULL)
+ return 0;
+
+ return rbtree_insert(&rd->dcache, &inum, &ref);
+}
+
+static int dcache_find(sqfs_dir_reader_t *rd, sqfs_u32 inode, sqfs_u64 *ref)
+{
+ rbtree_node_t *node;
+
+ if (!(rd->flags & SQFS_DIR_READER_DOT_ENTRIES))
+ return SQFS_ERROR_NO_ENTRY;
+
+ node = rbtree_lookup(&rd->dcache, &inode);
+ if (node == NULL)
+ return SQFS_ERROR_NO_ENTRY;
+
+ *ref = *((sqfs_u64 *)rbtree_node_value(node));
+ return 0;
+}
+
static void dir_reader_destroy(sqfs_object_t *obj)
{
sqfs_dir_reader_t *rd = (sqfs_dir_reader_t *)obj;
- sqfs_dir_reader_dcache_cleanup(rd);
+ if (rd->flags & SQFS_DIR_READER_DOT_ENTRIES)
+ rbtree_cleanup(&rd->dcache);
+
sqfs_destroy(rd->meta_inode);
sqfs_destroy(rd->meta_dir);
free(rd);
@@ -27,8 +71,10 @@ static sqfs_object_t *dir_reader_copy(const sqfs_object_t *obj)
memcpy(copy, rd, sizeof(*copy));
- if (sqfs_dir_reader_dcache_init_copy(copy, rd))
- goto fail_cache;
+ if (rd->flags & SQFS_DIR_READER_DOT_ENTRIES) {
+ if (rbtree_copy(&rd->dcache, &copy->dcache))
+ goto fail_cache;
+ }
copy->meta_inode = sqfs_copy(rd->meta_inode);
if (copy->meta_inode == NULL)
@@ -42,7 +88,8 @@ static sqfs_object_t *dir_reader_copy(const sqfs_object_t *obj)
fail_mdir:
sqfs_destroy(copy->meta_inode);
fail_mino:
- sqfs_dir_reader_dcache_cleanup(copy);
+ if (copy->flags & SQFS_DIR_READER_DOT_ENTRIES)
+ rbtree_cleanup(&copy->dcache);
fail_cache:
free(copy);
return NULL;
@@ -55,6 +102,7 @@ sqfs_dir_reader_t *sqfs_dir_reader_create(const sqfs_super_t *super,
{
sqfs_dir_reader_t *rd;
sqfs_u64 start, limit;
+ int ret;
if (flags & ~SQFS_DIR_READER_ALL_FLAGS)
return NULL;
@@ -63,8 +111,13 @@ sqfs_dir_reader_t *sqfs_dir_reader_create(const sqfs_super_t *super,
if (rd == NULL)
return NULL;
- if (sqfs_dir_reader_dcache_init(rd, flags))
- goto fail_dcache;
+ if (flags & SQFS_DIR_READER_DOT_ENTRIES) {
+ ret = rbtree_init(&rd->dcache, sizeof(sqfs_u32),
+ sizeof(sqfs_u64), dcache_key_compare);
+
+ if (ret != 0)
+ goto fail_dcache;
+ }
start = super->inode_table_start;
limit = super->directory_table_start;
@@ -95,7 +148,8 @@ sqfs_dir_reader_t *sqfs_dir_reader_create(const sqfs_super_t *super,
fail_mdir:
sqfs_destroy(rd->meta_inode);
fail_mino:
- sqfs_dir_reader_dcache_cleanup(rd);
+ if (flags & SQFS_DIR_READER_DOT_ENTRIES)
+ rbtree_cleanup(&rd->dcache);
fail_dcache:
free(rd);
return NULL;
@@ -123,15 +177,12 @@ int sqfs_dir_reader_open_dir(sqfs_dir_reader_t *rd,
parent = inode->data.dir.parent_inode;
}
- if (sqfs_dir_reader_dcache_find(rd, inode->base.inode_number,
- &rd->cur_ref)) {
+ if (dcache_find(rd, inode->base.inode_number, &rd->cur_ref))
return SQFS_ERROR_NO_ENTRY;
- }
if (rd->cur_ref == rd->super->root_inode_ref) {
rd->parent_ref = rd->cur_ref;
- } else if (sqfs_dir_reader_dcache_find(rd, parent,
- &rd->parent_ref)) {
+ } else if (dcache_find(rd, parent, &rd->parent_ref)) {
return SQFS_ERROR_NO_ENTRY;
}
@@ -242,16 +293,7 @@ int sqfs_dir_reader_get_inode(sqfs_dir_reader_t *rd,
if (ret != 0)
return ret;
- if ((*inode)->base.type == SQFS_INODE_DIR ||
- (*inode)->base.type == SQFS_INODE_EXT_DIR) {
- sqfs_u32 inum = (*inode)->base.inode_number;
-
- ret = sqfs_dir_reader_dcache_add(rd, inum, ref);
- if (ret != 0)
- return ret;
- }
-
- return 0;
+ return dcache_add(rd, *inode, ref);
}
int sqfs_dir_reader_get_root_inode(sqfs_dir_reader_t *rd,
@@ -263,19 +305,8 @@ int sqfs_dir_reader_get_root_inode(sqfs_dir_reader_t *rd,
ret = sqfs_meta_reader_read_inode(rd->meta_inode, rd->super,
block_start, offset, inode);
-
if (ret != 0)
return ret;
- if ((*inode)->base.type == SQFS_INODE_DIR ||
- (*inode)->base.type == SQFS_INODE_EXT_DIR) {
- sqfs_u32 inum = (*inode)->base.inode_number;
- sqfs_u64 ref = rd->super->root_inode_ref;
-
- ret = sqfs_dir_reader_dcache_add(rd, inum, ref);
- if (ret != 0)
- return ret;
- }
-
- return 0;
+ return dcache_add(rd, *inode, rd->super->root_inode_ref);
}
diff --git a/lib/sqfs/dir_reader/internal.h b/lib/sqfs/dir_reader/internal.h
index 4dbe728..63e7cb2 100644
--- a/lib/sqfs/dir_reader/internal.h
+++ b/lib/sqfs/dir_reader/internal.h
@@ -50,18 +50,4 @@ struct sqfs_dir_reader_t {
rbtree_t dcache;
};
-SQFS_INTERNAL int sqfs_dir_reader_dcache_init(sqfs_dir_reader_t *rd,
- sqfs_u32 flags);
-
-SQFS_INTERNAL int sqfs_dir_reader_dcache_init_copy(sqfs_dir_reader_t *copy,
- const sqfs_dir_reader_t *rd);
-
-SQFS_INTERNAL int sqfs_dir_reader_dcache_add(sqfs_dir_reader_t *rd,
- sqfs_u32 inode, sqfs_u64 ref);
-
-SQFS_INTERNAL int sqfs_dir_reader_dcache_find(sqfs_dir_reader_t *rd,
- sqfs_u32 inode, sqfs_u64 *ref);
-
-SQFS_INTERNAL void sqfs_dir_reader_dcache_cleanup(sqfs_dir_reader_t *rd);
-
#endif /* DIR_READER_INTERNAL_H */