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