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