quota.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * quota.c - NTFS kernel quota ($Quota) handling. Part of the Linux-NTFS
  4. * project.
  5. *
  6. * Copyright (c) 2004 Anton Altaparmakov
  7. */
  8. #ifdef NTFS_RW
  9. #include "index.h"
  10. #include "quota.h"
  11. #include "debug.h"
  12. #include "ntfs.h"
  13. /**
  14. * ntfs_mark_quotas_out_of_date - mark the quotas out of date on an ntfs volume
  15. * @vol: ntfs volume on which to mark the quotas out of date
  16. *
  17. * Mark the quotas out of date on the ntfs volume @vol and return 'true' on
  18. * success and 'false' on error.
  19. */
  20. bool ntfs_mark_quotas_out_of_date(ntfs_volume *vol)
  21. {
  22. ntfs_index_context *ictx;
  23. QUOTA_CONTROL_ENTRY *qce;
  24. const le32 qid = QUOTA_DEFAULTS_ID;
  25. int err;
  26. ntfs_debug("Entering.");
  27. if (NVolQuotaOutOfDate(vol))
  28. goto done;
  29. if (!vol->quota_ino || !vol->quota_q_ino) {
  30. ntfs_error(vol->sb, "Quota inodes are not open.");
  31. return false;
  32. }
  33. inode_lock(vol->quota_q_ino);
  34. ictx = ntfs_index_ctx_get(NTFS_I(vol->quota_q_ino));
  35. if (!ictx) {
  36. ntfs_error(vol->sb, "Failed to get index context.");
  37. goto err_out;
  38. }
  39. err = ntfs_index_lookup(&qid, sizeof(qid), ictx);
  40. if (err) {
  41. if (err == -ENOENT)
  42. ntfs_error(vol->sb, "Quota defaults entry is not "
  43. "present.");
  44. else
  45. ntfs_error(vol->sb, "Lookup of quota defaults entry "
  46. "failed.");
  47. goto err_out;
  48. }
  49. if (ictx->data_len < offsetof(QUOTA_CONTROL_ENTRY, sid)) {
  50. ntfs_error(vol->sb, "Quota defaults entry size is invalid. "
  51. "Run chkdsk.");
  52. goto err_out;
  53. }
  54. qce = (QUOTA_CONTROL_ENTRY*)ictx->data;
  55. if (le32_to_cpu(qce->version) != QUOTA_VERSION) {
  56. ntfs_error(vol->sb, "Quota defaults entry version 0x%x is not "
  57. "supported.", le32_to_cpu(qce->version));
  58. goto err_out;
  59. }
  60. ntfs_debug("Quota defaults flags = 0x%x.", le32_to_cpu(qce->flags));
  61. /* If quotas are already marked out of date, no need to do anything. */
  62. if (qce->flags & QUOTA_FLAG_OUT_OF_DATE)
  63. goto set_done;
  64. /*
  65. * If quota tracking is neither requested, nor enabled and there are no
  66. * pending deletes, no need to mark the quotas out of date.
  67. */
  68. if (!(qce->flags & (QUOTA_FLAG_TRACKING_ENABLED |
  69. QUOTA_FLAG_TRACKING_REQUESTED |
  70. QUOTA_FLAG_PENDING_DELETES)))
  71. goto set_done;
  72. /*
  73. * Set the QUOTA_FLAG_OUT_OF_DATE bit thus marking quotas out of date.
  74. * This is verified on WinXP to be sufficient to cause windows to
  75. * rescan the volume on boot and update all quota entries.
  76. */
  77. qce->flags |= QUOTA_FLAG_OUT_OF_DATE;
  78. /* Ensure the modified flags are written to disk. */
  79. ntfs_index_entry_flush_dcache_page(ictx);
  80. ntfs_index_entry_mark_dirty(ictx);
  81. set_done:
  82. ntfs_index_ctx_put(ictx);
  83. inode_unlock(vol->quota_q_ino);
  84. /*
  85. * We set the flag so we do not try to mark the quotas out of date
  86. * again on remount.
  87. */
  88. NVolSetQuotaOutOfDate(vol);
  89. done:
  90. ntfs_debug("Done.");
  91. return true;
  92. err_out:
  93. if (ictx)
  94. ntfs_index_ctx_put(ictx);
  95. inode_unlock(vol->quota_q_ino);
  96. return false;
  97. }
  98. #endif /* NTFS_RW */