rtbitmap.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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_alloc.h"
  19. #include "xfs_rtalloc.h"
  20. #include "xfs_inode.h"
  21. #include "scrub/xfs_scrub.h"
  22. #include "scrub/scrub.h"
  23. #include "scrub/common.h"
  24. #include "scrub/trace.h"
  25. /* Set us up with the realtime metadata locked. */
  26. int
  27. xchk_setup_rt(
  28. struct xfs_scrub *sc,
  29. struct xfs_inode *ip)
  30. {
  31. int error;
  32. error = xchk_setup_fs(sc, ip);
  33. if (error)
  34. return error;
  35. sc->ilock_flags = XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP;
  36. sc->ip = sc->mp->m_rbmip;
  37. xfs_ilock(sc->ip, sc->ilock_flags);
  38. return 0;
  39. }
  40. /* Realtime bitmap. */
  41. /* Scrub a free extent record from the realtime bitmap. */
  42. STATIC int
  43. xchk_rtbitmap_rec(
  44. struct xfs_trans *tp,
  45. struct xfs_rtalloc_rec *rec,
  46. void *priv)
  47. {
  48. struct xfs_scrub *sc = priv;
  49. xfs_rtblock_t startblock;
  50. xfs_rtblock_t blockcount;
  51. startblock = rec->ar_startext * tp->t_mountp->m_sb.sb_rextsize;
  52. blockcount = rec->ar_extcount * tp->t_mountp->m_sb.sb_rextsize;
  53. if (startblock + blockcount <= startblock ||
  54. !xfs_verify_rtbno(sc->mp, startblock) ||
  55. !xfs_verify_rtbno(sc->mp, startblock + blockcount - 1))
  56. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
  57. return 0;
  58. }
  59. /* Scrub the realtime bitmap. */
  60. int
  61. xchk_rtbitmap(
  62. struct xfs_scrub *sc)
  63. {
  64. int error;
  65. /* Invoke the fork scrubber. */
  66. error = xchk_metadata_inode_forks(sc);
  67. if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
  68. return error;
  69. error = xfs_rtalloc_query_all(sc->tp, xchk_rtbitmap_rec, sc);
  70. if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
  71. goto out;
  72. out:
  73. return error;
  74. }
  75. /* Scrub the realtime summary. */
  76. int
  77. xchk_rtsummary(
  78. struct xfs_scrub *sc)
  79. {
  80. struct xfs_inode *rsumip = sc->mp->m_rsumip;
  81. struct xfs_inode *old_ip = sc->ip;
  82. uint old_ilock_flags = sc->ilock_flags;
  83. int error = 0;
  84. /*
  85. * We ILOCK'd the rt bitmap ip in the setup routine, now lock the
  86. * rt summary ip in compliance with the rt inode locking rules.
  87. *
  88. * Since we switch sc->ip to rsumip we have to save the old ilock
  89. * flags so that we don't mix up the inode state that @sc tracks.
  90. */
  91. sc->ip = rsumip;
  92. sc->ilock_flags = XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM;
  93. xfs_ilock(sc->ip, sc->ilock_flags);
  94. /* Invoke the fork scrubber. */
  95. error = xchk_metadata_inode_forks(sc);
  96. if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
  97. goto out;
  98. /* XXX: implement this some day */
  99. xchk_set_incomplete(sc);
  100. out:
  101. /* Switch back to the rtbitmap inode and lock flags. */
  102. xfs_iunlock(sc->ip, sc->ilock_flags);
  103. sc->ilock_flags = old_ilock_flags;
  104. sc->ip = old_ip;
  105. return error;
  106. }
  107. /* xref check that the extent is not free in the rtbitmap */
  108. void
  109. xchk_xref_is_used_rt_space(
  110. struct xfs_scrub *sc,
  111. xfs_rtblock_t fsbno,
  112. xfs_extlen_t len)
  113. {
  114. xfs_rtblock_t startext;
  115. xfs_rtblock_t endext;
  116. xfs_rtblock_t extcount;
  117. bool is_free;
  118. int error;
  119. if (xchk_skip_xref(sc->sm))
  120. return;
  121. startext = fsbno;
  122. endext = fsbno + len - 1;
  123. do_div(startext, sc->mp->m_sb.sb_rextsize);
  124. if (do_div(endext, sc->mp->m_sb.sb_rextsize))
  125. endext++;
  126. extcount = endext - startext;
  127. xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
  128. error = xfs_rtalloc_extent_is_free(sc->mp, sc->tp, startext, extcount,
  129. &is_free);
  130. if (!xchk_should_check_xref(sc, &error, NULL))
  131. goto out_unlock;
  132. if (is_free)
  133. xchk_ino_xref_set_corrupt(sc, sc->mp->m_rbmip->i_ino);
  134. out_unlock:
  135. xfs_iunlock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
  136. }