@@ -11,10 +11,10 @@ HFILES = addr.h agf.h agfl.h agi.h attr.h attrshort.h bit.h block.h bmap.h \
btblock.h bmroot.h check.h command.h crc.h debug.h \
dir2.h dir2sf.h dquot.h echo.h faddr.h field.h \
flist.h fprint.h frag.h freesp.h hash.h help.h init.h inode.h input.h \
- io.h logformat.h malloc.h metadump.h output.h print.h quit.h sb.h \
+ io.h logformat.h malloc.h metadump.h namei.h output.h print.h quit.h sb.h \
sig.h strvec.h text.h type.h write.h attrset.h symlink.h fsmap.h \
fuzz.h
-CFILES = $(HFILES:.h=.c) btdump.c btheight.c convert.c info.c namei.c \
+CFILES = $(HFILES:.h=.c) btdump.c btheight.c convert.c info.c \
timelimit.c
LSRCFILES = xfs_admin.sh xfs_ncheck.sh xfs_metadump.sh
@@ -14,6 +14,7 @@
#include "fprint.h"
#include "field.h"
#include "inode.h"
+#include "namei.h"
/* Path lookup */
@@ -137,7 +138,7 @@ rele:
}
/* Walk a directory path to an inode and set the io cursor to that inode. */
-static int
+int
path_walk(
char *path)
{
@@ -247,7 +248,8 @@ dir_emit(
char *name,
ssize_t namelen,
xfs_ino_t ino,
- uint8_t dtype)
+ uint8_t dtype,
+ void *priv)
{
char *display_name;
struct xfs_name xname = { .name = (unsigned char *)name };
@@ -284,7 +286,9 @@ dir_emit(
static int
list_sfdir(
- struct xfs_da_args *args)
+ struct xfs_da_args *args,
+ list_dir_fn list_fn,
+ void *priv)
{
struct xfs_inode *dp = args->dp;
struct xfs_mount *mp = dp->i_mount;
@@ -301,13 +305,13 @@ list_sfdir(
/* . and .. entries */
off = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
geo->data_entry_offset);
- dir_emit(args->dp->i_mount, off, ".", -1, dp->i_ino, XFS_DIR3_FT_DIR);
+ list_fn(args->dp->i_mount, off, ".", -1, dp->i_ino, XFS_DIR3_FT_DIR, priv);
ino = libxfs_dir2_sf_get_parent_ino(sfp);
off = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
geo->data_entry_offset +
libxfs_dir2_data_entsize(mp, sizeof(".") - 1));
- dir_emit(args->dp->i_mount, off, "..", -1, ino, XFS_DIR3_FT_DIR);
+ list_fn(args->dp->i_mount, off, "..", -1, ino, XFS_DIR3_FT_DIR, priv);
/* Walk everything else. */
sfep = xfs_dir2_sf_firstentry(sfp);
@@ -317,8 +321,8 @@ list_sfdir(
off = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
xfs_dir2_sf_get_offset(sfep));
- dir_emit(args->dp->i_mount, off, (char *)sfep->name,
- sfep->namelen, ino, filetype);
+ list_fn(args->dp->i_mount, off, (char *)sfep->name,
+ sfep->namelen, ino, filetype, priv);
sfep = libxfs_dir2_sf_nextentry(mp, sfp, sfep);
}
@@ -328,7 +332,9 @@ list_sfdir(
/* List entries in block format directory. */
static int
list_blockdir(
- struct xfs_da_args *args)
+ struct xfs_da_args *args,
+ list_dir_fn list_fn,
+ void *priv)
{
struct xfs_inode *dp = args->dp;
struct xfs_mount *mp = dp->i_mount;
@@ -359,8 +365,8 @@ list_blockdir(
diroff = xfs_dir2_db_off_to_dataptr(geo, geo->datablk, offset);
offset += libxfs_dir2_data_entsize(mp, dep->namelen);
filetype = libxfs_dir2_data_get_ftype(dp->i_mount, dep);
- dir_emit(mp, diroff, (char *)dep->name, dep->namelen,
- be64_to_cpu(dep->inumber), filetype);
+ list_fn(mp, diroff, (char *)dep->name, dep->namelen,
+ be64_to_cpu(dep->inumber), filetype, priv);
}
libxfs_trans_brelse(args->trans, bp);
@@ -370,7 +376,9 @@ list_blockdir(
/* List entries in leaf format directory. */
static int
list_leafdir(
- struct xfs_da_args *args)
+ struct xfs_da_args *args,
+ list_dir_fn list_fn,
+ void *priv)
{
struct xfs_bmbt_irec map;
struct xfs_iext_cursor icur;
@@ -424,9 +432,9 @@ list_leafdir(
offset += libxfs_dir2_data_entsize(mp, dep->namelen);
filetype = libxfs_dir2_data_get_ftype(mp, dep);
- dir_emit(mp, xfs_dir2_byte_to_dataptr(dirboff + offset),
+ list_fn(mp, xfs_dir2_byte_to_dataptr(dirboff + offset),
(char *)dep->name, dep->namelen,
- be64_to_cpu(dep->inumber), filetype);
+ be64_to_cpu(dep->inumber), filetype, priv);
}
dabno += XFS_DADDR_TO_FSB(mp, bp->b_length);
@@ -441,9 +449,11 @@ list_leafdir(
}
/* Read the directory, display contents. */
-static int
+int
listdir(
- struct xfs_inode *dp)
+ struct xfs_inode *dp,
+ list_dir_fn list_fn,
+ void *priv)
{
struct xfs_da_args args = {
.dp = dp,
@@ -453,15 +463,15 @@ listdir(
bool isblock;
if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL)
- return list_sfdir(&args);
+ return list_sfdir(&args, list_fn, priv);
error = -libxfs_dir2_isblock(&args, &isblock);
if (error)
return error;
if (isblock)
- return list_blockdir(&args);
- return list_leafdir(&args);
+ return list_blockdir(&args, list_fn, priv);
+ return list_leafdir(&args, list_fn, priv);
}
/* List the inode number of the currently selected inode. */
@@ -500,7 +510,7 @@ ls_cur(
if (tag)
dbprintf(_("%s:\n"), tag);
- error = listdir(dp);
+ error = listdir(dp, dir_emit, NULL);
if (error)
goto rele;
new file mode 100644
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 Oracle.
+ * All Rights Reserved.
+ */
+
+typedef void (*list_dir_fn)(struct xfs_mount *mp, xfs_dir2_dataptr_t off,
+ char *name, ssize_t namelen, xfs_ino_t inode, uint8_t dtype,
+ void *priv);
+
+extern void namei_init(void);
+extern int listdir(struct xfs_inode *dp, list_dir_fn list_fn, void *priv);
+extern int path_walk(char * path);
Create a namei.h header so that we can export functions needed to walk a directory. This will be used in the next patch to recursively list directory entries. Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com> --- db/Makefile | 4 ++-- db/namei.c | 48 +++++++++++++++++++++++++++++------------------- db/namei.h | 13 +++++++++++++ 3 files changed, 44 insertions(+), 21 deletions(-) create mode 100644 db/namei.h