1*1a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * Copyright (C) International Business Machines Corp., 2000-2004
41da177e4SLinus Torvalds */
51da177e4SLinus Torvalds #ifndef _H_JFS_BTREE
61da177e4SLinus Torvalds #define _H_JFS_BTREE
71da177e4SLinus Torvalds
81da177e4SLinus Torvalds /*
91da177e4SLinus Torvalds * jfs_btree.h: B+-tree
101da177e4SLinus Torvalds *
111da177e4SLinus Torvalds * JFS B+-tree (dtree and xtree) common definitions
121da177e4SLinus Torvalds */
131da177e4SLinus Torvalds
141da177e4SLinus Torvalds /*
151da177e4SLinus Torvalds * basic btree page - btpage
161da177e4SLinus Torvalds *
171da177e4SLinus Torvalds struct btpage {
181da177e4SLinus Torvalds s64 next; right sibling bn
191da177e4SLinus Torvalds s64 prev; left sibling bn
201da177e4SLinus Torvalds
211da177e4SLinus Torvalds u8 flag;
221da177e4SLinus Torvalds u8 rsrvd[7]; type specific
231da177e4SLinus Torvalds s64 self; self address
241da177e4SLinus Torvalds
251da177e4SLinus Torvalds u8 entry[4064];
261da177e4SLinus Torvalds }; */
271da177e4SLinus Torvalds
281da177e4SLinus Torvalds /* btpaget_t flag */
291da177e4SLinus Torvalds #define BT_TYPE 0x07 /* B+-tree index */
301da177e4SLinus Torvalds #define BT_ROOT 0x01 /* root page */
311da177e4SLinus Torvalds #define BT_LEAF 0x02 /* leaf page */
321da177e4SLinus Torvalds #define BT_INTERNAL 0x04 /* internal page */
331da177e4SLinus Torvalds #define BT_RIGHTMOST 0x10 /* rightmost page */
341da177e4SLinus Torvalds #define BT_LEFTMOST 0x20 /* leftmost page */
351da177e4SLinus Torvalds #define BT_SWAPPED 0x80 /* used by fsck for endian swapping */
361da177e4SLinus Torvalds
371da177e4SLinus Torvalds /* btorder (in inode) */
381da177e4SLinus Torvalds #define BT_RANDOM 0x0000
391da177e4SLinus Torvalds #define BT_SEQUENTIAL 0x0001
401da177e4SLinus Torvalds #define BT_LOOKUP 0x0010
411da177e4SLinus Torvalds #define BT_INSERT 0x0020
421da177e4SLinus Torvalds #define BT_DELETE 0x0040
431da177e4SLinus Torvalds
441da177e4SLinus Torvalds /*
451da177e4SLinus Torvalds * btree page buffer cache access
461da177e4SLinus Torvalds */
471da177e4SLinus Torvalds #define BT_IS_ROOT(MP) (((MP)->xflag & COMMIT_PAGE) == 0)
481da177e4SLinus Torvalds
491da177e4SLinus Torvalds /* get page from buffer page */
501da177e4SLinus Torvalds #define BT_PAGE(IP, MP, TYPE, ROOT)\
511da177e4SLinus Torvalds (BT_IS_ROOT(MP) ? (TYPE *)&JFS_IP(IP)->ROOT : (TYPE *)(MP)->data)
521da177e4SLinus Torvalds
531da177e4SLinus Torvalds /* get the page buffer and the page for specified block address */
541da177e4SLinus Torvalds #define BT_GETPAGE(IP, BN, MP, TYPE, SIZE, P, RC, ROOT)\
551da177e4SLinus Torvalds {\
561da177e4SLinus Torvalds if ((BN) == 0)\
571da177e4SLinus Torvalds {\
581da177e4SLinus Torvalds MP = (struct metapage *)&JFS_IP(IP)->bxflag;\
591da177e4SLinus Torvalds P = (TYPE *)&JFS_IP(IP)->ROOT;\
601da177e4SLinus Torvalds RC = 0;\
611da177e4SLinus Torvalds }\
621da177e4SLinus Torvalds else\
631da177e4SLinus Torvalds {\
641da177e4SLinus Torvalds MP = read_metapage((IP), BN, SIZE, 1);\
651da177e4SLinus Torvalds if (MP) {\
661da177e4SLinus Torvalds RC = 0;\
671da177e4SLinus Torvalds P = (MP)->data;\
681da177e4SLinus Torvalds } else {\
691da177e4SLinus Torvalds P = NULL;\
701da177e4SLinus Torvalds jfs_err("bread failed!");\
711da177e4SLinus Torvalds RC = -EIO;\
721da177e4SLinus Torvalds }\
731da177e4SLinus Torvalds }\
741da177e4SLinus Torvalds }
751da177e4SLinus Torvalds
761da177e4SLinus Torvalds #define BT_MARK_DIRTY(MP, IP)\
771da177e4SLinus Torvalds {\
781da177e4SLinus Torvalds if (BT_IS_ROOT(MP))\
791da177e4SLinus Torvalds mark_inode_dirty(IP);\
801da177e4SLinus Torvalds else\
811da177e4SLinus Torvalds mark_metapage_dirty(MP);\
821da177e4SLinus Torvalds }
831da177e4SLinus Torvalds
841da177e4SLinus Torvalds /* put the page buffer */
851da177e4SLinus Torvalds #define BT_PUTPAGE(MP)\
861da177e4SLinus Torvalds {\
871da177e4SLinus Torvalds if (! BT_IS_ROOT(MP)) \
881da177e4SLinus Torvalds release_metapage(MP); \
891da177e4SLinus Torvalds }
901da177e4SLinus Torvalds
911da177e4SLinus Torvalds
921da177e4SLinus Torvalds /*
931da177e4SLinus Torvalds * btree traversal stack
941da177e4SLinus Torvalds *
951da177e4SLinus Torvalds * record the path traversed during the search;
961da177e4SLinus Torvalds * top frame record the leaf page/entry selected.
971da177e4SLinus Torvalds */
981da177e4SLinus Torvalds struct btframe { /* stack frame */
991da177e4SLinus Torvalds s64 bn; /* 8: */
1001da177e4SLinus Torvalds s16 index; /* 2: */
1011da177e4SLinus Torvalds s16 lastindex; /* 2: unused */
1021da177e4SLinus Torvalds struct metapage *mp; /* 4/8: */
1031da177e4SLinus Torvalds }; /* (16/24) */
1041da177e4SLinus Torvalds
1051da177e4SLinus Torvalds struct btstack {
1061da177e4SLinus Torvalds struct btframe *top;
1071da177e4SLinus Torvalds int nsplit;
1081da177e4SLinus Torvalds struct btframe stack[MAXTREEHEIGHT];
1091da177e4SLinus Torvalds };
1101da177e4SLinus Torvalds
1111da177e4SLinus Torvalds #define BT_CLR(btstack)\
1121da177e4SLinus Torvalds (btstack)->top = (btstack)->stack
1131da177e4SLinus Torvalds
1141da177e4SLinus Torvalds #define BT_STACK_FULL(btstack)\
1151da177e4SLinus Torvalds ( (btstack)->top == &((btstack)->stack[MAXTREEHEIGHT-1]))
1161da177e4SLinus Torvalds
1171da177e4SLinus Torvalds #define BT_PUSH(BTSTACK, BN, INDEX)\
1181da177e4SLinus Torvalds {\
1191da177e4SLinus Torvalds assert(!BT_STACK_FULL(BTSTACK));\
1201da177e4SLinus Torvalds (BTSTACK)->top->bn = BN;\
1211da177e4SLinus Torvalds (BTSTACK)->top->index = INDEX;\
1221da177e4SLinus Torvalds ++(BTSTACK)->top;\
1231da177e4SLinus Torvalds }
1241da177e4SLinus Torvalds
1251da177e4SLinus Torvalds #define BT_POP(btstack)\
1261da177e4SLinus Torvalds ( (btstack)->top == (btstack)->stack ? NULL : --(btstack)->top )
1271da177e4SLinus Torvalds
1281da177e4SLinus Torvalds #define BT_STACK(btstack)\
1291da177e4SLinus Torvalds ( (btstack)->top == (btstack)->stack ? NULL : (btstack)->top )
1301da177e4SLinus Torvalds
BT_STACK_DUMP(struct btstack * btstack)1311da177e4SLinus Torvalds static inline void BT_STACK_DUMP(struct btstack *btstack)
1321da177e4SLinus Torvalds {
1331da177e4SLinus Torvalds int i;
1341da177e4SLinus Torvalds printk("btstack dump:\n");
1351da177e4SLinus Torvalds for (i = 0; i < MAXTREEHEIGHT; i++)
1361da177e4SLinus Torvalds printk(KERN_ERR "bn = %Lx, index = %d\n",
1371da177e4SLinus Torvalds (long long)btstack->stack[i].bn,
1381da177e4SLinus Torvalds btstack->stack[i].index);
1391da177e4SLinus Torvalds }
1401da177e4SLinus Torvalds
1411da177e4SLinus Torvalds /* retrieve search results */
1421da177e4SLinus Torvalds #define BT_GETSEARCH(IP, LEAF, BN, MP, TYPE, P, INDEX, ROOT)\
1431da177e4SLinus Torvalds {\
1441da177e4SLinus Torvalds BN = (LEAF)->bn;\
1451da177e4SLinus Torvalds MP = (LEAF)->mp;\
1461da177e4SLinus Torvalds if (BN)\
1471da177e4SLinus Torvalds P = (TYPE *)MP->data;\
1481da177e4SLinus Torvalds else\
1491da177e4SLinus Torvalds P = (TYPE *)&JFS_IP(IP)->ROOT;\
1501da177e4SLinus Torvalds INDEX = (LEAF)->index;\
1511da177e4SLinus Torvalds }
1521da177e4SLinus Torvalds
1531da177e4SLinus Torvalds /* put the page buffer of search */
1541da177e4SLinus Torvalds #define BT_PUTSEARCH(BTSTACK)\
1551da177e4SLinus Torvalds {\
1561da177e4SLinus Torvalds if (! BT_IS_ROOT((BTSTACK)->top->mp))\
1571da177e4SLinus Torvalds release_metapage((BTSTACK)->top->mp);\
1581da177e4SLinus Torvalds }
1591da177e4SLinus Torvalds #endif /* _H_JFS_BTREE */
160