nlinks_repair.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (c) 2021-2024 Oracle. All Rights Reserved.
  4. * Author: Darrick J. Wong <djwong@kernel.org>
  5. */
  6. #include "xfs.h"
  7. #include "xfs_fs.h"
  8. #include "xfs_shared.h"
  9. #include "xfs_format.h"
  10. #include "xfs_trans_resv.h"
  11. #include "xfs_mount.h"
  12. #include "xfs_log_format.h"
  13. #include "xfs_trans.h"
  14. #include "xfs_inode.h"
  15. #include "xfs_icache.h"
  16. #include "xfs_bmap_util.h"
  17. #include "xfs_iwalk.h"
  18. #include "xfs_ialloc.h"
  19. #include "xfs_sb.h"
  20. #include "xfs_ag.h"
  21. #include "xfs_dir2.h"
  22. #include "xfs_parent.h"
  23. #include "scrub/scrub.h"
  24. #include "scrub/common.h"
  25. #include "scrub/repair.h"
  26. #include "scrub/xfile.h"
  27. #include "scrub/xfarray.h"
  28. #include "scrub/iscan.h"
  29. #include "scrub/orphanage.h"
  30. #include "scrub/nlinks.h"
  31. #include "scrub/trace.h"
  32. #include "scrub/tempfile.h"
  33. /*
  34. * Live Inode Link Count Repair
  35. * ============================
  36. *
  37. * Use the live inode link count information that we collected to replace the
  38. * nlink values of the incore inodes. A scrub->repair cycle should have left
  39. * the live data and hooks active, so this is safe so long as we make sure the
  40. * inode is locked.
  41. */
  42. /* Set up to repair inode link counts. */
  43. int
  44. xrep_setup_nlinks(
  45. struct xfs_scrub *sc)
  46. {
  47. return xrep_orphanage_try_create(sc);
  48. }
  49. /*
  50. * Inodes that aren't the root directory or the orphanage, have a nonzero link
  51. * count, and no observed parents should be moved to the orphanage.
  52. */
  53. static inline bool
  54. xrep_nlinks_is_orphaned(
  55. struct xfs_scrub *sc,
  56. struct xfs_inode *ip,
  57. unsigned int actual_nlink,
  58. const struct xchk_nlink *obs)
  59. {
  60. struct xfs_mount *mp = ip->i_mount;
  61. if (obs->parents != 0)
  62. return false;
  63. if (ip == mp->m_rootip || ip == sc->orphanage)
  64. return false;
  65. return actual_nlink != 0;
  66. }
  67. /* Remove an inode from the unlinked list. */
  68. STATIC int
  69. xrep_nlinks_iunlink_remove(
  70. struct xfs_scrub *sc)
  71. {
  72. struct xfs_perag *pag;
  73. int error;
  74. pag = xfs_perag_get(sc->mp, XFS_INO_TO_AGNO(sc->mp, sc->ip->i_ino));
  75. error = xfs_iunlink_remove(sc->tp, pag, sc->ip);
  76. xfs_perag_put(pag);
  77. return error;
  78. }
  79. /*
  80. * Correct the link count of the given inode. Because we have to grab locks
  81. * and resources in a certain order, it's possible that this will be a no-op.
  82. */
  83. STATIC int
  84. xrep_nlinks_repair_inode(
  85. struct xchk_nlink_ctrs *xnc)
  86. {
  87. struct xchk_nlink obs;
  88. struct xfs_scrub *sc = xnc->sc;
  89. struct xfs_mount *mp = sc->mp;
  90. struct xfs_inode *ip = sc->ip;
  91. uint64_t total_links;
  92. uint64_t actual_nlink;
  93. bool orphanage_available = false;
  94. bool dirty = false;
  95. int error;
  96. /*
  97. * Ignore temporary files being used to stage repairs, since we assume
  98. * they're correct for non-directories, and the directory repair code
  99. * doesn't bump the link counts for the children.
  100. */
  101. if (xrep_is_tempfile(ip))
  102. return 0;
  103. /*
  104. * If the filesystem has an orphanage attached to the scrub context,
  105. * prepare for a link count repair that could involve @ip being adopted
  106. * by the lost+found.
  107. */
  108. if (xrep_orphanage_can_adopt(sc)) {
  109. error = xrep_orphanage_iolock_two(sc);
  110. if (error)
  111. return error;
  112. error = xrep_adoption_trans_alloc(sc, &xnc->adoption);
  113. if (error) {
  114. xchk_iunlock(sc, XFS_IOLOCK_EXCL);
  115. xrep_orphanage_iunlock(sc, XFS_IOLOCK_EXCL);
  116. } else {
  117. orphanage_available = true;
  118. }
  119. }
  120. /*
  121. * Either there is no orphanage or we couldn't allocate resources for
  122. * that kind of update. Let's try again with only the resources we
  123. * need for a simple link count update, since that's much more common.
  124. */
  125. if (!orphanage_available) {
  126. xchk_ilock(sc, XFS_IOLOCK_EXCL);
  127. error = xfs_trans_alloc(mp, &M_RES(mp)->tr_link, 0, 0, 0,
  128. &sc->tp);
  129. if (error) {
  130. xchk_iunlock(sc, XFS_IOLOCK_EXCL);
  131. return error;
  132. }
  133. xchk_ilock(sc, XFS_ILOCK_EXCL);
  134. xfs_trans_ijoin(sc->tp, ip, 0);
  135. }
  136. mutex_lock(&xnc->lock);
  137. if (xchk_iscan_aborted(&xnc->collect_iscan)) {
  138. error = -ECANCELED;
  139. goto out_scanlock;
  140. }
  141. error = xfarray_load_sparse(xnc->nlinks, ip->i_ino, &obs);
  142. if (error)
  143. goto out_scanlock;
  144. /*
  145. * We're done accessing the shared scan data, so we can drop the lock.
  146. * We still hold @ip's ILOCK, so its link count cannot change.
  147. */
  148. mutex_unlock(&xnc->lock);
  149. total_links = xchk_nlink_total(ip, &obs);
  150. actual_nlink = VFS_I(ip)->i_nlink;
  151. /*
  152. * Non-directories cannot have directories pointing up to them.
  153. *
  154. * We previously set error to zero, but set it again because one static
  155. * checker author fears that programmers will fail to maintain this
  156. * invariant and built their tool to flag this as a security risk. A
  157. * different tool author made their bot complain about the redundant
  158. * store. This is a never-ending and stupid battle; both tools missed
  159. * *actual bugs* elsewhere; and I no longer care.
  160. */
  161. if (!S_ISDIR(VFS_I(ip)->i_mode) && obs.children != 0) {
  162. trace_xrep_nlinks_unfixable_inode(mp, ip, &obs);
  163. error = 0;
  164. goto out_trans;
  165. }
  166. /*
  167. * Decide if we're going to move this file to the orphanage, and fix
  168. * up the incore link counts if we are.
  169. */
  170. if (orphanage_available &&
  171. xrep_nlinks_is_orphaned(sc, ip, actual_nlink, &obs)) {
  172. /* Figure out what name we're going to use here. */
  173. error = xrep_adoption_compute_name(&xnc->adoption, &xnc->xname);
  174. if (error)
  175. goto out_trans;
  176. /*
  177. * Reattach this file to the directory tree by moving it to
  178. * the orphanage per the adoption parameters that we already
  179. * computed.
  180. */
  181. error = xrep_adoption_move(&xnc->adoption);
  182. if (error)
  183. goto out_trans;
  184. /*
  185. * Re-read the link counts since the reparenting will have
  186. * updated our scan info.
  187. */
  188. mutex_lock(&xnc->lock);
  189. error = xfarray_load_sparse(xnc->nlinks, ip->i_ino, &obs);
  190. mutex_unlock(&xnc->lock);
  191. if (error)
  192. goto out_trans;
  193. total_links = xchk_nlink_total(ip, &obs);
  194. actual_nlink = VFS_I(ip)->i_nlink;
  195. dirty = true;
  196. }
  197. /*
  198. * If this inode is linked from the directory tree and on the unlinked
  199. * list, remove it from the unlinked list.
  200. */
  201. if (total_links > 0 && xfs_inode_on_unlinked_list(ip)) {
  202. error = xrep_nlinks_iunlink_remove(sc);
  203. if (error)
  204. goto out_trans;
  205. dirty = true;
  206. }
  207. /*
  208. * If this inode is not linked from the directory tree yet not on the
  209. * unlinked list, put it on the unlinked list.
  210. */
  211. if (total_links == 0 && !xfs_inode_on_unlinked_list(ip)) {
  212. error = xfs_iunlink(sc->tp, ip);
  213. if (error)
  214. goto out_trans;
  215. dirty = true;
  216. }
  217. /* Commit the new link count if it changed. */
  218. if (total_links != actual_nlink) {
  219. trace_xrep_nlinks_update_inode(mp, ip, &obs);
  220. set_nlink(VFS_I(ip), min_t(unsigned long long, total_links,
  221. XFS_NLINK_PINNED));
  222. dirty = true;
  223. }
  224. if (!dirty) {
  225. error = 0;
  226. goto out_trans;
  227. }
  228. xfs_trans_log_inode(sc->tp, ip, XFS_ILOG_CORE);
  229. error = xrep_trans_commit(sc);
  230. goto out_unlock;
  231. out_scanlock:
  232. mutex_unlock(&xnc->lock);
  233. out_trans:
  234. xchk_trans_cancel(sc);
  235. out_unlock:
  236. xchk_iunlock(sc, XFS_ILOCK_EXCL);
  237. if (orphanage_available) {
  238. xrep_orphanage_iunlock(sc, XFS_ILOCK_EXCL);
  239. xrep_orphanage_iunlock(sc, XFS_IOLOCK_EXCL);
  240. }
  241. xchk_iunlock(sc, XFS_IOLOCK_EXCL);
  242. return error;
  243. }
  244. /*
  245. * Try to visit every inode in the filesystem for repairs. Move on if we can't
  246. * grab an inode, since we're still making forward progress.
  247. */
  248. static int
  249. xrep_nlinks_iter(
  250. struct xchk_nlink_ctrs *xnc,
  251. struct xfs_inode **ipp)
  252. {
  253. int error;
  254. do {
  255. error = xchk_iscan_iter(&xnc->compare_iscan, ipp);
  256. } while (error == -EBUSY);
  257. return error;
  258. }
  259. /* Commit the new inode link counters. */
  260. int
  261. xrep_nlinks(
  262. struct xfs_scrub *sc)
  263. {
  264. struct xchk_nlink_ctrs *xnc = sc->buf;
  265. int error;
  266. /*
  267. * We need ftype for an accurate count of the number of child
  268. * subdirectory links. Child subdirectories with a back link (dotdot
  269. * entry) but no forward link are moved to the orphanage, so we cannot
  270. * repair the link count of the parent directory based on the back link
  271. * count alone. Filesystems without ftype support are rare (old V4) so
  272. * we just skip out here.
  273. */
  274. if (!xfs_has_ftype(sc->mp))
  275. return -EOPNOTSUPP;
  276. /*
  277. * Use the inobt to walk all allocated inodes to compare and fix the
  278. * link counts. Retry iget every tenth of a second for up to 30
  279. * seconds -- even if repair misses a few inodes, we still try to fix
  280. * as many of them as we can.
  281. */
  282. xchk_iscan_start(sc, 30000, 100, &xnc->compare_iscan);
  283. ASSERT(sc->ip == NULL);
  284. while ((error = xrep_nlinks_iter(xnc, &sc->ip)) == 1) {
  285. /*
  286. * Commit the scrub transaction so that we can create repair
  287. * transactions with the correct reservations.
  288. */
  289. xchk_trans_cancel(sc);
  290. error = xrep_nlinks_repair_inode(xnc);
  291. xchk_iscan_mark_visited(&xnc->compare_iscan, sc->ip);
  292. xchk_irele(sc, sc->ip);
  293. sc->ip = NULL;
  294. if (error)
  295. break;
  296. if (xchk_should_terminate(sc, &error))
  297. break;
  298. /*
  299. * Create a new empty transaction so that we can advance the
  300. * iscan cursor without deadlocking if the inobt has a cycle.
  301. * We can only push the inactivation workqueues with an empty
  302. * transaction.
  303. */
  304. error = xchk_trans_alloc_empty(sc);
  305. if (error)
  306. break;
  307. }
  308. xchk_iscan_iter_finish(&xnc->compare_iscan);
  309. xchk_iscan_teardown(&xnc->compare_iscan);
  310. return error;
  311. }