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