diff options
Diffstat (limited to 'lib/sqfs')
-rw-r--r-- | lib/sqfs/Makemodule.am | 2 | ||||
-rw-r--r-- | lib/sqfs/dir_reader/dcache.c | 73 | ||||
-rw-r--r-- | lib/sqfs/dir_reader/dir_reader.c | 99 | ||||
-rw-r--r-- | lib/sqfs/dir_reader/internal.h | 14 |
4 files changed, 66 insertions, 122 deletions
diff --git a/lib/sqfs/Makemodule.am b/lib/sqfs/Makemodule.am index c3add8e..f7292b1 100644 --- a/lib/sqfs/Makemodule.am +++ b/lib/sqfs/Makemodule.am @@ -33,7 +33,7 @@ libsquashfs_la_SOURCES += lib/sqfs/block_processor/block_processor.c libsquashfs_la_SOURCES += lib/sqfs/block_processor/backend.c libsquashfs_la_SOURCES += lib/sqfs/frag_table.c include/sqfs/frag_table.h libsquashfs_la_SOURCES += lib/sqfs/block_writer.c include/sqfs/block_writer.h -libsquashfs_la_SOURCES += lib/sqfs/misc.c lib/sqfs/dir_reader/dcache.c +libsquashfs_la_SOURCES += lib/sqfs/misc.c libsquashfs_la_CPPFLAGS = $(AM_CPPFLAGS) libsquashfs_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBSQUASHFS_SO_VERSION) libsquashfs_la_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) $(ZLIB_CFLAGS) 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, ©->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, ©->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(©->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 */ |