fscounters_repair.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (c) 2018-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_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_alloc.h"
  20. #include "xfs_ialloc.h"
  21. #include "xfs_rmap.h"
  22. #include "xfs_health.h"
  23. #include "scrub/xfs_scrub.h"
  24. #include "scrub/scrub.h"
  25. #include "scrub/common.h"
  26. #include "scrub/trace.h"
  27. #include "scrub/repair.h"
  28. #include "scrub/fscounters.h"
  29. /*
  30. * FS Summary Counters
  31. * ===================
  32. *
  33. * We correct errors in the filesystem summary counters by setting them to the
  34. * values computed during the obligatory scrub phase. However, we must be
  35. * careful not to allow any other thread to change the counters while we're
  36. * computing and setting new values. To achieve this, we freeze the
  37. * filesystem for the whole operation if the REPAIR flag is set. The checking
  38. * function is stricter when we've frozen the fs.
  39. */
  40. /*
  41. * Reset the superblock counters. Caller is responsible for freezing the
  42. * filesystem during the calculation and reset phases.
  43. */
  44. int
  45. xrep_fscounters(
  46. struct xfs_scrub *sc)
  47. {
  48. struct xfs_mount *mp = sc->mp;
  49. struct xchk_fscounters *fsc = sc->buf;
  50. /*
  51. * Reinitialize the in-core counters from what we computed. We froze
  52. * the filesystem, so there shouldn't be anyone else trying to modify
  53. * these counters.
  54. */
  55. if (!fsc->frozen) {
  56. ASSERT(fsc->frozen);
  57. return -EFSCORRUPTED;
  58. }
  59. trace_xrep_reset_counters(mp, fsc);
  60. percpu_counter_set(&mp->m_icount, fsc->icount);
  61. percpu_counter_set(&mp->m_ifree, fsc->ifree);
  62. percpu_counter_set(&mp->m_fdblocks, fsc->fdblocks);
  63. /*
  64. * Online repair is only supported on v5 file systems, which require
  65. * lazy sb counters and thus no update of sb_fdblocks here. But as of
  66. * now we don't support lazy counting sb_frextents yet, and thus need
  67. * to also update it directly here. And for that we need to keep
  68. * track of the delalloc reservations separately, as they are are
  69. * subtracted from m_frextents, but not included in sb_frextents.
  70. */
  71. percpu_counter_set(&mp->m_frextents,
  72. fsc->frextents - fsc->frextents_delayed);
  73. mp->m_sb.sb_frextents = fsc->frextents;
  74. return 0;
  75. }