• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0 */
2 #ifndef __EROFS_DIR_H
3 #define __EROFS_DIR_H
4 
5 #ifdef __cplusplus
6 extern "C"
7 {
8 #endif
9 
10 #include "internal.h"
11 
12 #define EROFS_READDIR_VALID_PNID	0x0001
13 #define EROFS_READDIR_DOTDOT_FOUND	0x0002
14 #define EROFS_READDIR_DOT_FOUND		0x0004
15 
16 #define EROFS_READDIR_ALL_SPECIAL_FOUND	\
17 	(EROFS_READDIR_DOTDOT_FOUND | EROFS_READDIR_DOT_FOUND)
18 
19 struct erofs_dir_context;
20 
21 /* callback function for iterating over inodes of EROFS */
22 typedef int (*erofs_readdir_cb)(struct erofs_dir_context *);
23 
24 /*
25  * Callers could use a wrapper to contain extra information.
26  *
27  * Note that callback can reuse `struct erofs_dir_context' with care
28  * to avoid stack overflow due to deep recursion:
29  *  - if fsck is true, |pnid|, |flags|, (optional)|cb| SHOULD be saved
30  *    to ensure the original state;
31  *  - if fsck is false, EROFS_READDIR_VALID_PNID SHOULD NOT be
32  *    set if |pnid| is inaccurate.
33  *
34  * Another way is to allocate a `struct erofs_dir_context' wraper
35  * with `struct inode' on heap, and chain them together for
36  * multi-level traversal to completely avoid recursion.
37  *
38  * |dname| may be WITHOUT the trailing '\0' and it's ONLY valid in
39  * the callback context. |de_namelen| is the exact dirent name length.
40  */
41 struct erofs_dir_context {
42 	struct erofs_inode *dir;
43 	erofs_readdir_cb cb;
44 	erofs_nid_t pnid;		/* optional */
45 
46 	/* [OUT] the dirent which is under processing */
47 	const char *dname;		/* please see the comment above */
48 	erofs_nid_t de_nid;
49 	u8 de_namelen, de_ftype, flags;
50 	bool dot_dotdot;
51 };
52 
53 /* Iterate over inodes that are in directory */
54 int erofs_iterate_dir(struct erofs_dir_context *ctx, bool fsck);
55 
56 #ifdef __cplusplus
57 }
58 #endif
59 
60 #endif
61