xfs_da_format.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  1. /*
  2. * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
  3. * Copyright (c) 2013 Red Hat, Inc.
  4. * All Rights Reserved.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it would be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write the Free Software Foundation,
  17. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18. */
  19. #include "xfs.h"
  20. #include "xfs_fs.h"
  21. #include "xfs_format.h"
  22. #include "xfs_log_format.h"
  23. #include "xfs_trans_resv.h"
  24. #include "xfs_sb.h"
  25. #include "xfs_ag.h"
  26. #include "xfs_mount.h"
  27. #include "xfs_da_format.h"
  28. #include "xfs_inode.h"
  29. #include "xfs_dir2.h"
  30. /*
  31. * Shortform directory ops
  32. */
  33. static int
  34. xfs_dir2_sf_entsize(
  35. struct xfs_dir2_sf_hdr *hdr,
  36. int len)
  37. {
  38. int count = sizeof(struct xfs_dir2_sf_entry); /* namelen + offset */
  39. count += len; /* name */
  40. count += hdr->i8count ? sizeof(xfs_dir2_ino8_t) :
  41. sizeof(xfs_dir2_ino4_t); /* ino # */
  42. return count;
  43. }
  44. static int
  45. xfs_dir3_sf_entsize(
  46. struct xfs_dir2_sf_hdr *hdr,
  47. int len)
  48. {
  49. return xfs_dir2_sf_entsize(hdr, len) + sizeof(__uint8_t);
  50. }
  51. static struct xfs_dir2_sf_entry *
  52. xfs_dir2_sf_nextentry(
  53. struct xfs_dir2_sf_hdr *hdr,
  54. struct xfs_dir2_sf_entry *sfep)
  55. {
  56. return (struct xfs_dir2_sf_entry *)
  57. ((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen));
  58. }
  59. static struct xfs_dir2_sf_entry *
  60. xfs_dir3_sf_nextentry(
  61. struct xfs_dir2_sf_hdr *hdr,
  62. struct xfs_dir2_sf_entry *sfep)
  63. {
  64. return (struct xfs_dir2_sf_entry *)
  65. ((char *)sfep + xfs_dir3_sf_entsize(hdr, sfep->namelen));
  66. }
  67. /*
  68. * For filetype enabled shortform directories, the file type field is stored at
  69. * the end of the name. Because it's only a single byte, endian conversion is
  70. * not necessary. For non-filetype enable directories, the type is always
  71. * unknown and we never store the value.
  72. */
  73. static __uint8_t
  74. xfs_dir2_sfe_get_ftype(
  75. struct xfs_dir2_sf_entry *sfep)
  76. {
  77. return XFS_DIR3_FT_UNKNOWN;
  78. }
  79. static void
  80. xfs_dir2_sfe_put_ftype(
  81. struct xfs_dir2_sf_entry *sfep,
  82. __uint8_t ftype)
  83. {
  84. ASSERT(ftype < XFS_DIR3_FT_MAX);
  85. }
  86. static __uint8_t
  87. xfs_dir3_sfe_get_ftype(
  88. struct xfs_dir2_sf_entry *sfep)
  89. {
  90. __uint8_t ftype;
  91. ftype = sfep->name[sfep->namelen];
  92. if (ftype >= XFS_DIR3_FT_MAX)
  93. return XFS_DIR3_FT_UNKNOWN;
  94. return ftype;
  95. }
  96. static void
  97. xfs_dir3_sfe_put_ftype(
  98. struct xfs_dir2_sf_entry *sfep,
  99. __uint8_t ftype)
  100. {
  101. ASSERT(ftype < XFS_DIR3_FT_MAX);
  102. sfep->name[sfep->namelen] = ftype;
  103. }
  104. /*
  105. * Inode numbers in short-form directories can come in two versions,
  106. * either 4 bytes or 8 bytes wide. These helpers deal with the
  107. * two forms transparently by looking at the headers i8count field.
  108. *
  109. * For 64-bit inode number the most significant byte must be zero.
  110. */
  111. static xfs_ino_t
  112. xfs_dir2_sf_get_ino(
  113. struct xfs_dir2_sf_hdr *hdr,
  114. xfs_dir2_inou_t *from)
  115. {
  116. if (hdr->i8count)
  117. return get_unaligned_be64(&from->i8.i) & 0x00ffffffffffffffULL;
  118. else
  119. return get_unaligned_be32(&from->i4.i);
  120. }
  121. static void
  122. xfs_dir2_sf_put_ino(
  123. struct xfs_dir2_sf_hdr *hdr,
  124. xfs_dir2_inou_t *to,
  125. xfs_ino_t ino)
  126. {
  127. ASSERT((ino & 0xff00000000000000ULL) == 0);
  128. if (hdr->i8count)
  129. put_unaligned_be64(ino, &to->i8.i);
  130. else
  131. put_unaligned_be32(ino, &to->i4.i);
  132. }
  133. static xfs_ino_t
  134. xfs_dir2_sf_get_parent_ino(
  135. struct xfs_dir2_sf_hdr *hdr)
  136. {
  137. return xfs_dir2_sf_get_ino(hdr, &hdr->parent);
  138. }
  139. static void
  140. xfs_dir2_sf_put_parent_ino(
  141. struct xfs_dir2_sf_hdr *hdr,
  142. xfs_ino_t ino)
  143. {
  144. xfs_dir2_sf_put_ino(hdr, &hdr->parent, ino);
  145. }
  146. /*
  147. * In short-form directory entries the inode numbers are stored at variable
  148. * offset behind the entry name. If the entry stores a filetype value, then it
  149. * sits between the name and the inode number. Hence the inode numbers may only
  150. * be accessed through the helpers below.
  151. */
  152. static xfs_ino_t
  153. xfs_dir2_sfe_get_ino(
  154. struct xfs_dir2_sf_hdr *hdr,
  155. struct xfs_dir2_sf_entry *sfep)
  156. {
  157. return xfs_dir2_sf_get_ino(hdr,
  158. (xfs_dir2_inou_t *)&sfep->name[sfep->namelen]);
  159. }
  160. static void
  161. xfs_dir2_sfe_put_ino(
  162. struct xfs_dir2_sf_hdr *hdr,
  163. struct xfs_dir2_sf_entry *sfep,
  164. xfs_ino_t ino)
  165. {
  166. xfs_dir2_sf_put_ino(hdr,
  167. (xfs_dir2_inou_t *)&sfep->name[sfep->namelen], ino);
  168. }
  169. static xfs_ino_t
  170. xfs_dir3_sfe_get_ino(
  171. struct xfs_dir2_sf_hdr *hdr,
  172. struct xfs_dir2_sf_entry *sfep)
  173. {
  174. return xfs_dir2_sf_get_ino(hdr,
  175. (xfs_dir2_inou_t *)&sfep->name[sfep->namelen + 1]);
  176. }
  177. static void
  178. xfs_dir3_sfe_put_ino(
  179. struct xfs_dir2_sf_hdr *hdr,
  180. struct xfs_dir2_sf_entry *sfep,
  181. xfs_ino_t ino)
  182. {
  183. xfs_dir2_sf_put_ino(hdr,
  184. (xfs_dir2_inou_t *)&sfep->name[sfep->namelen + 1], ino);
  185. }
  186. /*
  187. * Directory data block operations
  188. */
  189. static int
  190. __xfs_dir3_data_entsize(
  191. bool ftype,
  192. int n)
  193. {
  194. int size = offsetof(struct xfs_dir2_data_entry, name[0]);
  195. size += n;
  196. size += sizeof(xfs_dir2_data_off_t);
  197. if (ftype)
  198. size += sizeof(__uint8_t);
  199. return roundup(size, XFS_DIR2_DATA_ALIGN);
  200. }
  201. static int
  202. xfs_dir2_data_entsize(
  203. int n)
  204. {
  205. return __xfs_dir3_data_entsize(false, n);
  206. }
  207. static int
  208. xfs_dir3_data_entsize(
  209. int n)
  210. {
  211. return __xfs_dir3_data_entsize(true, n);
  212. }
  213. static __uint8_t
  214. xfs_dir2_data_get_ftype(
  215. struct xfs_dir2_data_entry *dep)
  216. {
  217. return XFS_DIR3_FT_UNKNOWN;
  218. }
  219. static void
  220. xfs_dir2_data_put_ftype(
  221. struct xfs_dir2_data_entry *dep,
  222. __uint8_t ftype)
  223. {
  224. ASSERT(ftype < XFS_DIR3_FT_MAX);
  225. }
  226. static __uint8_t
  227. xfs_dir3_data_get_ftype(
  228. struct xfs_dir2_data_entry *dep)
  229. {
  230. __uint8_t ftype = dep->name[dep->namelen];
  231. ASSERT(ftype < XFS_DIR3_FT_MAX);
  232. if (ftype >= XFS_DIR3_FT_MAX)
  233. return XFS_DIR3_FT_UNKNOWN;
  234. return ftype;
  235. }
  236. static void
  237. xfs_dir3_data_put_ftype(
  238. struct xfs_dir2_data_entry *dep,
  239. __uint8_t type)
  240. {
  241. ASSERT(type < XFS_DIR3_FT_MAX);
  242. ASSERT(dep->namelen != 0);
  243. dep->name[dep->namelen] = type;
  244. }
  245. /*
  246. * Pointer to an entry's tag word.
  247. */
  248. static __be16 *
  249. xfs_dir2_data_entry_tag_p(
  250. struct xfs_dir2_data_entry *dep)
  251. {
  252. return (__be16 *)((char *)dep +
  253. xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16));
  254. }
  255. static __be16 *
  256. xfs_dir3_data_entry_tag_p(
  257. struct xfs_dir2_data_entry *dep)
  258. {
  259. return (__be16 *)((char *)dep +
  260. xfs_dir3_data_entsize(dep->namelen) - sizeof(__be16));
  261. }
  262. /*
  263. * Offsets of . and .. in data space (always block 0)
  264. */
  265. static xfs_dir2_data_aoff_t
  266. xfs_dir2_data_dot_offset(void)
  267. {
  268. return sizeof(struct xfs_dir2_data_hdr);
  269. }
  270. static xfs_dir2_data_aoff_t
  271. xfs_dir2_data_dotdot_offset(void)
  272. {
  273. return xfs_dir2_data_dot_offset() + xfs_dir2_data_entsize(1);
  274. }
  275. static xfs_dir2_data_aoff_t
  276. xfs_dir2_data_first_offset(void)
  277. {
  278. return xfs_dir2_data_dotdot_offset() + xfs_dir2_data_entsize(2);
  279. }
  280. static xfs_dir2_data_aoff_t
  281. xfs_dir3_data_dot_offset(void)
  282. {
  283. return sizeof(struct xfs_dir3_data_hdr);
  284. }
  285. static xfs_dir2_data_aoff_t
  286. xfs_dir3_data_dotdot_offset(void)
  287. {
  288. return xfs_dir3_data_dot_offset() + xfs_dir3_data_entsize(1);
  289. }
  290. static xfs_dir2_data_aoff_t
  291. xfs_dir3_data_first_offset(void)
  292. {
  293. return xfs_dir3_data_dotdot_offset() + xfs_dir3_data_entsize(2);
  294. }
  295. /*
  296. * location of . and .. in data space (always block 0)
  297. */
  298. static struct xfs_dir2_data_entry *
  299. xfs_dir2_data_dot_entry_p(
  300. struct xfs_dir2_data_hdr *hdr)
  301. {
  302. return (struct xfs_dir2_data_entry *)
  303. ((char *)hdr + xfs_dir2_data_dot_offset());
  304. }
  305. static struct xfs_dir2_data_entry *
  306. xfs_dir2_data_dotdot_entry_p(
  307. struct xfs_dir2_data_hdr *hdr)
  308. {
  309. return (struct xfs_dir2_data_entry *)
  310. ((char *)hdr + xfs_dir2_data_dotdot_offset());
  311. }
  312. static struct xfs_dir2_data_entry *
  313. xfs_dir2_data_first_entry_p(
  314. struct xfs_dir2_data_hdr *hdr)
  315. {
  316. return (struct xfs_dir2_data_entry *)
  317. ((char *)hdr + xfs_dir2_data_first_offset());
  318. }
  319. static struct xfs_dir2_data_entry *
  320. xfs_dir3_data_dot_entry_p(
  321. struct xfs_dir2_data_hdr *hdr)
  322. {
  323. return (struct xfs_dir2_data_entry *)
  324. ((char *)hdr + xfs_dir3_data_dot_offset());
  325. }
  326. static struct xfs_dir2_data_entry *
  327. xfs_dir3_data_dotdot_entry_p(
  328. struct xfs_dir2_data_hdr *hdr)
  329. {
  330. return (struct xfs_dir2_data_entry *)
  331. ((char *)hdr + xfs_dir3_data_dotdot_offset());
  332. }
  333. static struct xfs_dir2_data_entry *
  334. xfs_dir3_data_first_entry_p(
  335. struct xfs_dir2_data_hdr *hdr)
  336. {
  337. return (struct xfs_dir2_data_entry *)
  338. ((char *)hdr + xfs_dir3_data_first_offset());
  339. }
  340. static struct xfs_dir2_data_free *
  341. xfs_dir2_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
  342. {
  343. return hdr->bestfree;
  344. }
  345. static struct xfs_dir2_data_free *
  346. xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
  347. {
  348. return ((struct xfs_dir3_data_hdr *)hdr)->best_free;
  349. }
  350. static size_t
  351. xfs_dir2_data_entry_offset(void)
  352. {
  353. return sizeof(struct xfs_dir2_data_hdr);
  354. }
  355. static struct xfs_dir2_data_entry *
  356. xfs_dir2_data_entry_p(struct xfs_dir2_data_hdr *hdr)
  357. {
  358. return (struct xfs_dir2_data_entry *)
  359. ((char *)hdr + xfs_dir2_data_entry_offset());
  360. }
  361. static struct xfs_dir2_data_unused *
  362. xfs_dir2_data_unused_p(struct xfs_dir2_data_hdr *hdr)
  363. {
  364. return (struct xfs_dir2_data_unused *)
  365. ((char *)hdr + xfs_dir2_data_entry_offset());
  366. }
  367. static size_t
  368. xfs_dir3_data_entry_offset(void)
  369. {
  370. return sizeof(struct xfs_dir3_data_hdr);
  371. }
  372. static struct xfs_dir2_data_entry *
  373. xfs_dir3_data_entry_p(struct xfs_dir2_data_hdr *hdr)
  374. {
  375. return (struct xfs_dir2_data_entry *)
  376. ((char *)hdr + xfs_dir3_data_entry_offset());
  377. }
  378. static struct xfs_dir2_data_unused *
  379. xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
  380. {
  381. return (struct xfs_dir2_data_unused *)
  382. ((char *)hdr + xfs_dir3_data_entry_offset());
  383. }
  384. /*
  385. * Directory Leaf block operations
  386. */
  387. static int
  388. xfs_dir2_leaf_hdr_size(void)
  389. {
  390. return sizeof(struct xfs_dir2_leaf_hdr);
  391. }
  392. static int
  393. xfs_dir2_max_leaf_ents(struct xfs_mount *mp)
  394. {
  395. return (mp->m_dirblksize - xfs_dir2_leaf_hdr_size()) /
  396. (uint)sizeof(struct xfs_dir2_leaf_entry);
  397. }
  398. static struct xfs_dir2_leaf_entry *
  399. xfs_dir2_leaf_ents_p(struct xfs_dir2_leaf *lp)
  400. {
  401. return lp->__ents;
  402. }
  403. static int
  404. xfs_dir3_leaf_hdr_size(void)
  405. {
  406. return sizeof(struct xfs_dir3_leaf_hdr);
  407. }
  408. static inline int
  409. xfs_dir3_max_leaf_ents(struct xfs_mount *mp)
  410. {
  411. return (mp->m_dirblksize - xfs_dir3_leaf_hdr_size()) /
  412. (uint)sizeof(struct xfs_dir2_leaf_entry);
  413. }
  414. static inline struct xfs_dir2_leaf_entry *
  415. xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp)
  416. {
  417. return ((struct xfs_dir3_leaf *)lp)->__ents;
  418. }
  419. /*
  420. * Directory/Attribute Node block operations
  421. */
  422. static inline int
  423. xfs_da2_node_hdr_size(void)
  424. {
  425. return sizeof(struct xfs_da_node_hdr);
  426. }
  427. static struct xfs_da_node_entry *
  428. xfs_da2_node_tree_p(struct xfs_da_intnode *dap)
  429. {
  430. return dap->__btree;
  431. }
  432. static inline int
  433. xfs_da3_node_hdr_size(void)
  434. {
  435. return sizeof(struct xfs_da3_node_hdr);
  436. }
  437. static inline struct xfs_da_node_entry *
  438. xfs_da3_node_tree_p(struct xfs_da_intnode *dap)
  439. {
  440. return ((struct xfs_da3_intnode *)dap)->__btree;
  441. }
  442. const struct xfs_dir_ops xfs_dir2_ops = {
  443. .sf_entsize = xfs_dir2_sf_entsize,
  444. .sf_nextentry = xfs_dir2_sf_nextentry,
  445. .sf_get_ftype = xfs_dir2_sfe_get_ftype,
  446. .sf_put_ftype = xfs_dir2_sfe_put_ftype,
  447. .sf_get_ino = xfs_dir2_sfe_get_ino,
  448. .sf_put_ino = xfs_dir2_sfe_put_ino,
  449. .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
  450. .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
  451. .data_entsize = xfs_dir2_data_entsize,
  452. .data_get_ftype = xfs_dir2_data_get_ftype,
  453. .data_put_ftype = xfs_dir2_data_put_ftype,
  454. .data_entry_tag_p = xfs_dir2_data_entry_tag_p,
  455. .data_bestfree_p = xfs_dir2_data_bestfree_p,
  456. .data_dot_offset = xfs_dir2_data_dot_offset,
  457. .data_dotdot_offset = xfs_dir2_data_dotdot_offset,
  458. .data_first_offset = xfs_dir2_data_first_offset,
  459. .data_entry_offset = xfs_dir2_data_entry_offset,
  460. .data_dot_entry_p = xfs_dir2_data_dot_entry_p,
  461. .data_dotdot_entry_p = xfs_dir2_data_dotdot_entry_p,
  462. .data_first_entry_p = xfs_dir2_data_first_entry_p,
  463. .data_entry_p = xfs_dir2_data_entry_p,
  464. .data_unused_p = xfs_dir2_data_unused_p,
  465. .leaf_hdr_size = xfs_dir2_leaf_hdr_size,
  466. .leaf_max_ents = xfs_dir2_max_leaf_ents,
  467. .leaf_ents_p = xfs_dir2_leaf_ents_p,
  468. .node_hdr_size = xfs_da2_node_hdr_size,
  469. .node_tree_p = xfs_da2_node_tree_p,
  470. };
  471. const struct xfs_dir_ops xfs_dir2_ftype_ops = {
  472. .sf_entsize = xfs_dir3_sf_entsize,
  473. .sf_nextentry = xfs_dir3_sf_nextentry,
  474. .sf_get_ftype = xfs_dir3_sfe_get_ftype,
  475. .sf_put_ftype = xfs_dir3_sfe_put_ftype,
  476. .sf_get_ino = xfs_dir3_sfe_get_ino,
  477. .sf_put_ino = xfs_dir3_sfe_put_ino,
  478. .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
  479. .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
  480. .data_entsize = xfs_dir3_data_entsize,
  481. .data_get_ftype = xfs_dir3_data_get_ftype,
  482. .data_put_ftype = xfs_dir3_data_put_ftype,
  483. .data_entry_tag_p = xfs_dir3_data_entry_tag_p,
  484. .data_bestfree_p = xfs_dir2_data_bestfree_p,
  485. .data_dot_offset = xfs_dir2_data_dot_offset,
  486. .data_dotdot_offset = xfs_dir2_data_dotdot_offset,
  487. .data_first_offset = xfs_dir2_data_first_offset,
  488. .data_entry_offset = xfs_dir2_data_entry_offset,
  489. .data_dot_entry_p = xfs_dir2_data_dot_entry_p,
  490. .data_dotdot_entry_p = xfs_dir2_data_dotdot_entry_p,
  491. .data_first_entry_p = xfs_dir2_data_first_entry_p,
  492. .data_entry_p = xfs_dir2_data_entry_p,
  493. .data_unused_p = xfs_dir2_data_unused_p,
  494. .leaf_hdr_size = xfs_dir2_leaf_hdr_size,
  495. .leaf_max_ents = xfs_dir2_max_leaf_ents,
  496. .leaf_ents_p = xfs_dir2_leaf_ents_p,
  497. .node_hdr_size = xfs_da2_node_hdr_size,
  498. .node_tree_p = xfs_da2_node_tree_p,
  499. };
  500. const struct xfs_dir_ops xfs_dir3_ops = {
  501. .sf_entsize = xfs_dir3_sf_entsize,
  502. .sf_nextentry = xfs_dir3_sf_nextentry,
  503. .sf_get_ftype = xfs_dir3_sfe_get_ftype,
  504. .sf_put_ftype = xfs_dir3_sfe_put_ftype,
  505. .sf_get_ino = xfs_dir3_sfe_get_ino,
  506. .sf_put_ino = xfs_dir3_sfe_put_ino,
  507. .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
  508. .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
  509. .data_entsize = xfs_dir3_data_entsize,
  510. .data_get_ftype = xfs_dir3_data_get_ftype,
  511. .data_put_ftype = xfs_dir3_data_put_ftype,
  512. .data_entry_tag_p = xfs_dir3_data_entry_tag_p,
  513. .data_bestfree_p = xfs_dir3_data_bestfree_p,
  514. .data_dot_offset = xfs_dir3_data_dot_offset,
  515. .data_dotdot_offset = xfs_dir3_data_dotdot_offset,
  516. .data_first_offset = xfs_dir3_data_first_offset,
  517. .data_entry_offset = xfs_dir3_data_entry_offset,
  518. .data_dot_entry_p = xfs_dir3_data_dot_entry_p,
  519. .data_dotdot_entry_p = xfs_dir3_data_dotdot_entry_p,
  520. .data_first_entry_p = xfs_dir3_data_first_entry_p,
  521. .data_entry_p = xfs_dir3_data_entry_p,
  522. .data_unused_p = xfs_dir3_data_unused_p,
  523. .leaf_hdr_size = xfs_dir3_leaf_hdr_size,
  524. .leaf_max_ents = xfs_dir3_max_leaf_ents,
  525. .leaf_ents_p = xfs_dir3_leaf_ents_p,
  526. .node_hdr_size = xfs_da3_node_hdr_size,
  527. .node_tree_p = xfs_da3_node_tree_p,
  528. };
  529. const struct xfs_dir_ops xfs_dir2_nondir_ops = {
  530. .node_hdr_size = xfs_da2_node_hdr_size,
  531. .node_tree_p = xfs_da2_node_tree_p,
  532. };
  533. const struct xfs_dir_ops xfs_dir3_nondir_ops = {
  534. .node_hdr_size = xfs_da3_node_hdr_size,
  535. .node_tree_p = xfs_da3_node_tree_p,
  536. };
  537. /*
  538. * Return the ops structure according to the current config. If we are passed
  539. * an inode, then that overrides the default config we use which is based on
  540. * feature bits.
  541. */
  542. const struct xfs_dir_ops *
  543. xfs_dir_get_ops(
  544. struct xfs_mount *mp,
  545. struct xfs_inode *dp)
  546. {
  547. if (dp)
  548. return dp->d_ops;
  549. if (mp->m_dir_inode_ops)
  550. return mp->m_dir_inode_ops;
  551. if (xfs_sb_version_hascrc(&mp->m_sb))
  552. return &xfs_dir3_ops;
  553. if (xfs_sb_version_hasftype(&mp->m_sb))
  554. return &xfs_dir2_ftype_ops;
  555. return &xfs_dir2_ops;
  556. }
  557. const struct xfs_dir_ops *
  558. xfs_nondir_get_ops(
  559. struct xfs_mount *mp,
  560. struct xfs_inode *dp)
  561. {
  562. if (dp)
  563. return dp->d_ops;
  564. if (mp->m_nondir_inode_ops)
  565. return mp->m_nondir_inode_ops;
  566. if (xfs_sb_version_hascrc(&mp->m_sb))
  567. return &xfs_dir3_nondir_ops;
  568. return &xfs_dir2_nondir_ops;
  569. }