From 2d01fe534a775dcab61651ef807fc118c579dd3d Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sat, 16 Sep 2023 03:00:30 +0200 Subject: libsqfs: Expose the directory reader cache query function Signed-off-by: David Oberhollenzer --- include/sqfs/dir_reader.h | 20 ++++++++++++++++++++ lib/sqfs/src/dir_reader.c | 41 +++++++++++++++++++++++------------------ 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/include/sqfs/dir_reader.h b/include/sqfs/dir_reader.h index 11f7ae0..ceac22b 100644 --- a/include/sqfs/dir_reader.h +++ b/include/sqfs/dir_reader.h @@ -253,6 +253,26 @@ SQFS_API int sqfs_dir_reader_get_inode(sqfs_dir_reader_t *rd, sqfs_u64 ref, SQFS_API int sqfs_dir_reader_get_root_inode(sqfs_dir_reader_t *rd, sqfs_inode_generic_t **inode); +/** + * @brief Try to lookup a cached inode number + * + * @memberof sqfs_dir_reader_t + * + * If the inode reader was created with the @ref SQFS_DIR_READER_DOT_ENTRIES + * flag, it maintains an internal cache of all directory inodes that it has + * seen while traversing the filesystem. The cache maps inode numbers to + * inode references. This is used to lookup the parent inode of directory. + * This function can be used to query the cache directly. + * + * @param rd A pointer to a directory reader. + * @param inode An inode number. + * @param ref Retrns an inode reference on success. + * + * @return Zero on success, @ref SQFS_ERROR_NO_ENTRY if the inode is unknown + */ +SQFS_API int sqfs_dir_reader_resolve_inum(sqfs_dir_reader_t *rd, + sqfs_u32 inode, sqfs_u64 *ref); + #ifdef __cplusplus } #endif diff --git a/lib/sqfs/src/dir_reader.c b/lib/sqfs/src/dir_reader.c index 042b93a..6920a7d 100644 --- a/lib/sqfs/src/dir_reader.c +++ b/lib/sqfs/src/dir_reader.c @@ -63,21 +63,6 @@ static int dcache_add(sqfs_dir_reader_t *rd, 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; @@ -208,12 +193,15 @@ 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, &state->dir_ref)) - return SQFS_ERROR_NO_ENTRY; + ret = sqfs_dir_reader_resolve_inum(rd, inode->base.inode_number, + &state->dir_ref); + if (ret) + return ret; if (state->dir_ref == rd->super.root_inode_ref) { state->parent_ref = state->dir_ref; - } else if (dcache_find(rd, parent, &state->parent_ref)) { + } else if (sqfs_dir_reader_resolve_inum(rd, parent, + &state->parent_ref)) { return SQFS_ERROR_NO_ENTRY; } @@ -291,3 +279,20 @@ int sqfs_dir_reader_get_root_inode(sqfs_dir_reader_t *rd, { return sqfs_dir_reader_get_inode(rd, rd->super.root_inode_ref, inode); } + +int sqfs_dir_reader_resolve_inum(sqfs_dir_reader_t *rd, + sqfs_u32 inode, sqfs_u64 *ref) +{ + rbtree_node_t *node; + + *ref = 0; + 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; +} -- cgit v1.2.3