+
+/*
+ * Return the count of number of directories in the dir_info structure
+ */
+int e2fsck_get_num_dirinfo(e2fsck_t ctx)
+{
+ return ctx->dir_info ? ctx->dir_info->count : 0;
+}
+
+struct dir_info_iter *e2fsck_dir_info_iter_begin(e2fsck_t ctx)
+{
+ struct dir_info_iter *iter;
+
+ iter = e2fsck_allocate_memory(ctx, sizeof(struct dir_info_iter),
+ "dir_info iterator");
+
+#ifdef CONFIG_TDB
+ if (ctx->dir_info->tdb)
+ iter->tdb_iter = tdb_firstkey(ctx->dir_info->tdb);
+#endif
+
+ return iter;
+}
+
+void e2fsck_dir_info_iter_end(e2fsck_t ctx EXT2FS_ATTR((unused)),
+ struct dir_info_iter *iter)
+{
+#ifdef CONFIG_TDB
+ free(iter->tdb_iter.dptr);
+#endif
+ ext2fs_free_mem(&iter);
+}
+
+/*
+ * A simple iterator function
+ */
+struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, struct dir_info_iter *iter)
+{
+ if (!ctx->dir_info || !iter)
+ return 0;
+
+#ifdef CONFIG_TDB
+ if (ctx->dir_info->tdb) {
+ static struct dir_info ret_dir_info;
+ struct dir_info_ent *buf;
+ TDB_DATA data, key;
+
+ if (iter->tdb_iter.dptr == 0)
+ return 0;
+ key = iter->tdb_iter;
+ data = tdb_fetch(ctx->dir_info->tdb, key);
+ if (!data.dptr) {
+ printf("iter fetch failed: %s\n",
+ tdb_errorstr(ctx->dir_info->tdb));
+ return 0;
+ }
+ buf = (struct dir_info_ent *) data.dptr;
+ ret_dir_info.ino = *((ext2_ino_t *) iter->tdb_iter.dptr);
+ ret_dir_info.dotdot = buf->dotdot;
+ ret_dir_info.parent = buf->parent;
+ iter->tdb_iter = tdb_nextkey(ctx->dir_info->tdb, key);
+ free(key.dptr);
+ free(data.dptr);
+ return &ret_dir_info;
+ }
+#endif
+
+ if (iter->i >= ctx->dir_info->count)
+ return 0;
+
+#ifdef DIRINFO_DEBUG
+ printf("iter(%u, %u, %u)...", ctx->dir_info->array[iter->i].ino,
+ ctx->dir_info->array[iter->i].dotdot,
+ ctx->dir_info->array[iter->i].parent);
+#endif
+ ctx->dir_info->last_lookup = ctx->dir_info->array + iter->i++;
+ return(ctx->dir_info->last_lookup);
+}
+
+/*
+ * This function only sets the parent pointer, and requires that
+ * dirinfo structure has already been created.
+ */
+int e2fsck_dir_info_set_parent(e2fsck_t ctx, ext2_ino_t ino,
+ ext2_ino_t parent)
+{
+ struct dir_info *p;
+
+ p = e2fsck_get_dir_info(ctx, ino);
+ if (!p)
+ return 1;
+ p->parent = parent;
+ e2fsck_put_dir_info(ctx, p);
+ return 0;
+}
+
+/*
+ * This function only sets the dot dot pointer, and requires that
+ * dirinfo structure has already been created.
+ */
+int e2fsck_dir_info_set_dotdot(e2fsck_t ctx, ext2_ino_t ino,
+ ext2_ino_t dotdot)
+{
+ struct dir_info *p;
+
+ p = e2fsck_get_dir_info(ctx, ino);
+ if (!p)
+ return 1;
+ p->dotdot = dotdot;
+ e2fsck_put_dir_info(ctx, p);
+ return 0;
+}
+
+/*
+ * This function only sets the parent pointer, and requires that
+ * dirinfo structure has already been created.
+ */
+int e2fsck_dir_info_get_parent(e2fsck_t ctx, ext2_ino_t ino,
+ ext2_ino_t *parent)
+{
+ struct dir_info *p;
+
+ p = e2fsck_get_dir_info(ctx, ino);
+ if (!p)
+ return 1;
+ *parent = p->parent;
+ return 0;
+}
+
+/*
+ * This function only sets the dot dot pointer, and requires that
+ * dirinfo structure has already been created.
+ */
+int e2fsck_dir_info_get_dotdot(e2fsck_t ctx, ext2_ino_t ino,
+ ext2_ino_t *dotdot)
+{
+ struct dir_info *p;
+
+ p = e2fsck_get_dir_info(ctx, ino);
+ if (!p)
+ return 1;
+ *dotdot = p->dotdot;
+ return 0;
+}
+