xfs_parent.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2022-2024 Oracle.
  4. * All rights reserved.
  5. */
  6. #include "xfs.h"
  7. #include "xfs_fs.h"
  8. #include "xfs_format.h"
  9. #include "xfs_da_format.h"
  10. #include "xfs_log_format.h"
  11. #include "xfs_shared.h"
  12. #include "xfs_trans_resv.h"
  13. #include "xfs_mount.h"
  14. #include "xfs_bmap_btree.h"
  15. #include "xfs_inode.h"
  16. #include "xfs_error.h"
  17. #include "xfs_trace.h"
  18. #include "xfs_trans.h"
  19. #include "xfs_da_btree.h"
  20. #include "xfs_attr.h"
  21. #include "xfs_dir2.h"
  22. #include "xfs_dir2_priv.h"
  23. #include "xfs_attr_sf.h"
  24. #include "xfs_bmap.h"
  25. #include "xfs_defer.h"
  26. #include "xfs_log.h"
  27. #include "xfs_xattr.h"
  28. #include "xfs_parent.h"
  29. #include "xfs_trans_space.h"
  30. #include "xfs_attr_item.h"
  31. #include "xfs_health.h"
  32. struct kmem_cache *xfs_parent_args_cache;
  33. /*
  34. * Parent pointer attribute handling.
  35. *
  36. * Because the attribute name is a filename component, it will never be longer
  37. * than 255 bytes and must not contain nulls or slashes. These are roughly the
  38. * same constraints that apply to attribute names.
  39. *
  40. * The attribute value must always be a struct xfs_parent_rec. This means the
  41. * attribute will never be in remote format because 12 bytes is nowhere near
  42. * xfs_attr_leaf_entsize_local_max() (~75% of block size).
  43. *
  44. * Creating a new parent attribute will always create a new attribute - there
  45. * should never, ever be an existing attribute in the tree for a new inode.
  46. * ENOSPC behavior is problematic - creating the inode without the parent
  47. * pointer is effectively a corruption, so we allow parent attribute creation
  48. * to dip into the reserve block pool to avoid unexpected ENOSPC errors from
  49. * occurring.
  50. */
  51. /* Return true if parent pointer attr name is valid. */
  52. bool
  53. xfs_parent_namecheck(
  54. unsigned int attr_flags,
  55. const void *name,
  56. size_t length)
  57. {
  58. /*
  59. * Parent pointers always use logged operations, so there should never
  60. * be incomplete xattrs.
  61. */
  62. if (attr_flags & XFS_ATTR_INCOMPLETE)
  63. return false;
  64. return xfs_dir2_namecheck(name, length);
  65. }
  66. /* Return true if parent pointer attr value is valid. */
  67. bool
  68. xfs_parent_valuecheck(
  69. struct xfs_mount *mp,
  70. const void *value,
  71. size_t valuelen)
  72. {
  73. const struct xfs_parent_rec *rec = value;
  74. if (!xfs_has_parent(mp))
  75. return false;
  76. /* The xattr value must be a parent record. */
  77. if (valuelen != sizeof(struct xfs_parent_rec))
  78. return false;
  79. /* The parent record must be local. */
  80. if (value == NULL)
  81. return false;
  82. /* The parent inumber must be valid. */
  83. if (!xfs_verify_dir_ino(mp, be64_to_cpu(rec->p_ino)))
  84. return false;
  85. return true;
  86. }
  87. /* Compute the attribute name hash for a parent pointer. */
  88. xfs_dahash_t
  89. xfs_parent_hashval(
  90. struct xfs_mount *mp,
  91. const uint8_t *name,
  92. int namelen,
  93. xfs_ino_t parent_ino)
  94. {
  95. struct xfs_name xname = {
  96. .name = name,
  97. .len = namelen,
  98. };
  99. /*
  100. * Use the same dirent name hash as would be used on the directory, but
  101. * mix in the parent inode number to avoid collisions on hardlinked
  102. * files with identical names but different parents.
  103. */
  104. return xfs_dir2_hashname(mp, &xname) ^
  105. upper_32_bits(parent_ino) ^ lower_32_bits(parent_ino);
  106. }
  107. /* Compute the attribute name hash from the xattr components. */
  108. xfs_dahash_t
  109. xfs_parent_hashattr(
  110. struct xfs_mount *mp,
  111. const uint8_t *name,
  112. int namelen,
  113. const void *value,
  114. int valuelen)
  115. {
  116. const struct xfs_parent_rec *rec = value;
  117. /* Requires a local attr value in xfs_parent_rec format */
  118. if (valuelen != sizeof(struct xfs_parent_rec)) {
  119. ASSERT(valuelen == sizeof(struct xfs_parent_rec));
  120. return 0;
  121. }
  122. if (!value) {
  123. ASSERT(value != NULL);
  124. return 0;
  125. }
  126. return xfs_parent_hashval(mp, name, namelen, be64_to_cpu(rec->p_ino));
  127. }
  128. /*
  129. * Initialize the parent pointer arguments structure. Caller must have zeroed
  130. * the contents of @args. @tp is only required for updates.
  131. */
  132. static void
  133. xfs_parent_da_args_init(
  134. struct xfs_da_args *args,
  135. struct xfs_trans *tp,
  136. struct xfs_parent_rec *rec,
  137. struct xfs_inode *child,
  138. xfs_ino_t owner,
  139. const struct xfs_name *parent_name)
  140. {
  141. args->geo = child->i_mount->m_attr_geo;
  142. args->whichfork = XFS_ATTR_FORK;
  143. args->attr_filter = XFS_ATTR_PARENT;
  144. args->op_flags = XFS_DA_OP_LOGGED | XFS_DA_OP_OKNOENT;
  145. args->trans = tp;
  146. args->dp = child;
  147. args->owner = owner;
  148. args->name = parent_name->name;
  149. args->namelen = parent_name->len;
  150. args->value = rec;
  151. args->valuelen = sizeof(struct xfs_parent_rec);
  152. xfs_attr_sethash(args);
  153. }
  154. /* Make sure the incore state is ready for a parent pointer query/update. */
  155. static inline int
  156. xfs_parent_iread_extents(
  157. struct xfs_trans *tp,
  158. struct xfs_inode *child)
  159. {
  160. /* Parent pointers require that the attr fork must exist. */
  161. if (XFS_IS_CORRUPT(child->i_mount, !xfs_inode_has_attr_fork(child))) {
  162. xfs_inode_mark_sick(child, XFS_SICK_INO_PARENT);
  163. return -EFSCORRUPTED;
  164. }
  165. return xfs_iread_extents(tp, child, XFS_ATTR_FORK);
  166. }
  167. /* Add a parent pointer to reflect a dirent addition. */
  168. int
  169. xfs_parent_addname(
  170. struct xfs_trans *tp,
  171. struct xfs_parent_args *ppargs,
  172. struct xfs_inode *dp,
  173. const struct xfs_name *parent_name,
  174. struct xfs_inode *child)
  175. {
  176. int error;
  177. error = xfs_parent_iread_extents(tp, child);
  178. if (error)
  179. return error;
  180. xfs_inode_to_parent_rec(&ppargs->rec, dp);
  181. xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
  182. child->i_ino, parent_name);
  183. xfs_attr_defer_add(&ppargs->args, XFS_ATTR_DEFER_SET);
  184. return 0;
  185. }
  186. /* Remove a parent pointer to reflect a dirent removal. */
  187. int
  188. xfs_parent_removename(
  189. struct xfs_trans *tp,
  190. struct xfs_parent_args *ppargs,
  191. struct xfs_inode *dp,
  192. const struct xfs_name *parent_name,
  193. struct xfs_inode *child)
  194. {
  195. int error;
  196. error = xfs_parent_iread_extents(tp, child);
  197. if (error)
  198. return error;
  199. xfs_inode_to_parent_rec(&ppargs->rec, dp);
  200. xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
  201. child->i_ino, parent_name);
  202. xfs_attr_defer_add(&ppargs->args, XFS_ATTR_DEFER_REMOVE);
  203. return 0;
  204. }
  205. /* Replace one parent pointer with another to reflect a rename. */
  206. int
  207. xfs_parent_replacename(
  208. struct xfs_trans *tp,
  209. struct xfs_parent_args *ppargs,
  210. struct xfs_inode *old_dp,
  211. const struct xfs_name *old_name,
  212. struct xfs_inode *new_dp,
  213. const struct xfs_name *new_name,
  214. struct xfs_inode *child)
  215. {
  216. int error;
  217. error = xfs_parent_iread_extents(tp, child);
  218. if (error)
  219. return error;
  220. xfs_inode_to_parent_rec(&ppargs->rec, old_dp);
  221. xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
  222. child->i_ino, old_name);
  223. xfs_inode_to_parent_rec(&ppargs->new_rec, new_dp);
  224. ppargs->args.new_name = new_name->name;
  225. ppargs->args.new_namelen = new_name->len;
  226. ppargs->args.new_value = &ppargs->new_rec;
  227. ppargs->args.new_valuelen = sizeof(struct xfs_parent_rec);
  228. xfs_attr_defer_add(&ppargs->args, XFS_ATTR_DEFER_REPLACE);
  229. return 0;
  230. }
  231. /*
  232. * Extract parent pointer information from any parent pointer xattr into
  233. * @parent_ino/gen. The last two parameters can be NULL pointers.
  234. *
  235. * Returns 0 if this is not a parent pointer xattr at all; or -EFSCORRUPTED for
  236. * garbage.
  237. */
  238. int
  239. xfs_parent_from_attr(
  240. struct xfs_mount *mp,
  241. unsigned int attr_flags,
  242. const unsigned char *name,
  243. unsigned int namelen,
  244. const void *value,
  245. unsigned int valuelen,
  246. xfs_ino_t *parent_ino,
  247. uint32_t *parent_gen)
  248. {
  249. const struct xfs_parent_rec *rec = value;
  250. ASSERT(attr_flags & XFS_ATTR_PARENT);
  251. if (!xfs_parent_namecheck(attr_flags, name, namelen))
  252. return -EFSCORRUPTED;
  253. if (!xfs_parent_valuecheck(mp, value, valuelen))
  254. return -EFSCORRUPTED;
  255. if (parent_ino)
  256. *parent_ino = be64_to_cpu(rec->p_ino);
  257. if (parent_gen)
  258. *parent_gen = be32_to_cpu(rec->p_gen);
  259. return 0;
  260. }
  261. /*
  262. * Look up a parent pointer record (@parent_name -> @pptr) of @ip.
  263. *
  264. * Caller must hold at least ILOCK_SHARED. The scratchpad need not be
  265. * initialized.
  266. *
  267. * Returns 0 if the pointer is found, -ENOATTR if there is no match, or a
  268. * negative errno.
  269. */
  270. int
  271. xfs_parent_lookup(
  272. struct xfs_trans *tp,
  273. struct xfs_inode *ip,
  274. const struct xfs_name *parent_name,
  275. struct xfs_parent_rec *pptr,
  276. struct xfs_da_args *scratch)
  277. {
  278. memset(scratch, 0, sizeof(struct xfs_da_args));
  279. xfs_parent_da_args_init(scratch, tp, pptr, ip, ip->i_ino, parent_name);
  280. return xfs_attr_get_ilocked(scratch);
  281. }
  282. /* Sanity-check a parent pointer before we try to perform repairs. */
  283. static inline bool
  284. xfs_parent_sanity_check(
  285. struct xfs_mount *mp,
  286. const struct xfs_name *parent_name,
  287. const struct xfs_parent_rec *pptr)
  288. {
  289. if (!xfs_parent_namecheck(XFS_ATTR_PARENT, parent_name->name,
  290. parent_name->len))
  291. return false;
  292. if (!xfs_parent_valuecheck(mp, pptr, sizeof(*pptr)))
  293. return false;
  294. return true;
  295. }
  296. /*
  297. * Attach the parent pointer (@parent_name -> @pptr) to @ip immediately.
  298. * Caller must not have a transaction or hold the ILOCK. This is for
  299. * specialized repair functions only. The scratchpad need not be initialized.
  300. */
  301. int
  302. xfs_parent_set(
  303. struct xfs_inode *ip,
  304. xfs_ino_t owner,
  305. const struct xfs_name *parent_name,
  306. struct xfs_parent_rec *pptr,
  307. struct xfs_da_args *scratch)
  308. {
  309. if (!xfs_parent_sanity_check(ip->i_mount, parent_name, pptr)) {
  310. ASSERT(0);
  311. return -EFSCORRUPTED;
  312. }
  313. memset(scratch, 0, sizeof(struct xfs_da_args));
  314. xfs_parent_da_args_init(scratch, NULL, pptr, ip, owner, parent_name);
  315. return xfs_attr_set(scratch, XFS_ATTRUPDATE_CREATE, false);
  316. }
  317. /*
  318. * Remove the parent pointer (@parent_name -> @pptr) from @ip immediately.
  319. * Caller must not have a transaction or hold the ILOCK. This is for
  320. * specialized repair functions only. The scratchpad need not be initialized.
  321. */
  322. int
  323. xfs_parent_unset(
  324. struct xfs_inode *ip,
  325. xfs_ino_t owner,
  326. const struct xfs_name *parent_name,
  327. struct xfs_parent_rec *pptr,
  328. struct xfs_da_args *scratch)
  329. {
  330. if (!xfs_parent_sanity_check(ip->i_mount, parent_name, pptr)) {
  331. ASSERT(0);
  332. return -EFSCORRUPTED;
  333. }
  334. memset(scratch, 0, sizeof(struct xfs_da_args));
  335. xfs_parent_da_args_init(scratch, NULL, pptr, ip, owner, parent_name);
  336. return xfs_attr_set(scratch, XFS_ATTRUPDATE_REMOVE, false);
  337. }