xref: /OK3568_Linux_fs/kernel/fs/jfs/jfs_dtree.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *   Copyright (C) International Business Machines Corp., 2000-2002
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun #ifndef _H_JFS_DTREE
6*4882a593Smuzhiyun #define	_H_JFS_DTREE
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun /*
9*4882a593Smuzhiyun  *	jfs_dtree.h: directory B+-tree manager
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include "jfs_btree.h"
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun typedef union {
15*4882a593Smuzhiyun 	struct {
16*4882a593Smuzhiyun 		tid_t tid;
17*4882a593Smuzhiyun 		struct inode *ip;
18*4882a593Smuzhiyun 		u32 ino;
19*4882a593Smuzhiyun 	} leaf;
20*4882a593Smuzhiyun 	pxd_t xd;
21*4882a593Smuzhiyun } ddata_t;
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun /*
25*4882a593Smuzhiyun  *	entry segment/slot
26*4882a593Smuzhiyun  *
27*4882a593Smuzhiyun  * an entry consists of type dependent head/only segment/slot and
28*4882a593Smuzhiyun  * additional segments/slots linked vi next field;
29*4882a593Smuzhiyun  * N.B. last/only segment of entry is terminated by next = -1;
30*4882a593Smuzhiyun  */
31*4882a593Smuzhiyun /*
32*4882a593Smuzhiyun  *	directory page slot
33*4882a593Smuzhiyun  */
34*4882a593Smuzhiyun struct dtslot {
35*4882a593Smuzhiyun 	s8 next;		/* 1: */
36*4882a593Smuzhiyun 	s8 cnt;			/* 1: */
37*4882a593Smuzhiyun 	__le16 name[15];	/* 30: */
38*4882a593Smuzhiyun };				/* (32) */
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun #define DATASLOTSIZE	16
42*4882a593Smuzhiyun #define L2DATASLOTSIZE	4
43*4882a593Smuzhiyun #define	DTSLOTSIZE	32
44*4882a593Smuzhiyun #define	L2DTSLOTSIZE	5
45*4882a593Smuzhiyun #define DTSLOTHDRSIZE	2
46*4882a593Smuzhiyun #define DTSLOTDATASIZE	30
47*4882a593Smuzhiyun #define DTSLOTDATALEN	15
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun /*
50*4882a593Smuzhiyun  *	 internal node entry head/only segment
51*4882a593Smuzhiyun  */
52*4882a593Smuzhiyun struct idtentry {
53*4882a593Smuzhiyun 	pxd_t xd;		/* 8: child extent descriptor */
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	s8 next;		/* 1: */
56*4882a593Smuzhiyun 	u8 namlen;		/* 1: */
57*4882a593Smuzhiyun 	__le16 name[11];	/* 22: 2-byte aligned */
58*4882a593Smuzhiyun };				/* (32) */
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun #define DTIHDRSIZE	10
61*4882a593Smuzhiyun #define DTIHDRDATALEN	11
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun /* compute number of slots for entry */
64*4882a593Smuzhiyun #define	NDTINTERNAL(klen) (DIV_ROUND_UP((4 + (klen)), 15))
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun /*
68*4882a593Smuzhiyun  *	leaf node entry head/only segment
69*4882a593Smuzhiyun  *
70*4882a593Smuzhiyun  *	For legacy filesystems, name contains 13 wchars -- no index field
71*4882a593Smuzhiyun  */
72*4882a593Smuzhiyun struct ldtentry {
73*4882a593Smuzhiyun 	__le32 inumber;		/* 4: 4-byte aligned */
74*4882a593Smuzhiyun 	s8 next;		/* 1: */
75*4882a593Smuzhiyun 	u8 namlen;		/* 1: */
76*4882a593Smuzhiyun 	__le16 name[11];	/* 22: 2-byte aligned */
77*4882a593Smuzhiyun 	__le32 index;		/* 4: index into dir_table */
78*4882a593Smuzhiyun };				/* (32) */
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun #define DTLHDRSIZE	6
81*4882a593Smuzhiyun #define DTLHDRDATALEN_LEGACY	13	/* Old (OS/2) format */
82*4882a593Smuzhiyun #define DTLHDRDATALEN	11
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun /*
85*4882a593Smuzhiyun  * dir_table used for directory traversal during readdir
86*4882a593Smuzhiyun  */
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun /*
89*4882a593Smuzhiyun  * Keep persistent index for directory entries
90*4882a593Smuzhiyun  */
91*4882a593Smuzhiyun #define DO_INDEX(INODE) (JFS_SBI((INODE)->i_sb)->mntflag & JFS_DIR_INDEX)
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun /*
94*4882a593Smuzhiyun  * Maximum entry in inline directory table
95*4882a593Smuzhiyun  */
96*4882a593Smuzhiyun #define MAX_INLINE_DIRTABLE_ENTRY 13
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun struct dir_table_slot {
99*4882a593Smuzhiyun 	u8 rsrvd;		/* 1: */
100*4882a593Smuzhiyun 	u8 flag;		/* 1: 0 if free */
101*4882a593Smuzhiyun 	u8 slot;		/* 1: slot within leaf page of entry */
102*4882a593Smuzhiyun 	u8 addr1;		/* 1: upper 8 bits of leaf page address */
103*4882a593Smuzhiyun 	__le32 addr2;		/* 4: lower 32 bits of leaf page address -OR-
104*4882a593Smuzhiyun 				   index of next entry when this entry was deleted */
105*4882a593Smuzhiyun };				/* (8) */
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun /*
108*4882a593Smuzhiyun  * flag values
109*4882a593Smuzhiyun  */
110*4882a593Smuzhiyun #define DIR_INDEX_VALID 1
111*4882a593Smuzhiyun #define DIR_INDEX_FREE 0
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun #define DTSaddress(dir_table_slot, address64)\
114*4882a593Smuzhiyun {\
115*4882a593Smuzhiyun 	(dir_table_slot)->addr1 = ((u64)address64) >> 32;\
116*4882a593Smuzhiyun 	(dir_table_slot)->addr2 = __cpu_to_le32((address64) & 0xffffffff);\
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun #define addressDTS(dts)\
120*4882a593Smuzhiyun 	( ((s64)((dts)->addr1)) << 32 | __le32_to_cpu((dts)->addr2) )
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun /* compute number of slots for entry */
123*4882a593Smuzhiyun #define	NDTLEAF_LEGACY(klen)	(DIV_ROUND_UP((2 + (klen)), 15))
124*4882a593Smuzhiyun #define	NDTLEAF	NDTINTERNAL
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun /*
128*4882a593Smuzhiyun  *	directory root page (in-line in on-disk inode):
129*4882a593Smuzhiyun  *
130*4882a593Smuzhiyun  * cf. dtpage_t below.
131*4882a593Smuzhiyun  */
132*4882a593Smuzhiyun typedef union {
133*4882a593Smuzhiyun 	struct {
134*4882a593Smuzhiyun 		struct dasd DASD; /* 16: DASD limit/usage info */
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun 		u8 flag;	/* 1: */
137*4882a593Smuzhiyun 		u8 nextindex;	/* 1: next free entry in stbl */
138*4882a593Smuzhiyun 		s8 freecnt;	/* 1: free count */
139*4882a593Smuzhiyun 		s8 freelist;	/* 1: freelist header */
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 		__le32 idotdot;	/* 4: parent inode number */
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 		s8 stbl[8];	/* 8: sorted entry index table */
144*4882a593Smuzhiyun 	} header;		/* (32) */
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	struct dtslot slot[9];
147*4882a593Smuzhiyun } dtroot_t;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun #define PARENT(IP) \
150*4882a593Smuzhiyun 	(le32_to_cpu(JFS_IP(IP)->i_dtroot.header.idotdot))
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun #define DTROOTMAXSLOT	9
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun #define	dtEmpty(IP) (JFS_IP(IP)->i_dtroot.header.nextindex == 0)
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun /*
158*4882a593Smuzhiyun  *	directory regular page:
159*4882a593Smuzhiyun  *
160*4882a593Smuzhiyun  *	entry slot array of 32 byte slot
161*4882a593Smuzhiyun  *
162*4882a593Smuzhiyun  * sorted entry slot index table (stbl):
163*4882a593Smuzhiyun  * contiguous slots at slot specified by stblindex,
164*4882a593Smuzhiyun  * 1-byte per entry
165*4882a593Smuzhiyun  *   512 byte block:  16 entry tbl (1 slot)
166*4882a593Smuzhiyun  *  1024 byte block:  32 entry tbl (1 slot)
167*4882a593Smuzhiyun  *  2048 byte block:  64 entry tbl (2 slot)
168*4882a593Smuzhiyun  *  4096 byte block: 128 entry tbl (4 slot)
169*4882a593Smuzhiyun  *
170*4882a593Smuzhiyun  * data area:
171*4882a593Smuzhiyun  *   512 byte block:  16 - 2 =  14 slot
172*4882a593Smuzhiyun  *  1024 byte block:  32 - 2 =  30 slot
173*4882a593Smuzhiyun  *  2048 byte block:  64 - 3 =  61 slot
174*4882a593Smuzhiyun  *  4096 byte block: 128 - 5 = 123 slot
175*4882a593Smuzhiyun  *
176*4882a593Smuzhiyun  * N.B. index is 0-based; index fields refer to slot index
177*4882a593Smuzhiyun  * except nextindex which refers to entry index in stbl;
178*4882a593Smuzhiyun  * end of entry stot list or freelist is marked with -1.
179*4882a593Smuzhiyun  */
180*4882a593Smuzhiyun typedef union {
181*4882a593Smuzhiyun 	struct {
182*4882a593Smuzhiyun 		__le64 next;	/* 8: next sibling */
183*4882a593Smuzhiyun 		__le64 prev;	/* 8: previous sibling */
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 		u8 flag;	/* 1: */
186*4882a593Smuzhiyun 		u8 nextindex;	/* 1: next entry index in stbl */
187*4882a593Smuzhiyun 		s8 freecnt;	/* 1: */
188*4882a593Smuzhiyun 		s8 freelist;	/* 1: slot index of head of freelist */
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 		u8 maxslot;	/* 1: number of slots in page slot[] */
191*4882a593Smuzhiyun 		u8 stblindex;	/* 1: slot index of start of stbl */
192*4882a593Smuzhiyun 		u8 rsrvd[2];	/* 2: */
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 		pxd_t self;	/* 8: self pxd */
195*4882a593Smuzhiyun 	} header;		/* (32) */
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	struct dtslot slot[128];
198*4882a593Smuzhiyun } dtpage_t;
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun #define DTPAGEMAXSLOT        128
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun #define DT8THPGNODEBYTES     512
203*4882a593Smuzhiyun #define DT8THPGNODETSLOTS      1
204*4882a593Smuzhiyun #define DT8THPGNODESLOTS      16
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun #define DTQTRPGNODEBYTES    1024
207*4882a593Smuzhiyun #define DTQTRPGNODETSLOTS      1
208*4882a593Smuzhiyun #define DTQTRPGNODESLOTS      32
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun #define DTHALFPGNODEBYTES   2048
211*4882a593Smuzhiyun #define DTHALFPGNODETSLOTS     2
212*4882a593Smuzhiyun #define DTHALFPGNODESLOTS     64
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun #define DTFULLPGNODEBYTES   4096
215*4882a593Smuzhiyun #define DTFULLPGNODETSLOTS     4
216*4882a593Smuzhiyun #define DTFULLPGNODESLOTS    128
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun #define DTENTRYSTART	1
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun /* get sorted entry table of the page */
221*4882a593Smuzhiyun #define DT_GETSTBL(p) ( ((p)->header.flag & BT_ROOT) ?\
222*4882a593Smuzhiyun 	((dtroot_t *)(p))->header.stbl : \
223*4882a593Smuzhiyun 	(s8 *)&(p)->slot[(p)->header.stblindex] )
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun /*
226*4882a593Smuzhiyun  * Flags for dtSearch
227*4882a593Smuzhiyun  */
228*4882a593Smuzhiyun #define JFS_CREATE 1
229*4882a593Smuzhiyun #define JFS_LOOKUP 2
230*4882a593Smuzhiyun #define JFS_REMOVE 3
231*4882a593Smuzhiyun #define JFS_RENAME 4
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun /*
234*4882a593Smuzhiyun  * Maximum file offset for directories.
235*4882a593Smuzhiyun  */
236*4882a593Smuzhiyun #define DIREND	INT_MAX
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun /*
239*4882a593Smuzhiyun  *	external declarations
240*4882a593Smuzhiyun  */
241*4882a593Smuzhiyun extern void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot);
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun extern int dtSearch(struct inode *ip, struct component_name * key,
244*4882a593Smuzhiyun 		    ino_t * data, struct btstack * btstack, int flag);
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun extern int dtInsert(tid_t tid, struct inode *ip, struct component_name * key,
247*4882a593Smuzhiyun 		    ino_t * ino, struct btstack * btstack);
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun extern int dtDelete(tid_t tid, struct inode *ip, struct component_name * key,
250*4882a593Smuzhiyun 		    ino_t * data, int flag);
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun extern int dtModify(tid_t tid, struct inode *ip, struct component_name * key,
253*4882a593Smuzhiyun 		    ino_t * orig_ino, ino_t new_ino, int flag);
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun extern int jfs_readdir(struct file *file, struct dir_context *ctx);
256*4882a593Smuzhiyun #endif				/* !_H_JFS_DTREE */
257