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