Linux Audio

Check our new training course

Loading...
v4.6
 
  1/*
  2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
  3 * All Rights Reserved.
  4 *
  5 * This program is free software; you can redistribute it and/or
  6 * modify it under the terms of the GNU General Public License as
  7 * published by the Free Software Foundation.
  8 *
  9 * This program is distributed in the hope that it would be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12 * GNU General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU General Public License
 15 * along with this program; if not, write the Free Software Foundation,
 16 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 17 */
 18#ifndef __XFS_DIR2_H__
 19#define __XFS_DIR2_H__
 20
 21struct xfs_bmap_free;
 
 
 22struct xfs_da_args;
 23struct xfs_inode;
 24struct xfs_mount;
 25struct xfs_trans;
 26struct xfs_dir2_sf_hdr;
 27struct xfs_dir2_sf_entry;
 28struct xfs_dir2_data_hdr;
 29struct xfs_dir2_data_entry;
 30struct xfs_dir2_data_unused;
 
 
 31
 32extern struct xfs_name	xfs_name_dotdot;
 33
 34/*
 35 * directory filetype conversion tables.
 36 */
 37#define S_SHIFT 12
 38extern const unsigned char xfs_mode_to_ftype[];
 39
 40/*
 41 * directory operations vector for encode/decode routines
 42 */
 43struct xfs_dir_ops {
 44	int	(*sf_entsize)(struct xfs_dir2_sf_hdr *hdr, int len);
 45	struct xfs_dir2_sf_entry *
 46		(*sf_nextentry)(struct xfs_dir2_sf_hdr *hdr,
 47				struct xfs_dir2_sf_entry *sfep);
 48	__uint8_t (*sf_get_ftype)(struct xfs_dir2_sf_entry *sfep);
 49	void	(*sf_put_ftype)(struct xfs_dir2_sf_entry *sfep,
 50				__uint8_t ftype);
 51	xfs_ino_t (*sf_get_ino)(struct xfs_dir2_sf_hdr *hdr,
 52				struct xfs_dir2_sf_entry *sfep);
 53	void	(*sf_put_ino)(struct xfs_dir2_sf_hdr *hdr,
 54			      struct xfs_dir2_sf_entry *sfep,
 55			      xfs_ino_t ino);
 56	xfs_ino_t (*sf_get_parent_ino)(struct xfs_dir2_sf_hdr *hdr);
 57	void	(*sf_put_parent_ino)(struct xfs_dir2_sf_hdr *hdr,
 58				     xfs_ino_t ino);
 59
 60	int	(*data_entsize)(int len);
 61	__uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep);
 62	void	(*data_put_ftype)(struct xfs_dir2_data_entry *dep,
 63				__uint8_t ftype);
 64	__be16 * (*data_entry_tag_p)(struct xfs_dir2_data_entry *dep);
 65	struct xfs_dir2_data_free *
 66		(*data_bestfree_p)(struct xfs_dir2_data_hdr *hdr);
 67
 68	xfs_dir2_data_aoff_t data_dot_offset;
 69	xfs_dir2_data_aoff_t data_dotdot_offset;
 70	xfs_dir2_data_aoff_t data_first_offset;
 71	size_t	data_entry_offset;
 72
 73	struct xfs_dir2_data_entry *
 74		(*data_dot_entry_p)(struct xfs_dir2_data_hdr *hdr);
 75	struct xfs_dir2_data_entry *
 76		(*data_dotdot_entry_p)(struct xfs_dir2_data_hdr *hdr);
 77	struct xfs_dir2_data_entry *
 78		(*data_first_entry_p)(struct xfs_dir2_data_hdr *hdr);
 79	struct xfs_dir2_data_entry *
 80		(*data_entry_p)(struct xfs_dir2_data_hdr *hdr);
 81	struct xfs_dir2_data_unused *
 82		(*data_unused_p)(struct xfs_dir2_data_hdr *hdr);
 83
 84	int	leaf_hdr_size;
 85	void	(*leaf_hdr_to_disk)(struct xfs_dir2_leaf *to,
 86				    struct xfs_dir3_icleaf_hdr *from);
 87	void	(*leaf_hdr_from_disk)(struct xfs_dir3_icleaf_hdr *to,
 88				      struct xfs_dir2_leaf *from);
 89	int	(*leaf_max_ents)(struct xfs_da_geometry *geo);
 90	struct xfs_dir2_leaf_entry *
 91		(*leaf_ents_p)(struct xfs_dir2_leaf *lp);
 92
 93	int	node_hdr_size;
 94	void	(*node_hdr_to_disk)(struct xfs_da_intnode *to,
 95				    struct xfs_da3_icnode_hdr *from);
 96	void	(*node_hdr_from_disk)(struct xfs_da3_icnode_hdr *to,
 97				      struct xfs_da_intnode *from);
 98	struct xfs_da_node_entry *
 99		(*node_tree_p)(struct xfs_da_intnode *dap);
100
101	int	free_hdr_size;
102	void	(*free_hdr_to_disk)(struct xfs_dir2_free *to,
103				    struct xfs_dir3_icfree_hdr *from);
104	void	(*free_hdr_from_disk)(struct xfs_dir3_icfree_hdr *to,
105				      struct xfs_dir2_free *from);
106	int	(*free_max_bests)(struct xfs_da_geometry *geo);
107	__be16 * (*free_bests_p)(struct xfs_dir2_free *free);
108	xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo,
109				   xfs_dir2_db_t db);
110	int	(*db_to_fdindex)(struct xfs_da_geometry *geo,
111				 xfs_dir2_db_t db);
112};
113
114extern const struct xfs_dir_ops *
115	xfs_dir_get_ops(struct xfs_mount *mp, struct xfs_inode *dp);
116extern const struct xfs_dir_ops *
117	xfs_nondir_get_ops(struct xfs_mount *mp, struct xfs_inode *dp);
118
119/*
120 * Generic directory interface routines
121 */
122extern void xfs_dir_startup(void);
123extern int xfs_da_mount(struct xfs_mount *mp);
124extern void xfs_da_unmount(struct xfs_mount *mp);
125
126extern int xfs_dir_isempty(struct xfs_inode *dp);
127extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp,
128				struct xfs_inode *pdp);
129extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp,
130				struct xfs_name *name, xfs_ino_t inum,
131				xfs_fsblock_t *first,
132				struct xfs_bmap_free *flist, xfs_extlen_t tot);
133extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp,
134				struct xfs_name *name, xfs_ino_t *inum,
135				struct xfs_name *ci_name);
136extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp,
137				struct xfs_name *name, xfs_ino_t ino,
138				xfs_fsblock_t *first,
139				struct xfs_bmap_free *flist, xfs_extlen_t tot);
140extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
141				struct xfs_name *name, xfs_ino_t inum,
142				xfs_fsblock_t *first,
143				struct xfs_bmap_free *flist, xfs_extlen_t tot);
144extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp,
145				struct xfs_name *name);
146
147/*
148 * Direct call from the bmap code, bypassing the generic directory layer.
149 */
150extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
151
152/*
153 * Interface routines used by userspace utilities
154 */
155extern int xfs_dir2_isblock(struct xfs_da_args *args, int *r);
156extern int xfs_dir2_isleaf(struct xfs_da_args *args, int *r);
157extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
158				struct xfs_buf *bp);
159
160extern void xfs_dir2_data_freescan(struct xfs_inode *dp,
161		struct xfs_dir2_data_hdr *hdr, int *loghead);
162extern void xfs_dir2_data_log_entry(struct xfs_da_args *args,
163		struct xfs_buf *bp, struct xfs_dir2_data_entry *dep);
164extern void xfs_dir2_data_log_header(struct xfs_da_args *args,
165		struct xfs_buf *bp);
166extern void xfs_dir2_data_log_unused(struct xfs_da_args *args,
167		struct xfs_buf *bp, struct xfs_dir2_data_unused *dup);
168extern void xfs_dir2_data_make_free(struct xfs_da_args *args,
169		struct xfs_buf *bp, xfs_dir2_data_aoff_t offset,
170		xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);
171extern void xfs_dir2_data_use_free(struct xfs_da_args *args,
172		struct xfs_buf *bp, struct xfs_dir2_data_unused *dup,
173		xfs_dir2_data_aoff_t offset, xfs_dir2_data_aoff_t len,
174		int *needlogp, int *needscanp);
175
176extern struct xfs_dir2_data_free *xfs_dir2_data_freefind(
177		struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_free *bf,
178		struct xfs_dir2_data_unused *dup);
179
 
 
180extern const struct xfs_buf_ops xfs_dir3_block_buf_ops;
181extern const struct xfs_buf_ops xfs_dir3_leafn_buf_ops;
182extern const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops;
183extern const struct xfs_buf_ops xfs_dir3_free_buf_ops;
184extern const struct xfs_buf_ops xfs_dir3_data_buf_ops;
185
186/*
187 * Directory offset/block conversion functions.
188 *
189 * DB blocks here are logical directory block numbers, not filesystem blocks.
190 */
191
192/*
193 * Convert dataptr to byte in file space
194 */
195static inline xfs_dir2_off_t
196xfs_dir2_dataptr_to_byte(xfs_dir2_dataptr_t dp)
197{
198	return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
199}
200
201/*
202 * Convert byte in file space to dataptr.  It had better be aligned.
203 */
204static inline xfs_dir2_dataptr_t
205xfs_dir2_byte_to_dataptr(xfs_dir2_off_t by)
206{
207	return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
208}
209
210/*
211 * Convert byte in space to (DB) block
212 */
213static inline xfs_dir2_db_t
214xfs_dir2_byte_to_db(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
215{
216	return (xfs_dir2_db_t)(by >> geo->blklog);
217}
218
219/*
220 * Convert dataptr to a block number
221 */
222static inline xfs_dir2_db_t
223xfs_dir2_dataptr_to_db(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
224{
225	return xfs_dir2_byte_to_db(geo, xfs_dir2_dataptr_to_byte(dp));
226}
227
228/*
229 * Convert byte in space to offset in a block
230 */
231static inline xfs_dir2_data_aoff_t
232xfs_dir2_byte_to_off(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
233{
234	return (xfs_dir2_data_aoff_t)(by & (geo->blksize - 1));
235}
236
237/*
238 * Convert dataptr to a byte offset in a block
239 */
240static inline xfs_dir2_data_aoff_t
241xfs_dir2_dataptr_to_off(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
242{
243	return xfs_dir2_byte_to_off(geo, xfs_dir2_dataptr_to_byte(dp));
244}
245
246/*
247 * Convert block and offset to byte in space
248 */
249static inline xfs_dir2_off_t
250xfs_dir2_db_off_to_byte(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
251			xfs_dir2_data_aoff_t o)
252{
253	return ((xfs_dir2_off_t)db << geo->blklog) + o;
254}
255
256/*
257 * Convert block (DB) to block (dablk)
258 */
259static inline xfs_dablk_t
260xfs_dir2_db_to_da(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
261{
262	return (xfs_dablk_t)(db << (geo->blklog - geo->fsblog));
263}
264
265/*
266 * Convert byte in space to (DA) block
267 */
268static inline xfs_dablk_t
269xfs_dir2_byte_to_da(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
270{
271	return xfs_dir2_db_to_da(geo, xfs_dir2_byte_to_db(geo, by));
272}
273
274/*
275 * Convert block and offset to dataptr
276 */
277static inline xfs_dir2_dataptr_t
278xfs_dir2_db_off_to_dataptr(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
279			   xfs_dir2_data_aoff_t o)
280{
281	return xfs_dir2_byte_to_dataptr(xfs_dir2_db_off_to_byte(geo, db, o));
282}
283
284/*
285 * Convert block (dablk) to block (DB)
286 */
287static inline xfs_dir2_db_t
288xfs_dir2_da_to_db(struct xfs_da_geometry *geo, xfs_dablk_t da)
289{
290	return (xfs_dir2_db_t)(da >> (geo->blklog - geo->fsblog));
291}
292
293/*
294 * Convert block (dablk) to byte offset in space
295 */
296static inline xfs_dir2_off_t
297xfs_dir2_da_to_byte(struct xfs_da_geometry *geo, xfs_dablk_t da)
298{
299	return xfs_dir2_db_off_to_byte(geo, xfs_dir2_da_to_db(geo, da), 0);
300}
301
302/*
303 * Directory tail pointer accessor functions. Based on block geometry.
304 */
305static inline struct xfs_dir2_block_tail *
306xfs_dir2_block_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_data_hdr *hdr)
307{
308	return ((struct xfs_dir2_block_tail *)
309		((char *)hdr + geo->blksize)) - 1;
310}
311
312static inline struct xfs_dir2_leaf_tail *
313xfs_dir2_leaf_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_leaf *lp)
314{
315	return (struct xfs_dir2_leaf_tail *)
316		((char *)lp + geo->blksize -
317		  sizeof(struct xfs_dir2_leaf_tail));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318}
319
320#endif	/* __XFS_DIR2_H__ */
v6.8
  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
 12struct xfs_da_args;
 13struct xfs_inode;
 14struct xfs_mount;
 15struct xfs_trans;
 16struct xfs_dir2_sf_hdr;
 17struct xfs_dir2_sf_entry;
 18struct xfs_dir2_data_hdr;
 19struct xfs_dir2_data_entry;
 20struct xfs_dir2_data_unused;
 21struct xfs_dir3_icfree_hdr;
 22struct xfs_dir3_icleaf_hdr;
 23
 24extern const struct xfs_name	xfs_name_dotdot;
 25
 26/*
 27 * Convert inode mode to directory entry filetype
 28 */
 29extern unsigned char xfs_mode_to_ftype(int mode);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 30
 31/*
 32 * Generic directory interface routines
 33 */
 34extern void xfs_dir_startup(void);
 35extern int xfs_da_mount(struct xfs_mount *mp);
 36extern void xfs_da_unmount(struct xfs_mount *mp);
 37
 38extern int xfs_dir_isempty(struct xfs_inode *dp);
 39extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp,
 40				struct xfs_inode *pdp);
 41extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp,
 42				const struct xfs_name *name, xfs_ino_t inum,
 43				xfs_extlen_t tot);
 
 44extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp,
 45				const struct xfs_name *name, xfs_ino_t *inum,
 46				struct xfs_name *ci_name);
 47extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp,
 48				struct xfs_name *name, xfs_ino_t ino,
 49				xfs_extlen_t tot);
 
 50extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
 51				const struct xfs_name *name, xfs_ino_t inum,
 52				xfs_extlen_t tot);
 
 53extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp,
 54				struct xfs_name *name);
 55
 56/*
 57 * Direct call from the bmap code, bypassing the generic directory layer.
 58 */
 59extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
 60
 61/*
 62 * Interface routines used by userspace utilities
 63 */
 64extern int xfs_dir2_isblock(struct xfs_da_args *args, bool *isblock);
 65extern int xfs_dir2_isleaf(struct xfs_da_args *args, bool *isleaf);
 66extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
 67				struct xfs_buf *bp);
 68
 69extern void xfs_dir2_data_freescan(struct xfs_mount *mp,
 70		struct xfs_dir2_data_hdr *hdr, int *loghead);
 71extern void xfs_dir2_data_log_entry(struct xfs_da_args *args,
 72		struct xfs_buf *bp, struct xfs_dir2_data_entry *dep);
 73extern void xfs_dir2_data_log_header(struct xfs_da_args *args,
 74		struct xfs_buf *bp);
 75extern void xfs_dir2_data_log_unused(struct xfs_da_args *args,
 76		struct xfs_buf *bp, struct xfs_dir2_data_unused *dup);
 77extern void xfs_dir2_data_make_free(struct xfs_da_args *args,
 78		struct xfs_buf *bp, xfs_dir2_data_aoff_t offset,
 79		xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);
 80extern int xfs_dir2_data_use_free(struct xfs_da_args *args,
 81		struct xfs_buf *bp, struct xfs_dir2_data_unused *dup,
 82		xfs_dir2_data_aoff_t offset, xfs_dir2_data_aoff_t len,
 83		int *needlogp, int *needscanp);
 84
 85extern struct xfs_dir2_data_free *xfs_dir2_data_freefind(
 86		struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_free *bf,
 87		struct xfs_dir2_data_unused *dup);
 88
 89extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
 90
 91extern const struct xfs_buf_ops xfs_dir3_block_buf_ops;
 92extern const struct xfs_buf_ops xfs_dir3_leafn_buf_ops;
 93extern const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops;
 94extern const struct xfs_buf_ops xfs_dir3_free_buf_ops;
 95extern const struct xfs_buf_ops xfs_dir3_data_buf_ops;
 96
 97/*
 98 * Directory offset/block conversion functions.
 99 *
100 * DB blocks here are logical directory block numbers, not filesystem blocks.
101 */
102
103/*
104 * Convert dataptr to byte in file space
105 */
106static inline xfs_dir2_off_t
107xfs_dir2_dataptr_to_byte(xfs_dir2_dataptr_t dp)
108{
109	return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
110}
111
112/*
113 * Convert byte in file space to dataptr.  It had better be aligned.
114 */
115static inline xfs_dir2_dataptr_t
116xfs_dir2_byte_to_dataptr(xfs_dir2_off_t by)
117{
118	return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
119}
120
121/*
122 * Convert byte in space to (DB) block
123 */
124static inline xfs_dir2_db_t
125xfs_dir2_byte_to_db(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
126{
127	return (xfs_dir2_db_t)(by >> geo->blklog);
128}
129
130/*
131 * Convert dataptr to a block number
132 */
133static inline xfs_dir2_db_t
134xfs_dir2_dataptr_to_db(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
135{
136	return xfs_dir2_byte_to_db(geo, xfs_dir2_dataptr_to_byte(dp));
137}
138
139/*
140 * Convert byte in space to offset in a block
141 */
142static inline xfs_dir2_data_aoff_t
143xfs_dir2_byte_to_off(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
144{
145	return (xfs_dir2_data_aoff_t)(by & (geo->blksize - 1));
146}
147
148/*
149 * Convert dataptr to a byte offset in a block
150 */
151static inline xfs_dir2_data_aoff_t
152xfs_dir2_dataptr_to_off(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
153{
154	return xfs_dir2_byte_to_off(geo, xfs_dir2_dataptr_to_byte(dp));
155}
156
157/*
158 * Convert block and offset to byte in space
159 */
160static inline xfs_dir2_off_t
161xfs_dir2_db_off_to_byte(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
162			xfs_dir2_data_aoff_t o)
163{
164	return ((xfs_dir2_off_t)db << geo->blklog) + o;
165}
166
167/*
168 * Convert block (DB) to block (dablk)
169 */
170static inline xfs_dablk_t
171xfs_dir2_db_to_da(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
172{
173	return (xfs_dablk_t)(db << (geo->blklog - geo->fsblog));
174}
175
176/*
177 * Convert byte in space to (DA) block
178 */
179static inline xfs_dablk_t
180xfs_dir2_byte_to_da(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
181{
182	return xfs_dir2_db_to_da(geo, xfs_dir2_byte_to_db(geo, by));
183}
184
185/*
186 * Convert block and offset to dataptr
187 */
188static inline xfs_dir2_dataptr_t
189xfs_dir2_db_off_to_dataptr(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
190			   xfs_dir2_data_aoff_t o)
191{
192	return xfs_dir2_byte_to_dataptr(xfs_dir2_db_off_to_byte(geo, db, o));
193}
194
195/*
196 * Convert block (dablk) to block (DB)
197 */
198static inline xfs_dir2_db_t
199xfs_dir2_da_to_db(struct xfs_da_geometry *geo, xfs_dablk_t da)
200{
201	return (xfs_dir2_db_t)(da >> (geo->blklog - geo->fsblog));
202}
203
204/*
205 * Convert block (dablk) to byte offset in space
206 */
207static inline xfs_dir2_off_t
208xfs_dir2_da_to_byte(struct xfs_da_geometry *geo, xfs_dablk_t da)
209{
210	return xfs_dir2_db_off_to_byte(geo, xfs_dir2_da_to_db(geo, da), 0);
211}
212
213/*
214 * Directory tail pointer accessor functions. Based on block geometry.
215 */
216static inline struct xfs_dir2_block_tail *
217xfs_dir2_block_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_data_hdr *hdr)
218{
219	return ((struct xfs_dir2_block_tail *)
220		((char *)hdr + geo->blksize)) - 1;
221}
222
223static inline struct xfs_dir2_leaf_tail *
224xfs_dir2_leaf_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_leaf *lp)
225{
226	return (struct xfs_dir2_leaf_tail *)
227		((char *)lp + geo->blksize -
228		  sizeof(struct xfs_dir2_leaf_tail));
229}
230
231/*
232 * The Linux API doesn't pass down the total size of the buffer
233 * we read into down to the filesystem.  With the filldir concept
234 * it's not needed for correct information, but the XFS dir2 leaf
235 * code wants an estimate of the buffer size to calculate it's
236 * readahead window and size the buffers used for mapping to
237 * physical blocks.
238 *
239 * Try to give it an estimate that's good enough, maybe at some
240 * point we can change the ->readdir prototype to include the
241 * buffer size.  For now we use the current glibc buffer size.
242 * musl libc hardcodes 2k and dietlibc uses PAGE_SIZE.
243 */
244#define XFS_READDIR_BUFSIZE	(32768)
245
246unsigned char xfs_dir3_get_dtype(struct xfs_mount *mp, uint8_t filetype);
247unsigned int xfs_dir3_data_end_offset(struct xfs_da_geometry *geo,
248		struct xfs_dir2_data_hdr *hdr);
249bool xfs_dir2_namecheck(const void *name, size_t length);
250
251/*
252 * The "ascii-ci" feature was created to speed up case-insensitive lookups for
253 * a Samba product.  Because of the inherent problems with CI and UTF-8
254 * encoding, etc, it was decided that Samba would be configured to export
255 * latin1/iso 8859-1 encodings as that covered >90% of the target markets for
256 * the product.  Hence the "ascii-ci" casefolding code could be encoded into
257 * the XFS directory operations and remove all the overhead of casefolding from
258 * Samba.
259 *
260 * To provide consistent hashing behavior between the userspace and kernel,
261 * these functions prepare names for hashing by transforming specific bytes
262 * to other bytes.  Robustness with other encodings is not guaranteed.
263 */
264static inline bool xfs_ascii_ci_need_xfrm(unsigned char c)
265{
266	if (c >= 0x41 && c <= 0x5a)	/* A-Z */
267		return true;
268	if (c >= 0xc0 && c <= 0xd6)	/* latin A-O with accents */
269		return true;
270	if (c >= 0xd8 && c <= 0xde)	/* latin O-Y with accents */
271		return true;
272	return false;
273}
274
275static inline unsigned char xfs_ascii_ci_xfrm(unsigned char c)
276{
277	if (xfs_ascii_ci_need_xfrm(c))
278		c -= 'A' - 'a';
279	return c;
280}
281
282#endif	/* __XFS_DIR2_H__ */