1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * linux/fs/hfs/btree.h 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (C) 2001 6*4882a593Smuzhiyun * Brad Boyer (flar@allandria.com) 7*4882a593Smuzhiyun * (C) 2003 Ardis Technologies <roman@ardistech.com> 8*4882a593Smuzhiyun */ 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #include "hfs_fs.h" 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun typedef int (*btree_keycmp)(const btree_key *, const btree_key *); 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #define NODE_HASH_SIZE 256 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun /* B-tree mutex nested subclasses */ 17*4882a593Smuzhiyun enum hfs_btree_mutex_classes { 18*4882a593Smuzhiyun CATALOG_BTREE_MUTEX, 19*4882a593Smuzhiyun EXTENTS_BTREE_MUTEX, 20*4882a593Smuzhiyun ATTR_BTREE_MUTEX, 21*4882a593Smuzhiyun }; 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun /* A HFS BTree held in memory */ 24*4882a593Smuzhiyun struct hfs_btree { 25*4882a593Smuzhiyun struct super_block *sb; 26*4882a593Smuzhiyun struct inode *inode; 27*4882a593Smuzhiyun btree_keycmp keycmp; 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun u32 cnid; 30*4882a593Smuzhiyun u32 root; 31*4882a593Smuzhiyun u32 leaf_count; 32*4882a593Smuzhiyun u32 leaf_head; 33*4882a593Smuzhiyun u32 leaf_tail; 34*4882a593Smuzhiyun u32 node_count; 35*4882a593Smuzhiyun u32 free_nodes; 36*4882a593Smuzhiyun u32 attributes; 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun unsigned int node_size; 39*4882a593Smuzhiyun unsigned int node_size_shift; 40*4882a593Smuzhiyun unsigned int max_key_len; 41*4882a593Smuzhiyun unsigned int depth; 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun //unsigned int map1_size, map_size; 44*4882a593Smuzhiyun struct mutex tree_lock; 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun unsigned int pages_per_bnode; 47*4882a593Smuzhiyun spinlock_t hash_lock; 48*4882a593Smuzhiyun struct hfs_bnode *node_hash[NODE_HASH_SIZE]; 49*4882a593Smuzhiyun int node_hash_cnt; 50*4882a593Smuzhiyun }; 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun /* A HFS BTree node in memory */ 53*4882a593Smuzhiyun struct hfs_bnode { 54*4882a593Smuzhiyun struct hfs_btree *tree; 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun u32 prev; 57*4882a593Smuzhiyun u32 this; 58*4882a593Smuzhiyun u32 next; 59*4882a593Smuzhiyun u32 parent; 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun u16 num_recs; 62*4882a593Smuzhiyun u8 type; 63*4882a593Smuzhiyun u8 height; 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun struct hfs_bnode *next_hash; 66*4882a593Smuzhiyun unsigned long flags; 67*4882a593Smuzhiyun wait_queue_head_t lock_wq; 68*4882a593Smuzhiyun atomic_t refcnt; 69*4882a593Smuzhiyun unsigned int page_offset; 70*4882a593Smuzhiyun struct page *page[]; 71*4882a593Smuzhiyun }; 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun #define HFS_BNODE_ERROR 0 74*4882a593Smuzhiyun #define HFS_BNODE_NEW 1 75*4882a593Smuzhiyun #define HFS_BNODE_DELETED 2 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun struct hfs_find_data { 78*4882a593Smuzhiyun btree_key *key; 79*4882a593Smuzhiyun btree_key *search_key; 80*4882a593Smuzhiyun struct hfs_btree *tree; 81*4882a593Smuzhiyun struct hfs_bnode *bnode; 82*4882a593Smuzhiyun int record; 83*4882a593Smuzhiyun int keyoffset, keylength; 84*4882a593Smuzhiyun int entryoffset, entrylength; 85*4882a593Smuzhiyun }; 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun /* btree.c */ 89*4882a593Smuzhiyun extern struct hfs_btree *hfs_btree_open(struct super_block *, u32, btree_keycmp); 90*4882a593Smuzhiyun extern void hfs_btree_close(struct hfs_btree *); 91*4882a593Smuzhiyun extern void hfs_btree_write(struct hfs_btree *); 92*4882a593Smuzhiyun extern int hfs_bmap_reserve(struct hfs_btree *, int); 93*4882a593Smuzhiyun extern struct hfs_bnode * hfs_bmap_alloc(struct hfs_btree *); 94*4882a593Smuzhiyun extern void hfs_bmap_free(struct hfs_bnode *node); 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun /* bnode.c */ 97*4882a593Smuzhiyun extern void hfs_bnode_read(struct hfs_bnode *, void *, int, int); 98*4882a593Smuzhiyun extern u16 hfs_bnode_read_u16(struct hfs_bnode *, int); 99*4882a593Smuzhiyun extern u8 hfs_bnode_read_u8(struct hfs_bnode *, int); 100*4882a593Smuzhiyun extern void hfs_bnode_read_key(struct hfs_bnode *, void *, int); 101*4882a593Smuzhiyun extern void hfs_bnode_write(struct hfs_bnode *, void *, int, int); 102*4882a593Smuzhiyun extern void hfs_bnode_write_u16(struct hfs_bnode *, int, u16); 103*4882a593Smuzhiyun extern void hfs_bnode_write_u8(struct hfs_bnode *, int, u8); 104*4882a593Smuzhiyun extern void hfs_bnode_clear(struct hfs_bnode *, int, int); 105*4882a593Smuzhiyun extern void hfs_bnode_copy(struct hfs_bnode *, int, 106*4882a593Smuzhiyun struct hfs_bnode *, int, int); 107*4882a593Smuzhiyun extern void hfs_bnode_move(struct hfs_bnode *, int, int, int); 108*4882a593Smuzhiyun extern void hfs_bnode_dump(struct hfs_bnode *); 109*4882a593Smuzhiyun extern void hfs_bnode_unlink(struct hfs_bnode *); 110*4882a593Smuzhiyun extern struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *, u32); 111*4882a593Smuzhiyun extern struct hfs_bnode *hfs_bnode_find(struct hfs_btree *, u32); 112*4882a593Smuzhiyun extern void hfs_bnode_unhash(struct hfs_bnode *); 113*4882a593Smuzhiyun extern void hfs_bnode_free(struct hfs_bnode *); 114*4882a593Smuzhiyun extern struct hfs_bnode *hfs_bnode_create(struct hfs_btree *, u32); 115*4882a593Smuzhiyun extern void hfs_bnode_get(struct hfs_bnode *); 116*4882a593Smuzhiyun extern void hfs_bnode_put(struct hfs_bnode *); 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun /* brec.c */ 119*4882a593Smuzhiyun extern u16 hfs_brec_lenoff(struct hfs_bnode *, u16, u16 *); 120*4882a593Smuzhiyun extern u16 hfs_brec_keylen(struct hfs_bnode *, u16); 121*4882a593Smuzhiyun extern int hfs_brec_insert(struct hfs_find_data *, void *, int); 122*4882a593Smuzhiyun extern int hfs_brec_remove(struct hfs_find_data *); 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun /* bfind.c */ 125*4882a593Smuzhiyun extern int hfs_find_init(struct hfs_btree *, struct hfs_find_data *); 126*4882a593Smuzhiyun extern void hfs_find_exit(struct hfs_find_data *); 127*4882a593Smuzhiyun extern int __hfs_brec_find(struct hfs_bnode *, struct hfs_find_data *); 128*4882a593Smuzhiyun extern int hfs_brec_find(struct hfs_find_data *); 129*4882a593Smuzhiyun extern int hfs_brec_read(struct hfs_find_data *, void *, int); 130*4882a593Smuzhiyun extern int hfs_brec_goto(struct hfs_find_data *, int); 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun struct hfs_bnode_desc { 134*4882a593Smuzhiyun __be32 next; /* (V) Number of the next node at this level */ 135*4882a593Smuzhiyun __be32 prev; /* (V) Number of the prev node at this level */ 136*4882a593Smuzhiyun u8 type; /* (F) The type of node */ 137*4882a593Smuzhiyun u8 height; /* (F) The level of this node (leaves=1) */ 138*4882a593Smuzhiyun __be16 num_recs; /* (V) The number of records in this node */ 139*4882a593Smuzhiyun u16 reserved; 140*4882a593Smuzhiyun } __packed; 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun #define HFS_NODE_INDEX 0x00 /* An internal (index) node */ 143*4882a593Smuzhiyun #define HFS_NODE_HEADER 0x01 /* The tree header node (node 0) */ 144*4882a593Smuzhiyun #define HFS_NODE_MAP 0x02 /* Holds part of the bitmap of used nodes */ 145*4882a593Smuzhiyun #define HFS_NODE_LEAF 0xFF /* A leaf (ndNHeight==1) node */ 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun struct hfs_btree_header_rec { 148*4882a593Smuzhiyun __be16 depth; /* (V) The number of levels in this B-tree */ 149*4882a593Smuzhiyun __be32 root; /* (V) The node number of the root node */ 150*4882a593Smuzhiyun __be32 leaf_count; /* (V) The number of leaf records */ 151*4882a593Smuzhiyun __be32 leaf_head; /* (V) The number of the first leaf node */ 152*4882a593Smuzhiyun __be32 leaf_tail; /* (V) The number of the last leaf node */ 153*4882a593Smuzhiyun __be16 node_size; /* (F) The number of bytes in a node (=512) */ 154*4882a593Smuzhiyun __be16 max_key_len; /* (F) The length of a key in an index node */ 155*4882a593Smuzhiyun __be32 node_count; /* (V) The total number of nodes */ 156*4882a593Smuzhiyun __be32 free_nodes; /* (V) The number of unused nodes */ 157*4882a593Smuzhiyun u16 reserved1; 158*4882a593Smuzhiyun __be32 clump_size; /* (F) clump size. not usually used. */ 159*4882a593Smuzhiyun u8 btree_type; /* (F) BTree type */ 160*4882a593Smuzhiyun u8 reserved2; 161*4882a593Smuzhiyun __be32 attributes; /* (F) attributes */ 162*4882a593Smuzhiyun u32 reserved3[16]; 163*4882a593Smuzhiyun } __packed; 164*4882a593Smuzhiyun 165*4882a593Smuzhiyun #define BTREE_ATTR_BADCLOSE 0x00000001 /* b-tree not closed properly. not 166*4882a593Smuzhiyun used by hfsplus. */ 167*4882a593Smuzhiyun #define HFS_TREE_BIGKEYS 0x00000002 /* key length is u16 instead of u8. 168*4882a593Smuzhiyun used by hfsplus. */ 169*4882a593Smuzhiyun #define HFS_TREE_VARIDXKEYS 0x00000004 /* variable key length instead of 170*4882a593Smuzhiyun max key length. use din catalog 171*4882a593Smuzhiyun b-tree but not in extents 172*4882a593Smuzhiyun b-tree (hfsplus). */ 173