18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc. 48c2ecf20Sopenharmony_ci * Copyright (c) 2013 Red Hat, Inc. 58c2ecf20Sopenharmony_ci * All Rights Reserved. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#ifndef __XFS_DA_BTREE_H__ 88c2ecf20Sopenharmony_ci#define __XFS_DA_BTREE_H__ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_cistruct xfs_inode; 118c2ecf20Sopenharmony_cistruct xfs_trans; 128c2ecf20Sopenharmony_cistruct zone; 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci/* 158c2ecf20Sopenharmony_ci * Directory/attribute geometry information. There will be one of these for each 168c2ecf20Sopenharmony_ci * data fork type, and it will be passed around via the xfs_da_args. Global 178c2ecf20Sopenharmony_ci * structures will be attached to the xfs_mount. 188c2ecf20Sopenharmony_ci */ 198c2ecf20Sopenharmony_cistruct xfs_da_geometry { 208c2ecf20Sopenharmony_ci unsigned int blksize; /* da block size in bytes */ 218c2ecf20Sopenharmony_ci unsigned int fsbcount; /* da block size in filesystem blocks */ 228c2ecf20Sopenharmony_ci uint8_t fsblog; /* log2 of _filesystem_ block size */ 238c2ecf20Sopenharmony_ci uint8_t blklog; /* log2 of da block size */ 248c2ecf20Sopenharmony_ci unsigned int node_hdr_size; /* danode header size in bytes */ 258c2ecf20Sopenharmony_ci unsigned int node_ents; /* # of entries in a danode */ 268c2ecf20Sopenharmony_ci unsigned int magicpct; /* 37% of block size in bytes */ 278c2ecf20Sopenharmony_ci xfs_dablk_t datablk; /* blockno of dir data v2 */ 288c2ecf20Sopenharmony_ci unsigned int leaf_hdr_size; /* dir2 leaf header size */ 298c2ecf20Sopenharmony_ci unsigned int leaf_max_ents; /* # of entries in dir2 leaf */ 308c2ecf20Sopenharmony_ci xfs_dablk_t leafblk; /* blockno of leaf data v2 */ 318c2ecf20Sopenharmony_ci unsigned int free_hdr_size; /* dir2 free header size */ 328c2ecf20Sopenharmony_ci unsigned int free_max_bests; /* # of bests entries in dir2 free */ 338c2ecf20Sopenharmony_ci xfs_dablk_t freeblk; /* blockno of free data v2 */ 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci xfs_dir2_data_aoff_t data_first_offset; 368c2ecf20Sopenharmony_ci size_t data_entry_offset; 378c2ecf20Sopenharmony_ci}; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci/*======================================================================== 408c2ecf20Sopenharmony_ci * Btree searching and modification structure definitions. 418c2ecf20Sopenharmony_ci *========================================================================*/ 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci/* 448c2ecf20Sopenharmony_ci * Search comparison results 458c2ecf20Sopenharmony_ci */ 468c2ecf20Sopenharmony_cienum xfs_dacmp { 478c2ecf20Sopenharmony_ci XFS_CMP_DIFFERENT, /* names are completely different */ 488c2ecf20Sopenharmony_ci XFS_CMP_EXACT, /* names are exactly the same */ 498c2ecf20Sopenharmony_ci XFS_CMP_CASE /* names are same but differ in case */ 508c2ecf20Sopenharmony_ci}; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci/* 538c2ecf20Sopenharmony_ci * Structure to ease passing around component names. 548c2ecf20Sopenharmony_ci */ 558c2ecf20Sopenharmony_citypedef struct xfs_da_args { 568c2ecf20Sopenharmony_ci struct xfs_da_geometry *geo; /* da block geometry */ 578c2ecf20Sopenharmony_ci const uint8_t *name; /* string (maybe not NULL terminated) */ 588c2ecf20Sopenharmony_ci int namelen; /* length of string (maybe no NULL) */ 598c2ecf20Sopenharmony_ci uint8_t filetype; /* filetype of inode for directories */ 608c2ecf20Sopenharmony_ci void *value; /* set of bytes (maybe contain NULLs) */ 618c2ecf20Sopenharmony_ci int valuelen; /* length of value */ 628c2ecf20Sopenharmony_ci unsigned int attr_filter; /* XFS_ATTR_{ROOT,SECURE,INCOMPLETE} */ 638c2ecf20Sopenharmony_ci unsigned int attr_flags; /* XATTR_{CREATE,REPLACE} */ 648c2ecf20Sopenharmony_ci xfs_dahash_t hashval; /* hash value of name */ 658c2ecf20Sopenharmony_ci xfs_ino_t inumber; /* input/output inode number */ 668c2ecf20Sopenharmony_ci struct xfs_inode *dp; /* directory inode to manipulate */ 678c2ecf20Sopenharmony_ci struct xfs_trans *trans; /* current trans (changes over time) */ 688c2ecf20Sopenharmony_ci xfs_extlen_t total; /* total blocks needed, for 1st bmap */ 698c2ecf20Sopenharmony_ci int whichfork; /* data or attribute fork */ 708c2ecf20Sopenharmony_ci xfs_dablk_t blkno; /* blkno of attr leaf of interest */ 718c2ecf20Sopenharmony_ci int index; /* index of attr of interest in blk */ 728c2ecf20Sopenharmony_ci xfs_dablk_t rmtblkno; /* remote attr value starting blkno */ 738c2ecf20Sopenharmony_ci int rmtblkcnt; /* remote attr value block count */ 748c2ecf20Sopenharmony_ci int rmtvaluelen; /* remote attr value length in bytes */ 758c2ecf20Sopenharmony_ci xfs_dablk_t blkno2; /* blkno of 2nd attr leaf of interest */ 768c2ecf20Sopenharmony_ci int index2; /* index of 2nd attr in blk */ 778c2ecf20Sopenharmony_ci xfs_dablk_t rmtblkno2; /* remote attr value starting blkno */ 788c2ecf20Sopenharmony_ci int rmtblkcnt2; /* remote attr value block count */ 798c2ecf20Sopenharmony_ci int rmtvaluelen2; /* remote attr value length in bytes */ 808c2ecf20Sopenharmony_ci int op_flags; /* operation flags */ 818c2ecf20Sopenharmony_ci enum xfs_dacmp cmpresult; /* name compare result for lookups */ 828c2ecf20Sopenharmony_ci} xfs_da_args_t; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci/* 858c2ecf20Sopenharmony_ci * Operation flags: 868c2ecf20Sopenharmony_ci */ 878c2ecf20Sopenharmony_ci#define XFS_DA_OP_JUSTCHECK 0x0001 /* check for ok with no space */ 888c2ecf20Sopenharmony_ci#define XFS_DA_OP_RENAME 0x0002 /* this is an atomic rename op */ 898c2ecf20Sopenharmony_ci#define XFS_DA_OP_ADDNAME 0x0004 /* this is an add operation */ 908c2ecf20Sopenharmony_ci#define XFS_DA_OP_OKNOENT 0x0008 /* lookup/add op, ENOENT ok, else die */ 918c2ecf20Sopenharmony_ci#define XFS_DA_OP_CILOOKUP 0x0010 /* lookup to return CI name if found */ 928c2ecf20Sopenharmony_ci#define XFS_DA_OP_NOTIME 0x0020 /* don't update inode timestamps */ 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci#define XFS_DA_OP_FLAGS \ 958c2ecf20Sopenharmony_ci { XFS_DA_OP_JUSTCHECK, "JUSTCHECK" }, \ 968c2ecf20Sopenharmony_ci { XFS_DA_OP_RENAME, "RENAME" }, \ 978c2ecf20Sopenharmony_ci { XFS_DA_OP_ADDNAME, "ADDNAME" }, \ 988c2ecf20Sopenharmony_ci { XFS_DA_OP_OKNOENT, "OKNOENT" }, \ 998c2ecf20Sopenharmony_ci { XFS_DA_OP_CILOOKUP, "CILOOKUP" }, \ 1008c2ecf20Sopenharmony_ci { XFS_DA_OP_NOTIME, "NOTIME" } 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci/* 1038c2ecf20Sopenharmony_ci * Storage for holding state during Btree searches and split/join ops. 1048c2ecf20Sopenharmony_ci * 1058c2ecf20Sopenharmony_ci * Only need space for 5 intermediate nodes. With a minimum of 62-way 1068c2ecf20Sopenharmony_ci * fanout to the Btree, we can support over 900 million directory blocks, 1078c2ecf20Sopenharmony_ci * which is slightly more than enough. 1088c2ecf20Sopenharmony_ci */ 1098c2ecf20Sopenharmony_citypedef struct xfs_da_state_blk { 1108c2ecf20Sopenharmony_ci struct xfs_buf *bp; /* buffer containing block */ 1118c2ecf20Sopenharmony_ci xfs_dablk_t blkno; /* filesystem blkno of buffer */ 1128c2ecf20Sopenharmony_ci xfs_daddr_t disk_blkno; /* on-disk blkno (in BBs) of buffer */ 1138c2ecf20Sopenharmony_ci int index; /* relevant index into block */ 1148c2ecf20Sopenharmony_ci xfs_dahash_t hashval; /* last hash value in block */ 1158c2ecf20Sopenharmony_ci int magic; /* blk's magic number, ie: blk type */ 1168c2ecf20Sopenharmony_ci} xfs_da_state_blk_t; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_citypedef struct xfs_da_state_path { 1198c2ecf20Sopenharmony_ci int active; /* number of active levels */ 1208c2ecf20Sopenharmony_ci xfs_da_state_blk_t blk[XFS_DA_NODE_MAXDEPTH]; 1218c2ecf20Sopenharmony_ci} xfs_da_state_path_t; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_citypedef struct xfs_da_state { 1248c2ecf20Sopenharmony_ci xfs_da_args_t *args; /* filename arguments */ 1258c2ecf20Sopenharmony_ci struct xfs_mount *mp; /* filesystem mount point */ 1268c2ecf20Sopenharmony_ci xfs_da_state_path_t path; /* search/split paths */ 1278c2ecf20Sopenharmony_ci xfs_da_state_path_t altpath; /* alternate path for join */ 1288c2ecf20Sopenharmony_ci unsigned char inleaf; /* insert into 1->lf, 0->splf */ 1298c2ecf20Sopenharmony_ci unsigned char extravalid; /* T/F: extrablk is in use */ 1308c2ecf20Sopenharmony_ci unsigned char extraafter; /* T/F: extrablk is after new */ 1318c2ecf20Sopenharmony_ci xfs_da_state_blk_t extrablk; /* for double-splits on leaves */ 1328c2ecf20Sopenharmony_ci /* for dirv2 extrablk is data */ 1338c2ecf20Sopenharmony_ci} xfs_da_state_t; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci/* 1368c2ecf20Sopenharmony_ci * In-core version of the node header to abstract the differences in the v2 and 1378c2ecf20Sopenharmony_ci * v3 disk format of the headers. Callers need to convert to/from disk format as 1388c2ecf20Sopenharmony_ci * appropriate. 1398c2ecf20Sopenharmony_ci */ 1408c2ecf20Sopenharmony_cistruct xfs_da3_icnode_hdr { 1418c2ecf20Sopenharmony_ci uint32_t forw; 1428c2ecf20Sopenharmony_ci uint32_t back; 1438c2ecf20Sopenharmony_ci uint16_t magic; 1448c2ecf20Sopenharmony_ci uint16_t count; 1458c2ecf20Sopenharmony_ci uint16_t level; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci /* 1488c2ecf20Sopenharmony_ci * Pointer to the on-disk format entries, which are behind the 1498c2ecf20Sopenharmony_ci * variable size (v4 vs v5) header in the on-disk block. 1508c2ecf20Sopenharmony_ci */ 1518c2ecf20Sopenharmony_ci struct xfs_da_node_entry *btree; 1528c2ecf20Sopenharmony_ci}; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci/* 1558c2ecf20Sopenharmony_ci * Utility macros to aid in logging changed structure fields. 1568c2ecf20Sopenharmony_ci */ 1578c2ecf20Sopenharmony_ci#define XFS_DA_LOGOFF(BASE, ADDR) ((char *)(ADDR) - (char *)(BASE)) 1588c2ecf20Sopenharmony_ci#define XFS_DA_LOGRANGE(BASE, ADDR, SIZE) \ 1598c2ecf20Sopenharmony_ci (uint)(XFS_DA_LOGOFF(BASE, ADDR)), \ 1608c2ecf20Sopenharmony_ci (uint)(XFS_DA_LOGOFF(BASE, ADDR)+(SIZE)-1) 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci/*======================================================================== 1638c2ecf20Sopenharmony_ci * Function prototypes. 1648c2ecf20Sopenharmony_ci *========================================================================*/ 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci/* 1678c2ecf20Sopenharmony_ci * Routines used for growing the Btree. 1688c2ecf20Sopenharmony_ci */ 1698c2ecf20Sopenharmony_ciint xfs_da3_node_create(struct xfs_da_args *args, xfs_dablk_t blkno, 1708c2ecf20Sopenharmony_ci int level, struct xfs_buf **bpp, int whichfork); 1718c2ecf20Sopenharmony_ciint xfs_da3_split(xfs_da_state_t *state); 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci/* 1748c2ecf20Sopenharmony_ci * Routines used for shrinking the Btree. 1758c2ecf20Sopenharmony_ci */ 1768c2ecf20Sopenharmony_ciint xfs_da3_join(xfs_da_state_t *state); 1778c2ecf20Sopenharmony_civoid xfs_da3_fixhashpath(struct xfs_da_state *state, 1788c2ecf20Sopenharmony_ci struct xfs_da_state_path *path_to_to_fix); 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci/* 1818c2ecf20Sopenharmony_ci * Routines used for finding things in the Btree. 1828c2ecf20Sopenharmony_ci */ 1838c2ecf20Sopenharmony_ciint xfs_da3_node_lookup_int(xfs_da_state_t *state, int *result); 1848c2ecf20Sopenharmony_ciint xfs_da3_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, 1858c2ecf20Sopenharmony_ci int forward, int release, int *result); 1868c2ecf20Sopenharmony_ci/* 1878c2ecf20Sopenharmony_ci * Utility routines. 1888c2ecf20Sopenharmony_ci */ 1898c2ecf20Sopenharmony_ciint xfs_da3_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, 1908c2ecf20Sopenharmony_ci xfs_da_state_blk_t *new_blk); 1918c2ecf20Sopenharmony_ciint xfs_da3_node_read(struct xfs_trans *tp, struct xfs_inode *dp, 1928c2ecf20Sopenharmony_ci xfs_dablk_t bno, struct xfs_buf **bpp, int whichfork); 1938c2ecf20Sopenharmony_ciint xfs_da3_node_read_mapped(struct xfs_trans *tp, struct xfs_inode *dp, 1948c2ecf20Sopenharmony_ci xfs_daddr_t mappedbno, struct xfs_buf **bpp, 1958c2ecf20Sopenharmony_ci int whichfork); 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci/* 1988c2ecf20Sopenharmony_ci * Utility routines. 1998c2ecf20Sopenharmony_ci */ 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci#define XFS_DABUF_MAP_HOLE_OK (1 << 0) 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ciint xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno); 2048c2ecf20Sopenharmony_ciint xfs_da_grow_inode_int(struct xfs_da_args *args, xfs_fileoff_t *bno, 2058c2ecf20Sopenharmony_ci int count); 2068c2ecf20Sopenharmony_ciint xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp, 2078c2ecf20Sopenharmony_ci xfs_dablk_t bno, struct xfs_buf **bp, int whichfork); 2088c2ecf20Sopenharmony_ciint xfs_da_read_buf(struct xfs_trans *trans, struct xfs_inode *dp, 2098c2ecf20Sopenharmony_ci xfs_dablk_t bno, unsigned int flags, struct xfs_buf **bpp, 2108c2ecf20Sopenharmony_ci int whichfork, const struct xfs_buf_ops *ops); 2118c2ecf20Sopenharmony_ciint xfs_da_reada_buf(struct xfs_inode *dp, xfs_dablk_t bno, 2128c2ecf20Sopenharmony_ci unsigned int flags, int whichfork, 2138c2ecf20Sopenharmony_ci const struct xfs_buf_ops *ops); 2148c2ecf20Sopenharmony_ciint xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, 2158c2ecf20Sopenharmony_ci struct xfs_buf *dead_buf); 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ciuint xfs_da_hashname(const uint8_t *name_string, int name_length); 2188c2ecf20Sopenharmony_cienum xfs_dacmp xfs_da_compname(struct xfs_da_args *args, 2198c2ecf20Sopenharmony_ci const unsigned char *name, int len); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_cistruct xfs_da_state *xfs_da_state_alloc(struct xfs_da_args *args); 2238c2ecf20Sopenharmony_civoid xfs_da_state_free(xfs_da_state_t *state); 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_civoid xfs_da3_node_hdr_from_disk(struct xfs_mount *mp, 2268c2ecf20Sopenharmony_ci struct xfs_da3_icnode_hdr *to, struct xfs_da_intnode *from); 2278c2ecf20Sopenharmony_civoid xfs_da3_node_hdr_to_disk(struct xfs_mount *mp, 2288c2ecf20Sopenharmony_ci struct xfs_da_intnode *to, struct xfs_da3_icnode_hdr *from); 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ciextern struct kmem_zone *xfs_da_state_zone; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci#endif /* __XFS_DA_BTREE_H__ */ 233