1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
5 */
6 #ifndef __XFS_DIR2_H__
7 #define __XFS_DIR2_H__
8
9 #include "xfs_da_format.h"
10 #include "xfs_da_btree.h"
11
12 struct xfs_da_args;
13 struct xfs_inode;
14 struct xfs_mount;
15 struct xfs_trans;
16 struct xfs_dir2_sf_hdr;
17 struct xfs_dir2_sf_entry;
18 struct xfs_dir2_data_hdr;
19 struct xfs_dir2_data_entry;
20 struct xfs_dir2_data_unused;
21 struct xfs_dir3_icfree_hdr;
22 struct xfs_dir3_icleaf_hdr;
23
24 extern struct xfs_name xfs_name_dotdot;
25
26 /*
27 * Convert inode mode to directory entry filetype
28 */
29 extern unsigned char xfs_mode_to_ftype(int mode);
30
31 /*
32 * directory operations vector for encode/decode routines
33 */
34 struct xfs_dir_ops {
35 int (*sf_entsize)(struct xfs_dir2_sf_hdr *hdr, int len);
36 struct xfs_dir2_sf_entry *
37 (*sf_nextentry)(struct xfs_dir2_sf_hdr *hdr,
38 struct xfs_dir2_sf_entry *sfep);
39 uint8_t (*sf_get_ftype)(struct xfs_dir2_sf_entry *sfep);
40 void (*sf_put_ftype)(struct xfs_dir2_sf_entry *sfep,
41 uint8_t ftype);
42 xfs_ino_t (*sf_get_ino)(struct xfs_dir2_sf_hdr *hdr,
43 struct xfs_dir2_sf_entry *sfep);
44 void (*sf_put_ino)(struct xfs_dir2_sf_hdr *hdr,
45 struct xfs_dir2_sf_entry *sfep,
46 xfs_ino_t ino);
47 xfs_ino_t (*sf_get_parent_ino)(struct xfs_dir2_sf_hdr *hdr);
48 void (*sf_put_parent_ino)(struct xfs_dir2_sf_hdr *hdr,
49 xfs_ino_t ino);
50
51 int (*data_entsize)(int len);
52 uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep);
53 void (*data_put_ftype)(struct xfs_dir2_data_entry *dep,
54 uint8_t ftype);
55 __be16 * (*data_entry_tag_p)(struct xfs_dir2_data_entry *dep);
56 struct xfs_dir2_data_free *
57 (*data_bestfree_p)(struct xfs_dir2_data_hdr *hdr);
58
59 xfs_dir2_data_aoff_t data_dot_offset;
60 xfs_dir2_data_aoff_t data_dotdot_offset;
61 xfs_dir2_data_aoff_t data_first_offset;
62 size_t data_entry_offset;
63
64 struct xfs_dir2_data_entry *
65 (*data_dot_entry_p)(struct xfs_dir2_data_hdr *hdr);
66 struct xfs_dir2_data_entry *
67 (*data_dotdot_entry_p)(struct xfs_dir2_data_hdr *hdr);
68 struct xfs_dir2_data_entry *
69 (*data_first_entry_p)(struct xfs_dir2_data_hdr *hdr);
70 struct xfs_dir2_data_entry *
71 (*data_entry_p)(struct xfs_dir2_data_hdr *hdr);
72 struct xfs_dir2_data_unused *
73 (*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
74
75 int leaf_hdr_size;
76 void (*leaf_hdr_to_disk)(struct xfs_dir2_leaf *to,
77 struct xfs_dir3_icleaf_hdr *from);
78 void (*leaf_hdr_from_disk)(struct xfs_dir3_icleaf_hdr *to,
79 struct xfs_dir2_leaf *from);
80 int (*leaf_max_ents)(struct xfs_da_geometry *geo);
81 struct xfs_dir2_leaf_entry *
82 (*leaf_ents_p)(struct xfs_dir2_leaf *lp);
83
84 int node_hdr_size;
85 void (*node_hdr_to_disk)(struct xfs_da_intnode *to,
86 struct xfs_da3_icnode_hdr *from);
87 void (*node_hdr_from_disk)(struct xfs_da3_icnode_hdr *to,
88 struct xfs_da_intnode *from);
89 struct xfs_da_node_entry *
90 (*node_tree_p)(struct xfs_da_intnode *dap);
91
92 int free_hdr_size;
93 void (*free_hdr_to_disk)(struct xfs_dir2_free *to,
94 struct xfs_dir3_icfree_hdr *from);
95 void (*free_hdr_from_disk)(struct xfs_dir3_icfree_hdr *to,
96 struct xfs_dir2_free *from);
97 int (*free_max_bests)(struct xfs_da_geometry *geo);
98 __be16 * (*free_bests_p)(struct xfs_dir2_free *free);
99 xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo,
100 xfs_dir2_db_t db);
101 int (*db_to_fdindex)(struct xfs_da_geometry *geo,
102 xfs_dir2_db_t db);
103 };
104
105 extern const struct xfs_dir_ops *
106 xfs_dir_get_ops(struct xfs_mount *mp, struct xfs_inode *dp);
107 extern const struct xfs_dir_ops *
108 xfs_nondir_get_ops(struct xfs_mount *mp, struct xfs_inode *dp);
109
110 /*
111 * Generic directory interface routines
112 */
113 extern void xfs_dir_startup(void);
114 extern int xfs_da_mount(struct xfs_mount *mp);
115 extern void xfs_da_unmount(struct xfs_mount *mp);
116
117 extern int xfs_dir_isempty(struct xfs_inode *dp);
118 extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp,
119 struct xfs_inode *pdp);
120 extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp,
121 struct xfs_name *name, xfs_ino_t inum,
122 xfs_extlen_t tot);
123 extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp,
124 struct xfs_name *name, xfs_ino_t *inum,
125 struct xfs_name *ci_name);
126 extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp,
127 struct xfs_name *name, xfs_ino_t ino,
128 xfs_extlen_t tot);
129 extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
130 struct xfs_name *name, xfs_ino_t inum,
131 xfs_extlen_t tot);
132 extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp,
133 struct xfs_name *name);
134
135 /*
136 * Direct call from the bmap code, bypassing the generic directory layer.
137 */
138 extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
139
140 /*
141 * Interface routines used by userspace utilities
142 */
143 extern int xfs_dir2_isblock(struct xfs_da_args *args, int *r);
144 extern int xfs_dir2_isleaf(struct xfs_da_args *args, int *r);
145 extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
146 struct xfs_buf *bp);
147
148 extern void xfs_dir2_data_freescan_int(struct xfs_da_geometry *geo,
149 const struct xfs_dir_ops *ops,
150 struct xfs_dir2_data_hdr *hdr, int *loghead);
151 extern void xfs_dir2_data_freescan(struct xfs_inode *dp,
152 struct xfs_dir2_data_hdr *hdr, int *loghead);
153 extern void xfs_dir2_data_log_entry(struct xfs_da_args *args,
154 struct xfs_buf *bp, struct xfs_dir2_data_entry *dep);
155 extern void xfs_dir2_data_log_header(struct xfs_da_args *args,
156 struct xfs_buf *bp);
157 extern void xfs_dir2_data_log_unused(struct xfs_da_args *args,
158 struct xfs_buf *bp, struct xfs_dir2_data_unused *dup);
159 extern void xfs_dir2_data_make_free(struct xfs_da_args *args,
160 struct xfs_buf *bp, xfs_dir2_data_aoff_t offset,
161 xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);
162 extern int xfs_dir2_data_use_free(struct xfs_da_args *args,
163 struct xfs_buf *bp, struct xfs_dir2_data_unused *dup,
164 xfs_dir2_data_aoff_t offset, xfs_dir2_data_aoff_t len,
165 int *needlogp, int *needscanp);
166
167 extern struct xfs_dir2_data_free *xfs_dir2_data_freefind(
168 struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_free *bf,
169 struct xfs_dir2_data_unused *dup);
170
171 extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
172
173 extern const struct xfs_buf_ops xfs_dir3_block_buf_ops;
174 extern const struct xfs_buf_ops xfs_dir3_leafn_buf_ops;
175 extern const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops;
176 extern const struct xfs_buf_ops xfs_dir3_free_buf_ops;
177 extern const struct xfs_buf_ops xfs_dir3_data_buf_ops;
178
179 /*
180 * Directory offset/block conversion functions.
181 *
182 * DB blocks here are logical directory block numbers, not filesystem blocks.
183 */
184
185 /*
186 * Convert dataptr to byte in file space
187 */
188 static inline xfs_dir2_off_t
xfs_dir2_dataptr_to_byte(xfs_dir2_dataptr_t dp)189 xfs_dir2_dataptr_to_byte(xfs_dir2_dataptr_t dp)
190 {
191 return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
192 }
193
194 /*
195 * Convert byte in file space to dataptr. It had better be aligned.
196 */
197 static inline xfs_dir2_dataptr_t
xfs_dir2_byte_to_dataptr(xfs_dir2_off_t by)198 xfs_dir2_byte_to_dataptr(xfs_dir2_off_t by)
199 {
200 return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
201 }
202
203 /*
204 * Convert byte in space to (DB) block
205 */
206 static inline xfs_dir2_db_t
xfs_dir2_byte_to_db(struct xfs_da_geometry * geo,xfs_dir2_off_t by)207 xfs_dir2_byte_to_db(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
208 {
209 return (xfs_dir2_db_t)(by >> geo->blklog);
210 }
211
212 /*
213 * Convert dataptr to a block number
214 */
215 static inline xfs_dir2_db_t
xfs_dir2_dataptr_to_db(struct xfs_da_geometry * geo,xfs_dir2_dataptr_t dp)216 xfs_dir2_dataptr_to_db(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
217 {
218 return xfs_dir2_byte_to_db(geo, xfs_dir2_dataptr_to_byte(dp));
219 }
220
221 /*
222 * Convert byte in space to offset in a block
223 */
224 static inline xfs_dir2_data_aoff_t
xfs_dir2_byte_to_off(struct xfs_da_geometry * geo,xfs_dir2_off_t by)225 xfs_dir2_byte_to_off(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
226 {
227 return (xfs_dir2_data_aoff_t)(by & (geo->blksize - 1));
228 }
229
230 /*
231 * Convert dataptr to a byte offset in a block
232 */
233 static inline xfs_dir2_data_aoff_t
xfs_dir2_dataptr_to_off(struct xfs_da_geometry * geo,xfs_dir2_dataptr_t dp)234 xfs_dir2_dataptr_to_off(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
235 {
236 return xfs_dir2_byte_to_off(geo, xfs_dir2_dataptr_to_byte(dp));
237 }
238
239 /*
240 * Convert block and offset to byte in space
241 */
242 static inline xfs_dir2_off_t
xfs_dir2_db_off_to_byte(struct xfs_da_geometry * geo,xfs_dir2_db_t db,xfs_dir2_data_aoff_t o)243 xfs_dir2_db_off_to_byte(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
244 xfs_dir2_data_aoff_t o)
245 {
246 return ((xfs_dir2_off_t)db << geo->blklog) + o;
247 }
248
249 /*
250 * Convert block (DB) to block (dablk)
251 */
252 static inline xfs_dablk_t
xfs_dir2_db_to_da(struct xfs_da_geometry * geo,xfs_dir2_db_t db)253 xfs_dir2_db_to_da(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
254 {
255 return (xfs_dablk_t)(db << (geo->blklog - geo->fsblog));
256 }
257
258 /*
259 * Convert byte in space to (DA) block
260 */
261 static inline xfs_dablk_t
xfs_dir2_byte_to_da(struct xfs_da_geometry * geo,xfs_dir2_off_t by)262 xfs_dir2_byte_to_da(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
263 {
264 return xfs_dir2_db_to_da(geo, xfs_dir2_byte_to_db(geo, by));
265 }
266
267 /*
268 * Convert block and offset to dataptr
269 */
270 static inline xfs_dir2_dataptr_t
xfs_dir2_db_off_to_dataptr(struct xfs_da_geometry * geo,xfs_dir2_db_t db,xfs_dir2_data_aoff_t o)271 xfs_dir2_db_off_to_dataptr(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
272 xfs_dir2_data_aoff_t o)
273 {
274 return xfs_dir2_byte_to_dataptr(xfs_dir2_db_off_to_byte(geo, db, o));
275 }
276
277 /*
278 * Convert block (dablk) to block (DB)
279 */
280 static inline xfs_dir2_db_t
xfs_dir2_da_to_db(struct xfs_da_geometry * geo,xfs_dablk_t da)281 xfs_dir2_da_to_db(struct xfs_da_geometry *geo, xfs_dablk_t da)
282 {
283 return (xfs_dir2_db_t)(da >> (geo->blklog - geo->fsblog));
284 }
285
286 /*
287 * Convert block (dablk) to byte offset in space
288 */
289 static inline xfs_dir2_off_t
xfs_dir2_da_to_byte(struct xfs_da_geometry * geo,xfs_dablk_t da)290 xfs_dir2_da_to_byte(struct xfs_da_geometry *geo, xfs_dablk_t da)
291 {
292 return xfs_dir2_db_off_to_byte(geo, xfs_dir2_da_to_db(geo, da), 0);
293 }
294
295 /*
296 * Directory tail pointer accessor functions. Based on block geometry.
297 */
298 static inline struct xfs_dir2_block_tail *
xfs_dir2_block_tail_p(struct xfs_da_geometry * geo,struct xfs_dir2_data_hdr * hdr)299 xfs_dir2_block_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_data_hdr *hdr)
300 {
301 return ((struct xfs_dir2_block_tail *)
302 ((char *)hdr + geo->blksize)) - 1;
303 }
304
305 static inline struct xfs_dir2_leaf_tail *
xfs_dir2_leaf_tail_p(struct xfs_da_geometry * geo,struct xfs_dir2_leaf * lp)306 xfs_dir2_leaf_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_leaf *lp)
307 {
308 return (struct xfs_dir2_leaf_tail *)
309 ((char *)lp + geo->blksize -
310 sizeof(struct xfs_dir2_leaf_tail));
311 }
312
313 /*
314 * The Linux API doesn't pass down the total size of the buffer
315 * we read into down to the filesystem. With the filldir concept
316 * it's not needed for correct information, but the XFS dir2 leaf
317 * code wants an estimate of the buffer size to calculate it's
318 * readahead window and size the buffers used for mapping to
319 * physical blocks.
320 *
321 * Try to give it an estimate that's good enough, maybe at some
322 * point we can change the ->readdir prototype to include the
323 * buffer size. For now we use the current glibc buffer size.
324 * musl libc hardcodes 2k and dietlibc uses PAGE_SIZE.
325 */
326 #define XFS_READDIR_BUFSIZE (32768)
327
328 unsigned char xfs_dir3_get_dtype(struct xfs_mount *mp, uint8_t filetype);
329 void *xfs_dir3_data_endp(struct xfs_da_geometry *geo,
330 struct xfs_dir2_data_hdr *hdr);
331 bool xfs_dir2_namecheck(const void *name, size_t length);
332
333 #endif /* __XFS_DIR2_H__ */
334