jfs_dtree.h 5.9 KB

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