162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) International Business Machines Corp., 2000-2004 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci#ifndef _H_JFS_BTREE 662306a36Sopenharmony_ci#define _H_JFS_BTREE 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci/* 962306a36Sopenharmony_ci * jfs_btree.h: B+-tree 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * JFS B+-tree (dtree and xtree) common definitions 1262306a36Sopenharmony_ci */ 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci/* 1562306a36Sopenharmony_ci * basic btree page - btpage 1662306a36Sopenharmony_ci * 1762306a36Sopenharmony_cistruct btpage { 1862306a36Sopenharmony_ci s64 next; right sibling bn 1962306a36Sopenharmony_ci s64 prev; left sibling bn 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci u8 flag; 2262306a36Sopenharmony_ci u8 rsrvd[7]; type specific 2362306a36Sopenharmony_ci s64 self; self address 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci u8 entry[4064]; 2662306a36Sopenharmony_ci}; */ 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci/* btpaget_t flag */ 2962306a36Sopenharmony_ci#define BT_TYPE 0x07 /* B+-tree index */ 3062306a36Sopenharmony_ci#define BT_ROOT 0x01 /* root page */ 3162306a36Sopenharmony_ci#define BT_LEAF 0x02 /* leaf page */ 3262306a36Sopenharmony_ci#define BT_INTERNAL 0x04 /* internal page */ 3362306a36Sopenharmony_ci#define BT_RIGHTMOST 0x10 /* rightmost page */ 3462306a36Sopenharmony_ci#define BT_LEFTMOST 0x20 /* leftmost page */ 3562306a36Sopenharmony_ci#define BT_SWAPPED 0x80 /* used by fsck for endian swapping */ 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/* btorder (in inode) */ 3862306a36Sopenharmony_ci#define BT_RANDOM 0x0000 3962306a36Sopenharmony_ci#define BT_SEQUENTIAL 0x0001 4062306a36Sopenharmony_ci#define BT_LOOKUP 0x0010 4162306a36Sopenharmony_ci#define BT_INSERT 0x0020 4262306a36Sopenharmony_ci#define BT_DELETE 0x0040 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/* 4562306a36Sopenharmony_ci * btree page buffer cache access 4662306a36Sopenharmony_ci */ 4762306a36Sopenharmony_ci#define BT_IS_ROOT(MP) (((MP)->xflag & COMMIT_PAGE) == 0) 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci/* get page from buffer page */ 5062306a36Sopenharmony_ci#define BT_PAGE(IP, MP, TYPE, ROOT)\ 5162306a36Sopenharmony_ci (BT_IS_ROOT(MP) ? (TYPE *)&JFS_IP(IP)->ROOT : (TYPE *)(MP)->data) 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/* get the page buffer and the page for specified block address */ 5462306a36Sopenharmony_ci#define BT_GETPAGE(IP, BN, MP, TYPE, SIZE, P, RC, ROOT)\ 5562306a36Sopenharmony_ci{\ 5662306a36Sopenharmony_ci if ((BN) == 0)\ 5762306a36Sopenharmony_ci {\ 5862306a36Sopenharmony_ci MP = (struct metapage *)&JFS_IP(IP)->bxflag;\ 5962306a36Sopenharmony_ci P = (TYPE *)&JFS_IP(IP)->ROOT;\ 6062306a36Sopenharmony_ci RC = 0;\ 6162306a36Sopenharmony_ci }\ 6262306a36Sopenharmony_ci else\ 6362306a36Sopenharmony_ci {\ 6462306a36Sopenharmony_ci MP = read_metapage((IP), BN, SIZE, 1);\ 6562306a36Sopenharmony_ci if (MP) {\ 6662306a36Sopenharmony_ci RC = 0;\ 6762306a36Sopenharmony_ci P = (MP)->data;\ 6862306a36Sopenharmony_ci } else {\ 6962306a36Sopenharmony_ci P = NULL;\ 7062306a36Sopenharmony_ci jfs_err("bread failed!");\ 7162306a36Sopenharmony_ci RC = -EIO;\ 7262306a36Sopenharmony_ci }\ 7362306a36Sopenharmony_ci }\ 7462306a36Sopenharmony_ci} 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci#define BT_MARK_DIRTY(MP, IP)\ 7762306a36Sopenharmony_ci{\ 7862306a36Sopenharmony_ci if (BT_IS_ROOT(MP))\ 7962306a36Sopenharmony_ci mark_inode_dirty(IP);\ 8062306a36Sopenharmony_ci else\ 8162306a36Sopenharmony_ci mark_metapage_dirty(MP);\ 8262306a36Sopenharmony_ci} 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci/* put the page buffer */ 8562306a36Sopenharmony_ci#define BT_PUTPAGE(MP)\ 8662306a36Sopenharmony_ci{\ 8762306a36Sopenharmony_ci if (! BT_IS_ROOT(MP)) \ 8862306a36Sopenharmony_ci release_metapage(MP); \ 8962306a36Sopenharmony_ci} 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci/* 9362306a36Sopenharmony_ci * btree traversal stack 9462306a36Sopenharmony_ci * 9562306a36Sopenharmony_ci * record the path traversed during the search; 9662306a36Sopenharmony_ci * top frame record the leaf page/entry selected. 9762306a36Sopenharmony_ci */ 9862306a36Sopenharmony_cistruct btframe { /* stack frame */ 9962306a36Sopenharmony_ci s64 bn; /* 8: */ 10062306a36Sopenharmony_ci s16 index; /* 2: */ 10162306a36Sopenharmony_ci s16 lastindex; /* 2: unused */ 10262306a36Sopenharmony_ci struct metapage *mp; /* 4/8: */ 10362306a36Sopenharmony_ci}; /* (16/24) */ 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cistruct btstack { 10662306a36Sopenharmony_ci struct btframe *top; 10762306a36Sopenharmony_ci int nsplit; 10862306a36Sopenharmony_ci struct btframe stack[MAXTREEHEIGHT]; 10962306a36Sopenharmony_ci}; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci#define BT_CLR(btstack)\ 11262306a36Sopenharmony_ci (btstack)->top = (btstack)->stack 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci#define BT_STACK_FULL(btstack)\ 11562306a36Sopenharmony_ci ( (btstack)->top == &((btstack)->stack[MAXTREEHEIGHT-1])) 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci#define BT_PUSH(BTSTACK, BN, INDEX)\ 11862306a36Sopenharmony_ci{\ 11962306a36Sopenharmony_ci assert(!BT_STACK_FULL(BTSTACK));\ 12062306a36Sopenharmony_ci (BTSTACK)->top->bn = BN;\ 12162306a36Sopenharmony_ci (BTSTACK)->top->index = INDEX;\ 12262306a36Sopenharmony_ci ++(BTSTACK)->top;\ 12362306a36Sopenharmony_ci} 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci#define BT_POP(btstack)\ 12662306a36Sopenharmony_ci ( (btstack)->top == (btstack)->stack ? NULL : --(btstack)->top ) 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci#define BT_STACK(btstack)\ 12962306a36Sopenharmony_ci ( (btstack)->top == (btstack)->stack ? NULL : (btstack)->top ) 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_cistatic inline void BT_STACK_DUMP(struct btstack *btstack) 13262306a36Sopenharmony_ci{ 13362306a36Sopenharmony_ci int i; 13462306a36Sopenharmony_ci printk("btstack dump:\n"); 13562306a36Sopenharmony_ci for (i = 0; i < MAXTREEHEIGHT; i++) 13662306a36Sopenharmony_ci printk(KERN_ERR "bn = %Lx, index = %d\n", 13762306a36Sopenharmony_ci (long long)btstack->stack[i].bn, 13862306a36Sopenharmony_ci btstack->stack[i].index); 13962306a36Sopenharmony_ci} 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci/* retrieve search results */ 14262306a36Sopenharmony_ci#define BT_GETSEARCH(IP, LEAF, BN, MP, TYPE, P, INDEX, ROOT)\ 14362306a36Sopenharmony_ci{\ 14462306a36Sopenharmony_ci BN = (LEAF)->bn;\ 14562306a36Sopenharmony_ci MP = (LEAF)->mp;\ 14662306a36Sopenharmony_ci if (BN)\ 14762306a36Sopenharmony_ci P = (TYPE *)MP->data;\ 14862306a36Sopenharmony_ci else\ 14962306a36Sopenharmony_ci P = (TYPE *)&JFS_IP(IP)->ROOT;\ 15062306a36Sopenharmony_ci INDEX = (LEAF)->index;\ 15162306a36Sopenharmony_ci} 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci/* put the page buffer of search */ 15462306a36Sopenharmony_ci#define BT_PUTSEARCH(BTSTACK)\ 15562306a36Sopenharmony_ci{\ 15662306a36Sopenharmony_ci if (! BT_IS_ROOT((BTSTACK)->top->mp))\ 15762306a36Sopenharmony_ci release_metapage((BTSTACK)->top->mp);\ 15862306a36Sopenharmony_ci} 15962306a36Sopenharmony_ci#endif /* _H_JFS_BTREE */ 160