1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 21da177e4SLinus Torvalds /* 31da177e4SLinus Torvalds * linux/fs/hfs/btree.h 41da177e4SLinus Torvalds * 51da177e4SLinus Torvalds * Copyright (C) 2001 61da177e4SLinus Torvalds * Brad Boyer (flar@allandria.com) 71da177e4SLinus Torvalds * (C) 2003 Ardis Technologies <roman@ardistech.com> 81da177e4SLinus Torvalds */ 91da177e4SLinus Torvalds 101da177e4SLinus Torvalds #include "hfs_fs.h" 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds typedef int (*btree_keycmp)(const btree_key *, const btree_key *); 131da177e4SLinus Torvalds 141da177e4SLinus Torvalds #define NODE_HASH_SIZE 256 151da177e4SLinus Torvalds 16*b3b2177aSDesmond Cheong Zhi Xi /* B-tree mutex nested subclasses */ 17*b3b2177aSDesmond Cheong Zhi Xi enum hfs_btree_mutex_classes { 18*b3b2177aSDesmond Cheong Zhi Xi CATALOG_BTREE_MUTEX, 19*b3b2177aSDesmond Cheong Zhi Xi EXTENTS_BTREE_MUTEX, 20*b3b2177aSDesmond Cheong Zhi Xi ATTR_BTREE_MUTEX, 21*b3b2177aSDesmond Cheong Zhi Xi }; 22*b3b2177aSDesmond Cheong Zhi Xi 231da177e4SLinus Torvalds /* A HFS BTree held in memory */ 241da177e4SLinus Torvalds struct hfs_btree { 251da177e4SLinus Torvalds struct super_block *sb; 261da177e4SLinus Torvalds struct inode *inode; 271da177e4SLinus Torvalds btree_keycmp keycmp; 281da177e4SLinus Torvalds 291da177e4SLinus Torvalds u32 cnid; 301da177e4SLinus Torvalds u32 root; 311da177e4SLinus Torvalds u32 leaf_count; 321da177e4SLinus Torvalds u32 leaf_head; 331da177e4SLinus Torvalds u32 leaf_tail; 341da177e4SLinus Torvalds u32 node_count; 351da177e4SLinus Torvalds u32 free_nodes; 361da177e4SLinus Torvalds u32 attributes; 371da177e4SLinus Torvalds 381da177e4SLinus Torvalds unsigned int node_size; 391da177e4SLinus Torvalds unsigned int node_size_shift; 401da177e4SLinus Torvalds unsigned int max_key_len; 411da177e4SLinus Torvalds unsigned int depth; 421da177e4SLinus Torvalds 431da177e4SLinus Torvalds //unsigned int map1_size, map_size; 444a941035SThomas Gleixner struct mutex tree_lock; 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds unsigned int pages_per_bnode; 471da177e4SLinus Torvalds spinlock_t hash_lock; 481da177e4SLinus Torvalds struct hfs_bnode *node_hash[NODE_HASH_SIZE]; 491da177e4SLinus Torvalds int node_hash_cnt; 501da177e4SLinus Torvalds }; 511da177e4SLinus Torvalds 521da177e4SLinus Torvalds /* A HFS BTree node in memory */ 531da177e4SLinus Torvalds struct hfs_bnode { 541da177e4SLinus Torvalds struct hfs_btree *tree; 551da177e4SLinus Torvalds 561da177e4SLinus Torvalds u32 prev; 571da177e4SLinus Torvalds u32 this; 581da177e4SLinus Torvalds u32 next; 591da177e4SLinus Torvalds u32 parent; 601da177e4SLinus Torvalds 611da177e4SLinus Torvalds u16 num_recs; 621da177e4SLinus Torvalds u8 type; 631da177e4SLinus Torvalds u8 height; 641da177e4SLinus Torvalds 651da177e4SLinus Torvalds struct hfs_bnode *next_hash; 661da177e4SLinus Torvalds unsigned long flags; 671da177e4SLinus Torvalds wait_queue_head_t lock_wq; 681da177e4SLinus Torvalds atomic_t refcnt; 691da177e4SLinus Torvalds unsigned int page_offset; 705e01fdffSGustavo A. R. Silva struct page *page[]; 711da177e4SLinus Torvalds }; 721da177e4SLinus Torvalds 731da177e4SLinus Torvalds #define HFS_BNODE_ERROR 0 741da177e4SLinus Torvalds #define HFS_BNODE_NEW 1 751da177e4SLinus Torvalds #define HFS_BNODE_DELETED 2 761da177e4SLinus Torvalds 771da177e4SLinus Torvalds struct hfs_find_data { 781da177e4SLinus Torvalds btree_key *key; 791da177e4SLinus Torvalds btree_key *search_key; 801da177e4SLinus Torvalds struct hfs_btree *tree; 811da177e4SLinus Torvalds struct hfs_bnode *bnode; 821da177e4SLinus Torvalds int record; 831da177e4SLinus Torvalds int keyoffset, keylength; 841da177e4SLinus Torvalds int entryoffset, entrylength; 851da177e4SLinus Torvalds }; 861da177e4SLinus Torvalds 871da177e4SLinus Torvalds 881da177e4SLinus Torvalds /* btree.c */ 891da177e4SLinus Torvalds extern struct hfs_btree *hfs_btree_open(struct super_block *, u32, btree_keycmp); 901da177e4SLinus Torvalds extern void hfs_btree_close(struct hfs_btree *); 911da177e4SLinus Torvalds extern void hfs_btree_write(struct hfs_btree *); 9254640c75SErnesto A. Fernández extern int hfs_bmap_reserve(struct hfs_btree *, int); 931da177e4SLinus Torvalds extern struct hfs_bnode * hfs_bmap_alloc(struct hfs_btree *); 941da177e4SLinus Torvalds extern void hfs_bmap_free(struct hfs_bnode *node); 951da177e4SLinus Torvalds 961da177e4SLinus Torvalds /* bnode.c */ 971da177e4SLinus Torvalds extern void hfs_bnode_read(struct hfs_bnode *, void *, int, int); 981da177e4SLinus Torvalds extern u16 hfs_bnode_read_u16(struct hfs_bnode *, int); 991da177e4SLinus Torvalds extern u8 hfs_bnode_read_u8(struct hfs_bnode *, int); 1001da177e4SLinus Torvalds extern void hfs_bnode_read_key(struct hfs_bnode *, void *, int); 1011da177e4SLinus Torvalds extern void hfs_bnode_write(struct hfs_bnode *, void *, int, int); 1021da177e4SLinus Torvalds extern void hfs_bnode_write_u16(struct hfs_bnode *, int, u16); 1031da177e4SLinus Torvalds extern void hfs_bnode_write_u8(struct hfs_bnode *, int, u8); 1041da177e4SLinus Torvalds extern void hfs_bnode_clear(struct hfs_bnode *, int, int); 1051da177e4SLinus Torvalds extern void hfs_bnode_copy(struct hfs_bnode *, int, 1061da177e4SLinus Torvalds struct hfs_bnode *, int, int); 1071da177e4SLinus Torvalds extern void hfs_bnode_move(struct hfs_bnode *, int, int, int); 1081da177e4SLinus Torvalds extern void hfs_bnode_dump(struct hfs_bnode *); 1091da177e4SLinus Torvalds extern void hfs_bnode_unlink(struct hfs_bnode *); 1101da177e4SLinus Torvalds extern struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *, u32); 1111da177e4SLinus Torvalds extern struct hfs_bnode *hfs_bnode_find(struct hfs_btree *, u32); 1121da177e4SLinus Torvalds extern void hfs_bnode_unhash(struct hfs_bnode *); 1131da177e4SLinus Torvalds extern void hfs_bnode_free(struct hfs_bnode *); 1141da177e4SLinus Torvalds extern struct hfs_bnode *hfs_bnode_create(struct hfs_btree *, u32); 1151da177e4SLinus Torvalds extern void hfs_bnode_get(struct hfs_bnode *); 1161da177e4SLinus Torvalds extern void hfs_bnode_put(struct hfs_bnode *); 1171da177e4SLinus Torvalds 1181da177e4SLinus Torvalds /* brec.c */ 1191da177e4SLinus Torvalds extern u16 hfs_brec_lenoff(struct hfs_bnode *, u16, u16 *); 1201da177e4SLinus Torvalds extern u16 hfs_brec_keylen(struct hfs_bnode *, u16); 1211da177e4SLinus Torvalds extern int hfs_brec_insert(struct hfs_find_data *, void *, int); 1221da177e4SLinus Torvalds extern int hfs_brec_remove(struct hfs_find_data *); 1231da177e4SLinus Torvalds 1241da177e4SLinus Torvalds /* bfind.c */ 1251da177e4SLinus Torvalds extern int hfs_find_init(struct hfs_btree *, struct hfs_find_data *); 1261da177e4SLinus Torvalds extern void hfs_find_exit(struct hfs_find_data *); 1271da177e4SLinus Torvalds extern int __hfs_brec_find(struct hfs_bnode *, struct hfs_find_data *); 1281da177e4SLinus Torvalds extern int hfs_brec_find(struct hfs_find_data *); 1291da177e4SLinus Torvalds extern int hfs_brec_read(struct hfs_find_data *, void *, int); 1301da177e4SLinus Torvalds extern int hfs_brec_goto(struct hfs_find_data *, int); 1311da177e4SLinus Torvalds 1321da177e4SLinus Torvalds 1331da177e4SLinus Torvalds struct hfs_bnode_desc { 1341da177e4SLinus Torvalds __be32 next; /* (V) Number of the next node at this level */ 1351da177e4SLinus Torvalds __be32 prev; /* (V) Number of the prev node at this level */ 1361da177e4SLinus Torvalds u8 type; /* (F) The type of node */ 1371da177e4SLinus Torvalds u8 height; /* (F) The level of this node (leaves=1) */ 1381da177e4SLinus Torvalds __be16 num_recs; /* (V) The number of records in this node */ 1391da177e4SLinus Torvalds u16 reserved; 1401da177e4SLinus Torvalds } __packed; 1411da177e4SLinus Torvalds 1421da177e4SLinus Torvalds #define HFS_NODE_INDEX 0x00 /* An internal (index) node */ 1431da177e4SLinus Torvalds #define HFS_NODE_HEADER 0x01 /* The tree header node (node 0) */ 1441da177e4SLinus Torvalds #define HFS_NODE_MAP 0x02 /* Holds part of the bitmap of used nodes */ 1451da177e4SLinus Torvalds #define HFS_NODE_LEAF 0xFF /* A leaf (ndNHeight==1) node */ 1461da177e4SLinus Torvalds 1471da177e4SLinus Torvalds struct hfs_btree_header_rec { 1481da177e4SLinus Torvalds __be16 depth; /* (V) The number of levels in this B-tree */ 1491da177e4SLinus Torvalds __be32 root; /* (V) The node number of the root node */ 1501da177e4SLinus Torvalds __be32 leaf_count; /* (V) The number of leaf records */ 1511da177e4SLinus Torvalds __be32 leaf_head; /* (V) The number of the first leaf node */ 1521da177e4SLinus Torvalds __be32 leaf_tail; /* (V) The number of the last leaf node */ 1531da177e4SLinus Torvalds __be16 node_size; /* (F) The number of bytes in a node (=512) */ 1541da177e4SLinus Torvalds __be16 max_key_len; /* (F) The length of a key in an index node */ 1551da177e4SLinus Torvalds __be32 node_count; /* (V) The total number of nodes */ 1561da177e4SLinus Torvalds __be32 free_nodes; /* (V) The number of unused nodes */ 1571da177e4SLinus Torvalds u16 reserved1; 1581da177e4SLinus Torvalds __be32 clump_size; /* (F) clump size. not usually used. */ 1591da177e4SLinus Torvalds u8 btree_type; /* (F) BTree type */ 1601da177e4SLinus Torvalds u8 reserved2; 1611da177e4SLinus Torvalds __be32 attributes; /* (F) attributes */ 1621da177e4SLinus Torvalds u32 reserved3[16]; 1631da177e4SLinus Torvalds } __packed; 1641da177e4SLinus Torvalds 1651da177e4SLinus Torvalds #define BTREE_ATTR_BADCLOSE 0x00000001 /* b-tree not closed properly. not 1661da177e4SLinus Torvalds used by hfsplus. */ 1671da177e4SLinus Torvalds #define HFS_TREE_BIGKEYS 0x00000002 /* key length is u16 instead of u8. 1681da177e4SLinus Torvalds used by hfsplus. */ 1691da177e4SLinus Torvalds #define HFS_TREE_VARIDXKEYS 0x00000004 /* variable key length instead of 1701da177e4SLinus Torvalds max key length. use din catalog 1711da177e4SLinus Torvalds b-tree but not in extents 1721da177e4SLinus Torvalds b-tree (hfsplus). */ 173