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