parent.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2017 Oracle. All Rights Reserved.
  4. * Author: Darrick J. Wong <darrick.wong@oracle.com>
  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_defer.h"
  13. #include "xfs_btree.h"
  14. #include "xfs_bit.h"
  15. #include "xfs_log_format.h"
  16. #include "xfs_trans.h"
  17. #include "xfs_sb.h"
  18. #include "xfs_inode.h"
  19. #include "xfs_icache.h"
  20. #include "xfs_dir2.h"
  21. #include "xfs_dir2_priv.h"
  22. #include "xfs_ialloc.h"
  23. #include "scrub/xfs_scrub.h"
  24. #include "scrub/scrub.h"
  25. #include "scrub/common.h"
  26. #include "scrub/trace.h"
  27. /* Set us up to scrub parents. */
  28. int
  29. xchk_setup_parent(
  30. struct xfs_scrub *sc,
  31. struct xfs_inode *ip)
  32. {
  33. return xchk_setup_inode_contents(sc, ip, 0);
  34. }
  35. /* Parent pointers */
  36. /* Look for an entry in a parent pointing to this inode. */
  37. struct xchk_parent_ctx {
  38. struct dir_context dc;
  39. xfs_ino_t ino;
  40. xfs_nlink_t nlink;
  41. };
  42. /* Look for a single entry in a directory pointing to an inode. */
  43. STATIC int
  44. xchk_parent_actor(
  45. struct dir_context *dc,
  46. const char *name,
  47. int namelen,
  48. loff_t pos,
  49. u64 ino,
  50. unsigned type)
  51. {
  52. struct xchk_parent_ctx *spc;
  53. spc = container_of(dc, struct xchk_parent_ctx, dc);
  54. if (spc->ino == ino)
  55. spc->nlink++;
  56. return 0;
  57. }
  58. /* Count the number of dentries in the parent dir that point to this inode. */
  59. STATIC int
  60. xchk_parent_count_parent_dentries(
  61. struct xfs_scrub *sc,
  62. struct xfs_inode *parent,
  63. xfs_nlink_t *nlink)
  64. {
  65. struct xchk_parent_ctx spc = {
  66. .dc.actor = xchk_parent_actor,
  67. .dc.pos = 0,
  68. .ino = sc->ip->i_ino,
  69. .nlink = 0,
  70. };
  71. size_t bufsize;
  72. loff_t oldpos;
  73. uint lock_mode;
  74. int error = 0;
  75. /*
  76. * If there are any blocks, read-ahead block 0 as we're almost
  77. * certain to have the next operation be a read there. This is
  78. * how we guarantee that the parent's extent map has been loaded,
  79. * if there is one.
  80. */
  81. lock_mode = xfs_ilock_data_map_shared(parent);
  82. if (parent->i_d.di_nextents > 0)
  83. error = xfs_dir3_data_readahead(parent, 0, -1);
  84. xfs_iunlock(parent, lock_mode);
  85. if (error)
  86. return error;
  87. /*
  88. * Iterate the parent dir to confirm that there is
  89. * exactly one entry pointing back to the inode being
  90. * scanned.
  91. */
  92. bufsize = (size_t)min_t(loff_t, XFS_READDIR_BUFSIZE,
  93. parent->i_d.di_size);
  94. oldpos = 0;
  95. while (true) {
  96. error = xfs_readdir(sc->tp, parent, &spc.dc, bufsize);
  97. if (error)
  98. goto out;
  99. if (oldpos == spc.dc.pos)
  100. break;
  101. oldpos = spc.dc.pos;
  102. }
  103. *nlink = spc.nlink;
  104. out:
  105. return error;
  106. }
  107. /*
  108. * Given the inode number of the alleged parent of the inode being
  109. * scrubbed, try to validate that the parent has exactly one directory
  110. * entry pointing back to the inode being scrubbed.
  111. */
  112. STATIC int
  113. xchk_parent_validate(
  114. struct xfs_scrub *sc,
  115. xfs_ino_t dnum,
  116. bool *try_again)
  117. {
  118. struct xfs_mount *mp = sc->mp;
  119. struct xfs_inode *dp = NULL;
  120. xfs_nlink_t expected_nlink;
  121. xfs_nlink_t nlink;
  122. int error = 0;
  123. *try_again = false;
  124. if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
  125. goto out;
  126. /* '..' must not point to ourselves. */
  127. if (sc->ip->i_ino == dnum) {
  128. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
  129. goto out;
  130. }
  131. /*
  132. * If we're an unlinked directory, the parent /won't/ have a link
  133. * to us. Otherwise, it should have one link.
  134. */
  135. expected_nlink = VFS_I(sc->ip)->i_nlink == 0 ? 0 : 1;
  136. /*
  137. * Grab this parent inode. We release the inode before we
  138. * cancel the scrub transaction. Since we're don't know a
  139. * priori that releasing the inode won't trigger eofblocks
  140. * cleanup (which allocates what would be a nested transaction)
  141. * if the parent pointer erroneously points to a file, we
  142. * can't use DONTCACHE here because DONTCACHE inodes can trigger
  143. * immediate inactive cleanup of the inode.
  144. *
  145. * If _iget returns -EINVAL then the parent inode number is garbage
  146. * and the directory is corrupt. If the _iget returns -EFSCORRUPTED
  147. * or -EFSBADCRC then the parent is corrupt which is a cross
  148. * referencing error. Any other error is an operational error.
  149. */
  150. error = xfs_iget(mp, sc->tp, dnum, XFS_IGET_UNTRUSTED, 0, &dp);
  151. if (error == -EINVAL) {
  152. error = -EFSCORRUPTED;
  153. xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error);
  154. goto out;
  155. }
  156. if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, &error))
  157. goto out;
  158. if (dp == sc->ip || !S_ISDIR(VFS_I(dp)->i_mode)) {
  159. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
  160. goto out_rele;
  161. }
  162. /*
  163. * We prefer to keep the inode locked while we lock and search
  164. * its alleged parent for a forward reference. If we can grab
  165. * the iolock, validate the pointers and we're done. We must
  166. * use nowait here to avoid an ABBA deadlock on the parent and
  167. * the child inodes.
  168. */
  169. if (xfs_ilock_nowait(dp, XFS_IOLOCK_SHARED)) {
  170. error = xchk_parent_count_parent_dentries(sc, dp, &nlink);
  171. if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0,
  172. &error))
  173. goto out_unlock;
  174. if (nlink != expected_nlink)
  175. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
  176. goto out_unlock;
  177. }
  178. /*
  179. * The game changes if we get here. We failed to lock the parent,
  180. * so we're going to try to verify both pointers while only holding
  181. * one lock so as to avoid deadlocking with something that's actually
  182. * trying to traverse down the directory tree.
  183. */
  184. xfs_iunlock(sc->ip, sc->ilock_flags);
  185. sc->ilock_flags = 0;
  186. error = xchk_ilock_inverted(dp, XFS_IOLOCK_SHARED);
  187. if (error)
  188. goto out_rele;
  189. /* Go looking for our dentry. */
  190. error = xchk_parent_count_parent_dentries(sc, dp, &nlink);
  191. if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, &error))
  192. goto out_unlock;
  193. /* Drop the parent lock, relock this inode. */
  194. xfs_iunlock(dp, XFS_IOLOCK_SHARED);
  195. error = xchk_ilock_inverted(sc->ip, XFS_IOLOCK_EXCL);
  196. if (error)
  197. goto out_rele;
  198. sc->ilock_flags = XFS_IOLOCK_EXCL;
  199. /*
  200. * If we're an unlinked directory, the parent /won't/ have a link
  201. * to us. Otherwise, it should have one link. We have to re-set
  202. * it here because we dropped the lock on sc->ip.
  203. */
  204. expected_nlink = VFS_I(sc->ip)->i_nlink == 0 ? 0 : 1;
  205. /* Look up '..' to see if the inode changed. */
  206. error = xfs_dir_lookup(sc->tp, sc->ip, &xfs_name_dotdot, &dnum, NULL);
  207. if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
  208. goto out_rele;
  209. /* Drat, parent changed. Try again! */
  210. if (dnum != dp->i_ino) {
  211. xfs_irele(dp);
  212. *try_again = true;
  213. return 0;
  214. }
  215. xfs_irele(dp);
  216. /*
  217. * '..' didn't change, so check that there was only one entry
  218. * for us in the parent.
  219. */
  220. if (nlink != expected_nlink)
  221. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
  222. return error;
  223. out_unlock:
  224. xfs_iunlock(dp, XFS_IOLOCK_SHARED);
  225. out_rele:
  226. xfs_irele(dp);
  227. out:
  228. return error;
  229. }
  230. /* Scrub a parent pointer. */
  231. int
  232. xchk_parent(
  233. struct xfs_scrub *sc)
  234. {
  235. struct xfs_mount *mp = sc->mp;
  236. xfs_ino_t dnum;
  237. bool try_again;
  238. int tries = 0;
  239. int error = 0;
  240. /*
  241. * If we're a directory, check that the '..' link points up to
  242. * a directory that has one entry pointing to us.
  243. */
  244. if (!S_ISDIR(VFS_I(sc->ip)->i_mode))
  245. return -ENOENT;
  246. /* We're not a special inode, are we? */
  247. if (!xfs_verify_dir_ino(mp, sc->ip->i_ino)) {
  248. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
  249. goto out;
  250. }
  251. /*
  252. * The VFS grabs a read or write lock via i_rwsem before it reads
  253. * or writes to a directory. If we've gotten this far we've
  254. * already obtained IOLOCK_EXCL, which (since 4.10) is the same as
  255. * getting a write lock on i_rwsem. Therefore, it is safe for us
  256. * to drop the ILOCK here in order to do directory lookups.
  257. */
  258. sc->ilock_flags &= ~(XFS_ILOCK_EXCL | XFS_MMAPLOCK_EXCL);
  259. xfs_iunlock(sc->ip, XFS_ILOCK_EXCL | XFS_MMAPLOCK_EXCL);
  260. /* Look up '..' */
  261. error = xfs_dir_lookup(sc->tp, sc->ip, &xfs_name_dotdot, &dnum, NULL);
  262. if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
  263. goto out;
  264. if (!xfs_verify_dir_ino(mp, dnum)) {
  265. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
  266. goto out;
  267. }
  268. /* Is this the root dir? Then '..' must point to itself. */
  269. if (sc->ip == mp->m_rootip) {
  270. if (sc->ip->i_ino != mp->m_sb.sb_rootino ||
  271. sc->ip->i_ino != dnum)
  272. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
  273. goto out;
  274. }
  275. do {
  276. error = xchk_parent_validate(sc, dnum, &try_again);
  277. if (error)
  278. goto out;
  279. } while (try_again && ++tries < 20);
  280. /*
  281. * We gave it our best shot but failed, so mark this scrub
  282. * incomplete. Userspace can decide if it wants to try again.
  283. */
  284. if (try_again && tries == 20)
  285. xchk_set_incomplete(sc);
  286. out:
  287. /*
  288. * If we failed to lock the parent inode even after a retry, just mark
  289. * this scrub incomplete and return.
  290. */
  291. if (sc->try_harder && error == -EDEADLOCK) {
  292. error = 0;
  293. xchk_set_incomplete(sc);
  294. }
  295. return error;
  296. }