aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sqfs/dir_reader.h20
-rw-r--r--lib/sqfs/src/dir_reader.c41
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;
+}