aboutsummaryrefslogtreecommitdiff
path: root/dump/main.c
diff options
context:
space:
mode:
authorIgor Ostapenko <igoreisberg@gmail.com>2021-12-17 14:08:23 +0200
committerGao Xiang <xiang@kernel.org>2021-12-18 21:35:41 +0800
commite6082718f7434628af5687e103090f3981ed6fea (patch)
tree4c58f8274dab2844c9b7b6b8cacb67c942dfc885 /dump/main.c
parent5a9ac8e057cf744eb844da840ea08468c1be1f30 (diff)
downloaderofs-utils-e6082718f7434628af5687e103090f3981ed6fea.tar.gz
erofs-utils: lib: add API to get pathname of EROFS inode
* General-purpose erofs_get_pathname function utilizing erofs_iterate_dir, with recursion and a reused context to avoid overflowing the stack. Recommended buffer size is PATH_MAX. Zero-filling the buffer is not necessary. * dump: PATH_MAX+1 is not required since the definition of PATH_MAX is "chars in a path name including nul". * Return err from erofs_iterate_dir instead of hardcoded 0, to allow breaking the iteration by the callback using a non-zero return code. Link: https://lore.kernel.org/r/CABjEcnE84FNBgiHFk6Q+V3d-4L-93bUFDkdfN4ftPX19kpC=ww@mail.gmail.com Signed-off-by: Igor Ostapenko <igoreisberg@gmail.com> [ Gao Xiang: let's use NID instead of (struct erofs_inode *). ] Signed-off-by: Gao Xiang <xiang@kernel.org>
Diffstat (limited to 'dump/main.c')
-rw-r--r--dump/main.c72
1 files changed, 3 insertions, 69 deletions
diff --git a/dump/main.c b/dump/main.c
index 7f3f743..997460c 100644
--- a/dump/main.c
+++ b/dump/main.c
@@ -328,71 +328,6 @@ static inline int erofs_checkdirent(struct erofs_dirent *de,
return dname_len;
}
-static int erofs_get_pathname(erofs_nid_t nid, erofs_nid_t parent_nid,
- erofs_nid_t target, char *path, unsigned int pos)
-{
- int err;
- erofs_off_t offset;
- char buf[EROFS_BLKSIZ];
- struct erofs_inode inode = { .nid = nid };
-
- path[pos++] = '/';
- if (target == sbi.root_nid)
- return 0;
-
- err = erofs_read_inode_from_disk(&inode);
- if (err) {
- erofs_err("read inode failed @ nid %llu", nid | 0ULL);
- return err;
- }
-
- offset = 0;
- while (offset < inode.i_size) {
- erofs_off_t maxsize = min_t(erofs_off_t,
- inode.i_size - offset, EROFS_BLKSIZ);
- struct erofs_dirent *de = (void *)buf;
- struct erofs_dirent *end;
- unsigned int nameoff;
-
- err = erofs_pread(&inode, buf, maxsize, offset);
- if (err)
- return err;
-
- nameoff = le16_to_cpu(de->nameoff);
- end = (void *)buf + nameoff;
- while (de < end) {
- const char *dname;
- int len;
-
- nameoff = le16_to_cpu(de->nameoff);
- dname = (char *)buf + nameoff;
- len = erofs_checkdirent(de, end, maxsize, dname);
- if (len < 0)
- return len;
-
- if (le64_to_cpu(de->nid) == target) {
- memcpy(path + pos, dname, len);
- path[pos + len] = '\0';
- return 0;
- }
-
- if (de->file_type == EROFS_FT_DIR &&
- le64_to_cpu(de->nid) != parent_nid &&
- le64_to_cpu(de->nid) != nid) {
- memcpy(path + pos, dname, len);
- err = erofs_get_pathname(le64_to_cpu(de->nid),
- nid, target, path, pos + len);
- if (!err)
- return 0;
- memset(path + pos, 0, len);
- }
- ++de;
- }
- offset += maxsize;
- }
- return -1;
-}
-
static int erofsdump_map_blocks(struct erofs_inode *inode,
struct erofs_map_blocks *map, int flags)
{
@@ -411,7 +346,7 @@ static void erofsdump_show_fileinfo(bool show_extent)
erofs_off_t size;
u16 access_mode;
struct erofs_inode inode = { .nid = dumpcfg.nid };
- char path[PATH_MAX + 1] = {0};
+ char path[PATH_MAX];
char access_mode_str[] = "rwxrwxrwx";
char timebuf[128] = {0};
unsigned int extent_count = 0;
@@ -441,8 +376,7 @@ static void erofsdump_show_fileinfo(bool show_extent)
return;
}
- err = erofs_get_pathname(sbi.root_nid, sbi.root_nid,
- inode.nid, path, 0);
+ err = erofs_get_pathname(dumpcfg.nid, path, sizeof(path));
if (err < 0) {
erofs_err("file path not found @ nid %llu", inode.nid | 0ULL);
return;
@@ -598,7 +532,7 @@ static void erofsdump_print_statistic(void)
.cb = erofsdump_dirent_iter,
.de_nid = sbi.root_nid,
.dname = "",
- .de_namelen = 0
+ .de_namelen = 0,
};
err = erofsdump_readdir(&ctx);