quota.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  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_inode_fork.h"
  20. #include "xfs_alloc.h"
  21. #include "xfs_bmap.h"
  22. #include "xfs_quota.h"
  23. #include "xfs_qm.h"
  24. #include "xfs_dquot.h"
  25. #include "xfs_dquot_item.h"
  26. #include "scrub/xfs_scrub.h"
  27. #include "scrub/scrub.h"
  28. #include "scrub/common.h"
  29. #include "scrub/trace.h"
  30. /* Convert a scrub type code to a DQ flag, or return 0 if error. */
  31. static inline uint
  32. xchk_quota_to_dqtype(
  33. struct xfs_scrub *sc)
  34. {
  35. switch (sc->sm->sm_type) {
  36. case XFS_SCRUB_TYPE_UQUOTA:
  37. return XFS_DQ_USER;
  38. case XFS_SCRUB_TYPE_GQUOTA:
  39. return XFS_DQ_GROUP;
  40. case XFS_SCRUB_TYPE_PQUOTA:
  41. return XFS_DQ_PROJ;
  42. default:
  43. return 0;
  44. }
  45. }
  46. /* Set us up to scrub a quota. */
  47. int
  48. xchk_setup_quota(
  49. struct xfs_scrub *sc,
  50. struct xfs_inode *ip)
  51. {
  52. uint dqtype;
  53. int error;
  54. if (!XFS_IS_QUOTA_RUNNING(sc->mp) || !XFS_IS_QUOTA_ON(sc->mp))
  55. return -ENOENT;
  56. dqtype = xchk_quota_to_dqtype(sc);
  57. if (dqtype == 0)
  58. return -EINVAL;
  59. sc->has_quotaofflock = true;
  60. mutex_lock(&sc->mp->m_quotainfo->qi_quotaofflock);
  61. if (!xfs_this_quota_on(sc->mp, dqtype))
  62. return -ENOENT;
  63. error = xchk_setup_fs(sc, ip);
  64. if (error)
  65. return error;
  66. sc->ip = xfs_quota_inode(sc->mp, dqtype);
  67. xfs_ilock(sc->ip, XFS_ILOCK_EXCL);
  68. sc->ilock_flags = XFS_ILOCK_EXCL;
  69. return 0;
  70. }
  71. /* Quotas. */
  72. struct xchk_quota_info {
  73. struct xfs_scrub *sc;
  74. xfs_dqid_t last_id;
  75. };
  76. /* Scrub the fields in an individual quota item. */
  77. STATIC int
  78. xchk_quota_item(
  79. struct xfs_dquot *dq,
  80. uint dqtype,
  81. void *priv)
  82. {
  83. struct xchk_quota_info *sqi = priv;
  84. struct xfs_scrub *sc = sqi->sc;
  85. struct xfs_mount *mp = sc->mp;
  86. struct xfs_disk_dquot *d = &dq->q_core;
  87. struct xfs_quotainfo *qi = mp->m_quotainfo;
  88. xfs_fileoff_t offset;
  89. unsigned long long bsoft;
  90. unsigned long long isoft;
  91. unsigned long long rsoft;
  92. unsigned long long bhard;
  93. unsigned long long ihard;
  94. unsigned long long rhard;
  95. unsigned long long bcount;
  96. unsigned long long icount;
  97. unsigned long long rcount;
  98. xfs_ino_t fs_icount;
  99. xfs_dqid_t id = be32_to_cpu(d->d_id);
  100. /*
  101. * Except for the root dquot, the actual dquot we got must either have
  102. * the same or higher id as we saw before.
  103. */
  104. offset = id / qi->qi_dqperchunk;
  105. if (id && id <= sqi->last_id)
  106. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
  107. sqi->last_id = id;
  108. /* Did we get the dquot type we wanted? */
  109. if (dqtype != (d->d_flags & XFS_DQ_ALLTYPES))
  110. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
  111. if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0))
  112. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
  113. /* Check the limits. */
  114. bhard = be64_to_cpu(d->d_blk_hardlimit);
  115. ihard = be64_to_cpu(d->d_ino_hardlimit);
  116. rhard = be64_to_cpu(d->d_rtb_hardlimit);
  117. bsoft = be64_to_cpu(d->d_blk_softlimit);
  118. isoft = be64_to_cpu(d->d_ino_softlimit);
  119. rsoft = be64_to_cpu(d->d_rtb_softlimit);
  120. /*
  121. * Warn if the hard limits are larger than the fs.
  122. * Administrators can do this, though in production this seems
  123. * suspect, which is why we flag it for review.
  124. *
  125. * Complain about corruption if the soft limit is greater than
  126. * the hard limit.
  127. */
  128. if (bhard > mp->m_sb.sb_dblocks)
  129. xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
  130. if (bsoft > bhard)
  131. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
  132. if (ihard > mp->m_maxicount)
  133. xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
  134. if (isoft > ihard)
  135. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
  136. if (rhard > mp->m_sb.sb_rblocks)
  137. xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
  138. if (rsoft > rhard)
  139. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
  140. /* Check the resource counts. */
  141. bcount = be64_to_cpu(d->d_bcount);
  142. icount = be64_to_cpu(d->d_icount);
  143. rcount = be64_to_cpu(d->d_rtbcount);
  144. fs_icount = percpu_counter_sum(&mp->m_icount);
  145. /*
  146. * Check that usage doesn't exceed physical limits. However, on
  147. * a reflink filesystem we're allowed to exceed physical space
  148. * if there are no quota limits.
  149. */
  150. if (xfs_sb_version_hasreflink(&mp->m_sb)) {
  151. if (mp->m_sb.sb_dblocks < bcount)
  152. xchk_fblock_set_warning(sc, XFS_DATA_FORK,
  153. offset);
  154. } else {
  155. if (mp->m_sb.sb_dblocks < bcount)
  156. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK,
  157. offset);
  158. }
  159. if (icount > fs_icount || rcount > mp->m_sb.sb_rblocks)
  160. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
  161. /*
  162. * We can violate the hard limits if the admin suddenly sets a
  163. * lower limit than the actual usage. However, we flag it for
  164. * admin review.
  165. */
  166. if (id != 0 && bhard != 0 && bcount > bhard)
  167. xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
  168. if (id != 0 && ihard != 0 && icount > ihard)
  169. xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
  170. if (id != 0 && rhard != 0 && rcount > rhard)
  171. xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
  172. return 0;
  173. }
  174. /* Check the quota's data fork. */
  175. STATIC int
  176. xchk_quota_data_fork(
  177. struct xfs_scrub *sc)
  178. {
  179. struct xfs_bmbt_irec irec = { 0 };
  180. struct xfs_iext_cursor icur;
  181. struct xfs_quotainfo *qi = sc->mp->m_quotainfo;
  182. struct xfs_ifork *ifp;
  183. xfs_fileoff_t max_dqid_off;
  184. int error = 0;
  185. /* Invoke the fork scrubber. */
  186. error = xchk_metadata_inode_forks(sc);
  187. if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
  188. return error;
  189. /* Check for data fork problems that apply only to quota files. */
  190. max_dqid_off = ((xfs_dqid_t)-1) / qi->qi_dqperchunk;
  191. ifp = XFS_IFORK_PTR(sc->ip, XFS_DATA_FORK);
  192. for_each_xfs_iext(ifp, &icur, &irec) {
  193. if (xchk_should_terminate(sc, &error))
  194. break;
  195. /*
  196. * delalloc extents or blocks mapped above the highest
  197. * quota id shouldn't happen.
  198. */
  199. if (isnullstartblock(irec.br_startblock) ||
  200. irec.br_startoff > max_dqid_off ||
  201. irec.br_startoff + irec.br_blockcount - 1 > max_dqid_off) {
  202. xchk_fblock_set_corrupt(sc, XFS_DATA_FORK,
  203. irec.br_startoff);
  204. break;
  205. }
  206. }
  207. return error;
  208. }
  209. /* Scrub all of a quota type's items. */
  210. int
  211. xchk_quota(
  212. struct xfs_scrub *sc)
  213. {
  214. struct xchk_quota_info sqi;
  215. struct xfs_mount *mp = sc->mp;
  216. struct xfs_quotainfo *qi = mp->m_quotainfo;
  217. uint dqtype;
  218. int error = 0;
  219. dqtype = xchk_quota_to_dqtype(sc);
  220. /* Look for problem extents. */
  221. error = xchk_quota_data_fork(sc);
  222. if (error)
  223. goto out;
  224. if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
  225. goto out;
  226. /*
  227. * Check all the quota items. Now that we've checked the quota inode
  228. * data fork we have to drop ILOCK_EXCL to use the regular dquot
  229. * functions.
  230. */
  231. xfs_iunlock(sc->ip, sc->ilock_flags);
  232. sc->ilock_flags = 0;
  233. sqi.sc = sc;
  234. sqi.last_id = 0;
  235. error = xfs_qm_dqiterate(mp, dqtype, xchk_quota_item, &sqi);
  236. sc->ilock_flags = XFS_ILOCK_EXCL;
  237. xfs_ilock(sc->ip, sc->ilock_flags);
  238. if (!xchk_fblock_process_error(sc, XFS_DATA_FORK,
  239. sqi.last_id * qi->qi_dqperchunk, &error))
  240. goto out;
  241. out:
  242. return error;
  243. }