xfs_attr.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (c) 2000,2002-2003,2005 Silicon Graphics, Inc.
  4. * All Rights Reserved.
  5. */
  6. #ifndef __XFS_ATTR_H__
  7. #define __XFS_ATTR_H__
  8. struct xfs_inode;
  9. struct xfs_da_args;
  10. struct xfs_attr_list_context;
  11. /*
  12. * Large attribute lists are structured around Btrees where all the data
  13. * elements are in the leaf nodes. Attribute names are hashed into an int,
  14. * then that int is used as the index into the Btree. Since the hashval
  15. * of an attribute name may not be unique, we may have duplicate keys.
  16. * The internal links in the Btree are logical block offsets into the file.
  17. *
  18. * Small attribute lists use a different format and are packed as tightly
  19. * as possible so as to fit into the literal area of the inode.
  20. */
  21. /*
  22. * The maximum size (into the kernel or returned from the kernel) of an
  23. * attribute value or the buffer used for an attr_list() call. Larger
  24. * sizes will result in an ERANGE return code.
  25. */
  26. #define ATTR_MAX_VALUELEN (64*1024) /* max length of a value */
  27. /*
  28. * Kernel-internal version of the attrlist cursor.
  29. */
  30. struct xfs_attrlist_cursor_kern {
  31. __u32 hashval; /* hash value of next entry to add */
  32. __u32 blkno; /* block containing entry (suggestion) */
  33. __u32 offset; /* offset in list of equal-hashvals */
  34. __u16 pad1; /* padding to match user-level */
  35. __u8 pad2; /* padding to match user-level */
  36. __u8 initted; /* T/F: cursor has been initialized */
  37. };
  38. /*========================================================================
  39. * Structure used to pass context around among the routines.
  40. *========================================================================*/
  41. /* void; state communicated via *context */
  42. typedef void (*put_listent_func_t)(struct xfs_attr_list_context *, int,
  43. unsigned char *, int, int);
  44. struct xfs_attr_list_context {
  45. struct xfs_trans *tp;
  46. struct xfs_inode *dp; /* inode */
  47. struct xfs_attrlist_cursor_kern cursor; /* position in list */
  48. void *buffer; /* output buffer */
  49. /*
  50. * Abort attribute list iteration if non-zero. Can be used to pass
  51. * error values to the xfs_attr_list caller.
  52. */
  53. int seen_enough;
  54. bool allow_incomplete;
  55. ssize_t count; /* num used entries */
  56. int dupcnt; /* count dup hashvals seen */
  57. int bufsize; /* total buffer size */
  58. int firstu; /* first used byte in buffer */
  59. unsigned int attr_filter; /* XFS_ATTR_{ROOT,SECURE} */
  60. int resynch; /* T/F: resynch with cursor */
  61. put_listent_func_t put_listent; /* list output fmt function */
  62. int index; /* index into output buffer */
  63. };
  64. /*
  65. * ========================================================================
  66. * Structure used to pass context around among the delayed routines.
  67. * ========================================================================
  68. */
  69. /*
  70. * Below is a state machine diagram for attr remove operations. The XFS_DAS_*
  71. * states indicate places where the function would return -EAGAIN, and then
  72. * immediately resume from after being called by the calling function. States
  73. * marked as a "subroutine state" indicate that they belong to a subroutine, and
  74. * so the calling function needs to pass them back to that subroutine to allow
  75. * it to finish where it left off. But they otherwise do not have a role in the
  76. * calling function other than just passing through.
  77. *
  78. * xfs_attr_remove_iter()
  79. * │
  80. * v
  81. * have attr to remove? ──n──> done
  82. * │
  83. * y
  84. * │
  85. * v
  86. * are we short form? ──y──> xfs_attr_shortform_remove ──> done
  87. * │
  88. * n
  89. * │
  90. * V
  91. * are we leaf form? ──y──> xfs_attr_leaf_removename ──> done
  92. * │
  93. * n
  94. * │
  95. * V
  96. * ┌── need to setup state?
  97. * │ │
  98. * n y
  99. * │ │
  100. * │ v
  101. * │ find attr and get state
  102. * │ attr has remote blks? ──n─┐
  103. * │ │ v
  104. * │ │ find and invalidate
  105. * │ y the remote blocks.
  106. * │ │ mark attr incomplete
  107. * │ ├────────────────┘
  108. * └──────────┤
  109. * │
  110. * v
  111. * Have remote blks to remove? ───y─────┐
  112. * │ ^ remove the blks
  113. * │ │ │
  114. * │ │ v
  115. * │ XFS_DAS_RMTBLK <─n── done?
  116. * │ re-enter with │
  117. * │ one less blk to y
  118. * │ remove │
  119. * │ V
  120. * │ refill the state
  121. * n │
  122. * │ v
  123. * │ XFS_DAS_RM_NAME
  124. * │ │
  125. * ├─────────────────────────┘
  126. * │
  127. * v
  128. * remove leaf and
  129. * update hash with
  130. * xfs_attr_node_remove_cleanup
  131. * │
  132. * v
  133. * need to
  134. * shrink tree? ─n─┐
  135. * │ │
  136. * y │
  137. * │ │
  138. * v │
  139. * join leaf │
  140. * │ │
  141. * v │
  142. * XFS_DAS_RM_SHRINK │
  143. * │ │
  144. * v │
  145. * do the shrink │
  146. * │ │
  147. * v │
  148. * free state <──┘
  149. * │
  150. * v
  151. * done
  152. *
  153. *
  154. * Below is a state machine diagram for attr set operations.
  155. *
  156. * It seems the challenge with understanding this system comes from trying to
  157. * absorb the state machine all at once, when really one should only be looking
  158. * at it with in the context of a single function. Once a state sensitive
  159. * function is called, the idea is that it "takes ownership" of the
  160. * state machine. It isn't concerned with the states that may have belonged to
  161. * it's calling parent. Only the states relevant to itself or any other
  162. * subroutines there in. Once a calling function hands off the state machine to
  163. * a subroutine, it needs to respect the simple rule that it doesn't "own" the
  164. * state machine anymore, and it's the responsibility of that calling function
  165. * to propagate the -EAGAIN back up the call stack. Upon reentry, it is
  166. * committed to re-calling that subroutine until it returns something other than
  167. * -EAGAIN. Once that subroutine signals completion (by returning anything other
  168. * than -EAGAIN), the calling function can resume using the state machine.
  169. *
  170. * xfs_attr_set_iter()
  171. * │
  172. * v
  173. * ┌─y─ has an attr fork?
  174. * │ |
  175. * │ n
  176. * │ |
  177. * │ V
  178. * │ add a fork
  179. * │ │
  180. * └──────────┤
  181. * │
  182. * V
  183. * ┌─── is shortform?
  184. * │ │
  185. * │ y
  186. * │ │
  187. * │ V
  188. * │ xfs_attr_set_fmt
  189. * │ |
  190. * │ V
  191. * │ xfs_attr_try_sf_addname
  192. * │ │
  193. * │ V
  194. * │ had enough ──y──> done
  195. * │ space?
  196. * n │
  197. * │ n
  198. * │ │
  199. * │ V
  200. * │ transform to leaf
  201. * │ │
  202. * │ V
  203. * │ hold the leaf buffer
  204. * │ │
  205. * │ V
  206. * │ return -EAGAIN
  207. * │ Re-enter in
  208. * │ leaf form
  209. * │
  210. * └─> release leaf buffer
  211. * if needed
  212. * │
  213. * V
  214. * ┌───n── fork has
  215. * │ only 1 blk?
  216. * │ │
  217. * │ y
  218. * │ │
  219. * │ v
  220. * │ xfs_attr_leaf_try_add()
  221. * │ │
  222. * │ v
  223. * │ had enough ──────────────y─────────────┐
  224. * │ space? │
  225. * │ │ │
  226. * │ n │
  227. * │ │ │
  228. * │ v │
  229. * │ return -EAGAIN │
  230. * │ re-enter in │
  231. * │ node form │
  232. * │ │ │
  233. * └──────────┤ │
  234. * │ │
  235. * V │
  236. * xfs_attr_node_addname_find_attr │
  237. * determines if this │
  238. * is create or rename │
  239. * find space to store attr │
  240. * │ │
  241. * v │
  242. * xfs_attr_node_addname │
  243. * │ │
  244. * v │
  245. * fits in a node leaf? ────n─────┐ │
  246. * │ ^ v │
  247. * │ │ single leaf node? │
  248. * │ │ │ │ │
  249. * y │ y n │
  250. * │ │ │ │ │
  251. * v │ v v │
  252. * update │ grow the leaf split if │
  253. * hashvals └── return -EAGAIN needed │
  254. * │ retry leaf add │ │
  255. * │ on reentry │ │
  256. * ├────────────────────────────┘ │
  257. * │ │
  258. * v │
  259. * need to alloc │
  260. * ┌─y── or flip flag? │
  261. * │ │ │
  262. * │ n │
  263. * │ │ │
  264. * │ v │
  265. * │ done │
  266. * │ │
  267. * │ │
  268. * │ XFS_DAS_FOUND_LBLK <────────────────┘
  269. * │ │
  270. * │ V
  271. * │ xfs_attr_leaf_addname()
  272. * │ │
  273. * │ v
  274. * │ ┌──first time through?
  275. * │ │ │
  276. * │ │ y
  277. * │ │ │
  278. * │ n v
  279. * │ │ if we have rmt blks
  280. * │ │ find space for them
  281. * │ │ │
  282. * │ └──────────┤
  283. * │ │
  284. * │ v
  285. * │ still have
  286. * │ ┌─n─ blks to alloc? <──┐
  287. * │ │ │ │
  288. * │ │ y │
  289. * │ │ │ │
  290. * │ │ v │
  291. * │ │ alloc one blk │
  292. * │ │ return -EAGAIN ──┘
  293. * │ │ re-enter with one
  294. * │ │ less blk to alloc
  295. * │ │
  296. * │ │
  297. * │ └───> set the rmt
  298. * │ value
  299. * │ │
  300. * │ v
  301. * │ was this
  302. * │ a rename? ──n─┐
  303. * │ │ │
  304. * │ y │
  305. * │ │ │
  306. * │ v │
  307. * │ flip incomplete │
  308. * │ flag │
  309. * │ │ │
  310. * │ v │
  311. * │ XFS_DAS_FLIP_LFLAG │
  312. * │ │ │
  313. * │ v │
  314. * │ need to remove │
  315. * │ old bks? ──n──┤
  316. * │ │ │
  317. * │ y │
  318. * │ │ │
  319. * │ V │
  320. * │ remove │
  321. * │ ┌───> old blks │
  322. * │ │ │ │
  323. * │ XFS_DAS_RM_LBLK │ │
  324. * │ ^ │ │
  325. * │ │ v │
  326. * │ └──y── more to │
  327. * │ remove? │
  328. * │ │ │
  329. * │ n │
  330. * │ │ │
  331. * │ v │
  332. * │ XFS_DAS_RD_LEAF │
  333. * │ │ │
  334. * │ v │
  335. * │ remove leaf │
  336. * │ │ │
  337. * │ v │
  338. * │ shrink to sf │
  339. * │ if needed │
  340. * │ │ │
  341. * │ v │
  342. * │ done <──────┘
  343. * │
  344. * └──────> XFS_DAS_FOUND_NBLK
  345. * │
  346. * v
  347. * ┌─────n── need to
  348. * │ alloc blks?
  349. * │ │
  350. * │ y
  351. * │ │
  352. * │ v
  353. * │ find space
  354. * │ │
  355. * │ v
  356. * │ ┌─>XFS_DAS_ALLOC_NODE
  357. * │ │ │
  358. * │ │ v
  359. * │ │ alloc blk
  360. * │ │ │
  361. * │ │ v
  362. * │ └──y── need to alloc
  363. * │ more blocks?
  364. * │ │
  365. * │ n
  366. * │ │
  367. * │ v
  368. * │ set the rmt value
  369. * │ │
  370. * │ v
  371. * │ was this
  372. * └────────> a rename? ──n─┐
  373. * │ │
  374. * y │
  375. * │ │
  376. * v │
  377. * flip incomplete │
  378. * flag │
  379. * │ │
  380. * v │
  381. * XFS_DAS_FLIP_NFLAG │
  382. * │ │
  383. * v │
  384. * need to │
  385. * remove blks? ─n──┤
  386. * │ │
  387. * y │
  388. * │ │
  389. * v │
  390. * remove │
  391. * ┌────────> old blks │
  392. * │ │ │
  393. * XFS_DAS_RM_NBLK │ │
  394. * ^ │ │
  395. * │ v │
  396. * └──────y── more to │
  397. * remove │
  398. * │ │
  399. * n │
  400. * │ │
  401. * v │
  402. * XFS_DAS_CLR_FLAG │
  403. * │ │
  404. * v │
  405. * clear flags │
  406. * │ │
  407. * ├──────────┘
  408. * │
  409. * v
  410. * done
  411. */
  412. /*
  413. * Enum values for xfs_attr_intent.xattri_da_state
  414. *
  415. * These values are used by delayed attribute operations to keep track of where
  416. * they were before they returned -EAGAIN. A return code of -EAGAIN signals the
  417. * calling function to roll the transaction, and then call the subroutine to
  418. * finish the operation. The enum is then used by the subroutine to jump back
  419. * to where it was and resume executing where it left off.
  420. */
  421. enum xfs_delattr_state {
  422. XFS_DAS_UNINIT = 0, /* No state has been set yet */
  423. /*
  424. * Initial sequence states. The replace setup code relies on the
  425. * ADD and REMOVE states for a specific format to be sequential so
  426. * that we can transform the initial operation to be performed
  427. * according to the xfs_has_larp() state easily.
  428. */
  429. XFS_DAS_SF_ADD, /* Initial sf add state */
  430. XFS_DAS_SF_REMOVE, /* Initial sf replace/remove state */
  431. XFS_DAS_LEAF_ADD, /* Initial leaf add state */
  432. XFS_DAS_LEAF_REMOVE, /* Initial leaf replace/remove state */
  433. XFS_DAS_NODE_ADD, /* Initial node add state */
  434. XFS_DAS_NODE_REMOVE, /* Initial node replace/remove state */
  435. /* Leaf state set/replace/remove sequence */
  436. XFS_DAS_LEAF_SET_RMT, /* set a remote xattr from a leaf */
  437. XFS_DAS_LEAF_ALLOC_RMT, /* We are allocating remote blocks */
  438. XFS_DAS_LEAF_REPLACE, /* Perform replace ops on a leaf */
  439. XFS_DAS_LEAF_REMOVE_OLD, /* Start removing old attr from leaf */
  440. XFS_DAS_LEAF_REMOVE_RMT, /* A rename is removing remote blocks */
  441. XFS_DAS_LEAF_REMOVE_ATTR, /* Remove the old attr from a leaf */
  442. /* Node state sequence, must match leaf state above */
  443. XFS_DAS_NODE_SET_RMT, /* set a remote xattr from a node */
  444. XFS_DAS_NODE_ALLOC_RMT, /* We are allocating remote blocks */
  445. XFS_DAS_NODE_REPLACE, /* Perform replace ops on a node */
  446. XFS_DAS_NODE_REMOVE_OLD, /* Start removing old attr from node */
  447. XFS_DAS_NODE_REMOVE_RMT, /* A rename is removing remote blocks */
  448. XFS_DAS_NODE_REMOVE_ATTR, /* Remove the old attr from a node */
  449. XFS_DAS_DONE, /* finished operation */
  450. };
  451. #define XFS_DAS_STRINGS \
  452. { XFS_DAS_UNINIT, "XFS_DAS_UNINIT" }, \
  453. { XFS_DAS_SF_ADD, "XFS_DAS_SF_ADD" }, \
  454. { XFS_DAS_SF_REMOVE, "XFS_DAS_SF_REMOVE" }, \
  455. { XFS_DAS_LEAF_ADD, "XFS_DAS_LEAF_ADD" }, \
  456. { XFS_DAS_LEAF_REMOVE, "XFS_DAS_LEAF_REMOVE" }, \
  457. { XFS_DAS_NODE_ADD, "XFS_DAS_NODE_ADD" }, \
  458. { XFS_DAS_NODE_REMOVE, "XFS_DAS_NODE_REMOVE" }, \
  459. { XFS_DAS_LEAF_SET_RMT, "XFS_DAS_LEAF_SET_RMT" }, \
  460. { XFS_DAS_LEAF_ALLOC_RMT, "XFS_DAS_LEAF_ALLOC_RMT" }, \
  461. { XFS_DAS_LEAF_REPLACE, "XFS_DAS_LEAF_REPLACE" }, \
  462. { XFS_DAS_LEAF_REMOVE_OLD, "XFS_DAS_LEAF_REMOVE_OLD" }, \
  463. { XFS_DAS_LEAF_REMOVE_RMT, "XFS_DAS_LEAF_REMOVE_RMT" }, \
  464. { XFS_DAS_LEAF_REMOVE_ATTR, "XFS_DAS_LEAF_REMOVE_ATTR" }, \
  465. { XFS_DAS_NODE_SET_RMT, "XFS_DAS_NODE_SET_RMT" }, \
  466. { XFS_DAS_NODE_ALLOC_RMT, "XFS_DAS_NODE_ALLOC_RMT" }, \
  467. { XFS_DAS_NODE_REPLACE, "XFS_DAS_NODE_REPLACE" }, \
  468. { XFS_DAS_NODE_REMOVE_OLD, "XFS_DAS_NODE_REMOVE_OLD" }, \
  469. { XFS_DAS_NODE_REMOVE_RMT, "XFS_DAS_NODE_REMOVE_RMT" }, \
  470. { XFS_DAS_NODE_REMOVE_ATTR, "XFS_DAS_NODE_REMOVE_ATTR" }, \
  471. { XFS_DAS_DONE, "XFS_DAS_DONE" }
  472. struct xfs_attri_log_nameval;
  473. /*
  474. * Context used for keeping track of delayed attribute operations
  475. */
  476. struct xfs_attr_intent {
  477. /*
  478. * used to log this item to an intent containing a list of attrs to
  479. * commit later
  480. */
  481. struct list_head xattri_list;
  482. /* Used in xfs_attr_node_removename to roll through removing blocks */
  483. struct xfs_da_state *xattri_da_state;
  484. struct xfs_da_args *xattri_da_args;
  485. /*
  486. * Shared buffer containing the attr name and value so that the logging
  487. * code can share large memory buffers between log items.
  488. */
  489. struct xfs_attri_log_nameval *xattri_nameval;
  490. /* Used to keep track of current state of delayed operation */
  491. enum xfs_delattr_state xattri_dela_state;
  492. /*
  493. * Attr operation being performed - XFS_ATTRI_OP_FLAGS_*
  494. */
  495. unsigned int xattri_op_flags;
  496. /* Used in xfs_attr_rmtval_set_blk to roll through allocating blocks */
  497. xfs_dablk_t xattri_lblkno;
  498. int xattri_blkcnt;
  499. struct xfs_bmbt_irec xattri_map;
  500. };
  501. /*========================================================================
  502. * Function prototypes for the kernel.
  503. *========================================================================*/
  504. /*
  505. * Overall external interface routines.
  506. */
  507. int xfs_attr_inactive(struct xfs_inode *dp);
  508. int xfs_attr_list_ilocked(struct xfs_attr_list_context *);
  509. int xfs_attr_list(struct xfs_attr_list_context *);
  510. int xfs_inode_hasattr(struct xfs_inode *ip);
  511. bool xfs_attr_is_leaf(struct xfs_inode *ip);
  512. int xfs_attr_get_ilocked(struct xfs_da_args *args);
  513. int xfs_attr_get(struct xfs_da_args *args);
  514. int xfs_attr_set(struct xfs_da_args *args);
  515. int xfs_attr_set_iter(struct xfs_attr_intent *attr);
  516. int xfs_attr_remove_iter(struct xfs_attr_intent *attr);
  517. bool xfs_attr_namecheck(const void *name, size_t length);
  518. int xfs_attr_calc_size(struct xfs_da_args *args, int *local);
  519. void xfs_init_attr_trans(struct xfs_da_args *args, struct xfs_trans_res *tres,
  520. unsigned int *total);
  521. /*
  522. * Check to see if the attr should be upgraded from non-existent or shortform to
  523. * single-leaf-block attribute list.
  524. */
  525. static inline bool
  526. xfs_attr_is_shortform(
  527. struct xfs_inode *ip)
  528. {
  529. return ip->i_af.if_format == XFS_DINODE_FMT_LOCAL ||
  530. (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
  531. ip->i_af.if_nextents == 0);
  532. }
  533. static inline enum xfs_delattr_state
  534. xfs_attr_init_add_state(struct xfs_da_args *args)
  535. {
  536. /*
  537. * When called from the completion of a attr remove to determine the
  538. * next state, the attribute fork may be null. This can occur only occur
  539. * on a pure remove, but we grab the next state before we check if a
  540. * replace operation is being performed. If we are called from any other
  541. * context, i_af is guaranteed to exist. Hence if the attr fork is
  542. * null, we were called from a pure remove operation and so we are done.
  543. */
  544. if (!xfs_inode_has_attr_fork(args->dp))
  545. return XFS_DAS_DONE;
  546. args->op_flags |= XFS_DA_OP_ADDNAME;
  547. if (xfs_attr_is_shortform(args->dp))
  548. return XFS_DAS_SF_ADD;
  549. if (xfs_attr_is_leaf(args->dp))
  550. return XFS_DAS_LEAF_ADD;
  551. return XFS_DAS_NODE_ADD;
  552. }
  553. static inline enum xfs_delattr_state
  554. xfs_attr_init_remove_state(struct xfs_da_args *args)
  555. {
  556. args->op_flags |= XFS_DA_OP_REMOVE;
  557. if (xfs_attr_is_shortform(args->dp))
  558. return XFS_DAS_SF_REMOVE;
  559. if (xfs_attr_is_leaf(args->dp))
  560. return XFS_DAS_LEAF_REMOVE;
  561. return XFS_DAS_NODE_REMOVE;
  562. }
  563. /*
  564. * If we are logging the attributes, then we have to start with removal of the
  565. * old attribute so that there is always consistent state that we can recover
  566. * from if the system goes down part way through. We always log the new attr
  567. * value, so even when we remove the attr first we still have the information in
  568. * the log to finish the replace operation atomically.
  569. */
  570. static inline enum xfs_delattr_state
  571. xfs_attr_init_replace_state(struct xfs_da_args *args)
  572. {
  573. args->op_flags |= XFS_DA_OP_ADDNAME | XFS_DA_OP_REPLACE;
  574. if (args->op_flags & XFS_DA_OP_LOGGED)
  575. return xfs_attr_init_remove_state(args);
  576. return xfs_attr_init_add_state(args);
  577. }
  578. extern struct kmem_cache *xfs_attr_intent_cache;
  579. int __init xfs_attr_intent_init_cache(void);
  580. void xfs_attr_intent_destroy_cache(void);
  581. #endif /* __XFS_ATTR_H__ */