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