• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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