Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * quota.c - NTFS kernel quota ($Quota) handling.  Part of the Linux-NTFS
0004  *       project.
0005  *
0006  * Copyright (c) 2004 Anton Altaparmakov
0007  */
0008 
0009 #ifdef NTFS_RW
0010 
0011 #include "index.h"
0012 #include "quota.h"
0013 #include "debug.h"
0014 #include "ntfs.h"
0015 
0016 /**
0017  * ntfs_mark_quotas_out_of_date - mark the quotas out of date on an ntfs volume
0018  * @vol:    ntfs volume on which to mark the quotas out of date
0019  *
0020  * Mark the quotas out of date on the ntfs volume @vol and return 'true' on
0021  * success and 'false' on error.
0022  */
0023 bool ntfs_mark_quotas_out_of_date(ntfs_volume *vol)
0024 {
0025     ntfs_index_context *ictx;
0026     QUOTA_CONTROL_ENTRY *qce;
0027     const le32 qid = QUOTA_DEFAULTS_ID;
0028     int err;
0029 
0030     ntfs_debug("Entering.");
0031     if (NVolQuotaOutOfDate(vol))
0032         goto done;
0033     if (!vol->quota_ino || !vol->quota_q_ino) {
0034         ntfs_error(vol->sb, "Quota inodes are not open.");
0035         return false;
0036     }
0037     inode_lock(vol->quota_q_ino);
0038     ictx = ntfs_index_ctx_get(NTFS_I(vol->quota_q_ino));
0039     if (!ictx) {
0040         ntfs_error(vol->sb, "Failed to get index context.");
0041         goto err_out;
0042     }
0043     err = ntfs_index_lookup(&qid, sizeof(qid), ictx);
0044     if (err) {
0045         if (err == -ENOENT)
0046             ntfs_error(vol->sb, "Quota defaults entry is not "
0047                     "present.");
0048         else
0049             ntfs_error(vol->sb, "Lookup of quota defaults entry "
0050                     "failed.");
0051         goto err_out;
0052     }
0053     if (ictx->data_len < offsetof(QUOTA_CONTROL_ENTRY, sid)) {
0054         ntfs_error(vol->sb, "Quota defaults entry size is invalid.  "
0055                 "Run chkdsk.");
0056         goto err_out;
0057     }
0058     qce = (QUOTA_CONTROL_ENTRY*)ictx->data;
0059     if (le32_to_cpu(qce->version) != QUOTA_VERSION) {
0060         ntfs_error(vol->sb, "Quota defaults entry version 0x%x is not "
0061                 "supported.", le32_to_cpu(qce->version));
0062         goto err_out;
0063     }
0064     ntfs_debug("Quota defaults flags = 0x%x.", le32_to_cpu(qce->flags));
0065     /* If quotas are already marked out of date, no need to do anything. */
0066     if (qce->flags & QUOTA_FLAG_OUT_OF_DATE)
0067         goto set_done;
0068     /*
0069      * If quota tracking is neither requested, nor enabled and there are no
0070      * pending deletes, no need to mark the quotas out of date.
0071      */
0072     if (!(qce->flags & (QUOTA_FLAG_TRACKING_ENABLED |
0073             QUOTA_FLAG_TRACKING_REQUESTED |
0074             QUOTA_FLAG_PENDING_DELETES)))
0075         goto set_done;
0076     /*
0077      * Set the QUOTA_FLAG_OUT_OF_DATE bit thus marking quotas out of date.
0078      * This is verified on WinXP to be sufficient to cause windows to
0079      * rescan the volume on boot and update all quota entries.
0080      */
0081     qce->flags |= QUOTA_FLAG_OUT_OF_DATE;
0082     /* Ensure the modified flags are written to disk. */
0083     ntfs_index_entry_flush_dcache_page(ictx);
0084     ntfs_index_entry_mark_dirty(ictx);
0085 set_done:
0086     ntfs_index_ctx_put(ictx);
0087     inode_unlock(vol->quota_q_ino);
0088     /*
0089      * We set the flag so we do not try to mark the quotas out of date
0090      * again on remount.
0091      */
0092     NVolSetQuotaOutOfDate(vol);
0093 done:
0094     ntfs_debug("Done.");
0095     return true;
0096 err_out:
0097     if (ictx)
0098         ntfs_index_ctx_put(ictx);
0099     inode_unlock(vol->quota_q_ino);
0100     return false;
0101 }
0102 
0103 #endif /* NTFS_RW */