xref: /aosp_15_r20/external/erofs-utils/include/erofs/dir.h (revision 33b1fccf6a0fada2c2875d400ed01119b7676ee5)
1*33b1fccfSAndroid Build Coastguard Worker /* SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0 */
2*33b1fccfSAndroid Build Coastguard Worker #ifndef __EROFS_DIR_H
3*33b1fccfSAndroid Build Coastguard Worker #define __EROFS_DIR_H
4*33b1fccfSAndroid Build Coastguard Worker 
5*33b1fccfSAndroid Build Coastguard Worker #ifdef __cplusplus
6*33b1fccfSAndroid Build Coastguard Worker extern "C"
7*33b1fccfSAndroid Build Coastguard Worker {
8*33b1fccfSAndroid Build Coastguard Worker #endif
9*33b1fccfSAndroid Build Coastguard Worker 
10*33b1fccfSAndroid Build Coastguard Worker #include "internal.h"
11*33b1fccfSAndroid Build Coastguard Worker 
12*33b1fccfSAndroid Build Coastguard Worker #define EROFS_READDIR_VALID_PNID	0x0001
13*33b1fccfSAndroid Build Coastguard Worker #define EROFS_READDIR_DOTDOT_FOUND	0x0002
14*33b1fccfSAndroid Build Coastguard Worker #define EROFS_READDIR_DOT_FOUND		0x0004
15*33b1fccfSAndroid Build Coastguard Worker 
16*33b1fccfSAndroid Build Coastguard Worker #define EROFS_READDIR_ALL_SPECIAL_FOUND	\
17*33b1fccfSAndroid Build Coastguard Worker 	(EROFS_READDIR_DOTDOT_FOUND | EROFS_READDIR_DOT_FOUND)
18*33b1fccfSAndroid Build Coastguard Worker 
19*33b1fccfSAndroid Build Coastguard Worker struct erofs_dir_context;
20*33b1fccfSAndroid Build Coastguard Worker 
21*33b1fccfSAndroid Build Coastguard Worker /* callback function for iterating over inodes of EROFS */
22*33b1fccfSAndroid Build Coastguard Worker typedef int (*erofs_readdir_cb)(struct erofs_dir_context *);
23*33b1fccfSAndroid Build Coastguard Worker 
24*33b1fccfSAndroid Build Coastguard Worker /*
25*33b1fccfSAndroid Build Coastguard Worker  * Callers could use a wrapper to contain extra information.
26*33b1fccfSAndroid Build Coastguard Worker  *
27*33b1fccfSAndroid Build Coastguard Worker  * Note that callback can reuse `struct erofs_dir_context' with care
28*33b1fccfSAndroid Build Coastguard Worker  * to avoid stack overflow due to deep recursion:
29*33b1fccfSAndroid Build Coastguard Worker  *  - if fsck is true, |pnid|, |flags|, (optional)|cb| SHOULD be saved
30*33b1fccfSAndroid Build Coastguard Worker  *    to ensure the original state;
31*33b1fccfSAndroid Build Coastguard Worker  *  - if fsck is false, EROFS_READDIR_VALID_PNID SHOULD NOT be
32*33b1fccfSAndroid Build Coastguard Worker  *    set if |pnid| is inaccurate.
33*33b1fccfSAndroid Build Coastguard Worker  *
34*33b1fccfSAndroid Build Coastguard Worker  * Another way is to allocate a `struct erofs_dir_context' wraper
35*33b1fccfSAndroid Build Coastguard Worker  * with `struct inode' on heap, and chain them together for
36*33b1fccfSAndroid Build Coastguard Worker  * multi-level traversal to completely avoid recursion.
37*33b1fccfSAndroid Build Coastguard Worker  *
38*33b1fccfSAndroid Build Coastguard Worker  * |dname| may be WITHOUT the trailing '\0' and it's ONLY valid in
39*33b1fccfSAndroid Build Coastguard Worker  * the callback context. |de_namelen| is the exact dirent name length.
40*33b1fccfSAndroid Build Coastguard Worker  */
41*33b1fccfSAndroid Build Coastguard Worker struct erofs_dir_context {
42*33b1fccfSAndroid Build Coastguard Worker 	/*
43*33b1fccfSAndroid Build Coastguard Worker 	 * During execution of |erofs_iterate_dir|, the function needs to
44*33b1fccfSAndroid Build Coastguard Worker 	 * read the values inside |erofs_inode* dir|. So it is important
45*33b1fccfSAndroid Build Coastguard Worker 	 * that the callback function does not modify struct pointed by
46*33b1fccfSAndroid Build Coastguard Worker 	 * |dir|. It is OK to repoint |dir| to other objects.
47*33b1fccfSAndroid Build Coastguard Worker 	 * Unfortunately, it's not possible to enforce this restriction
48*33b1fccfSAndroid Build Coastguard Worker 	 * with const keyword, as |erofs_iterate_dir| needs to modify
49*33b1fccfSAndroid Build Coastguard Worker 	 * struct pointed by |dir|.
50*33b1fccfSAndroid Build Coastguard Worker 	 */
51*33b1fccfSAndroid Build Coastguard Worker 	struct erofs_inode *dir;
52*33b1fccfSAndroid Build Coastguard Worker 	erofs_readdir_cb cb;
53*33b1fccfSAndroid Build Coastguard Worker 	erofs_nid_t pnid;		/* optional */
54*33b1fccfSAndroid Build Coastguard Worker 
55*33b1fccfSAndroid Build Coastguard Worker 	/* [OUT] the dirent which is under processing */
56*33b1fccfSAndroid Build Coastguard Worker 	const char *dname;		/* please see the comment above */
57*33b1fccfSAndroid Build Coastguard Worker 	erofs_nid_t de_nid;
58*33b1fccfSAndroid Build Coastguard Worker 	u8 de_namelen, de_ftype, flags;
59*33b1fccfSAndroid Build Coastguard Worker 	bool dot_dotdot;
60*33b1fccfSAndroid Build Coastguard Worker };
61*33b1fccfSAndroid Build Coastguard Worker 
62*33b1fccfSAndroid Build Coastguard Worker /* Iterate over inodes that are in directory */
63*33b1fccfSAndroid Build Coastguard Worker int erofs_iterate_dir(struct erofs_dir_context *ctx, bool fsck);
64*33b1fccfSAndroid Build Coastguard Worker /* Get a full pathname of the inode NID */
65*33b1fccfSAndroid Build Coastguard Worker int erofs_get_pathname(struct erofs_sb_info *sbi, erofs_nid_t nid,
66*33b1fccfSAndroid Build Coastguard Worker 		       char *buf, size_t size);
67*33b1fccfSAndroid Build Coastguard Worker 
68*33b1fccfSAndroid Build Coastguard Worker #ifdef __cplusplus
69*33b1fccfSAndroid Build Coastguard Worker }
70*33b1fccfSAndroid Build Coastguard Worker #endif
71*33b1fccfSAndroid Build Coastguard Worker 
72*33b1fccfSAndroid Build Coastguard Worker #endif
73