]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ntfs: remove unsupported quota handling
authorDaeMyung Kang <charsyam@gmail.com>
Sun, 17 May 2026 03:44:47 +0000 (12:44 +0900)
committerNamjae Jeon <linkinjeon@kernel.org>
Fri, 5 Jun 2026 15:20:03 +0000 (00:20 +0900)
The ntfs driver does not implement quota accounting.  It creates
new inodes with the NTFS 1.2 $STANDARD_INFORMATION layout and does
not maintain the NTFS 3.x owner_id/quota_charged fields or the
$Quota usage records that Windows would need for meaningful quota
accounting.

The only runtime quota path left in the driver is the remount-rw
code that tries to mark $Quota/$Q out of date, plus the mount-time
code that loads $Quota and its $Q index solely to support that
marker.

Since the driver does not maintain the per-file quota metadata,
setting QUOTA_FLAG_OUT_OF_DATE does not make the quota state
meaningful, and failures in this unsupported path can unnecessarily
block remount-rw or force a mount read-only.

Remove the quota marker, the $Quota/$Q loading state, and the
unused quota volume flag.  Keep the on-disk quota layout definitions
in layout.h so the documented NTFS structures remain available.

Suggested-by: Hyunchul Lee <hyc.lee@gmail.com>
Link: https://lore.kernel.org/all/CANFS6bYTzioqZjYt=51Kb9RdR3MKXaez_fh_WCLoym093VxFmg@mail.gmail.com/
Signed-off-by: DaeMyung Kang <charsyam@gmail.com>
Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
fs/ntfs/Makefile
fs/ntfs/quota.c [deleted file]
fs/ntfs/quota.h [deleted file]
fs/ntfs/super.c
fs/ntfs/volume.h

index 0ce4d9a9388aff52c47272402b3fd297237520ac..e120c2e69862acd923501cd3e0b4ebb141e0b695 100644 (file)
@@ -5,6 +5,6 @@ obj-$(CONFIG_NTFS_FS) += ntfs.o
 ntfs-y := aops.o attrib.o collate.o dir.o file.o index.o inode.o \
          mft.o mst.o namei.o runlist.o super.o unistr.o attrlist.o ea.o \
          upcase.o bitmap.o lcnalloc.o logfile.o reparse.o compress.o \
-         iomap.o debug.o sysctl.o quota.o object_id.o bdev-io.o
+         iomap.o debug.o sysctl.o object_id.o bdev-io.o
 
 ccflags-$(CONFIG_NTFS_DEBUG) += -DDEBUG
diff --git a/fs/ntfs/quota.c b/fs/ntfs/quota.c
deleted file mode 100644 (file)
index b443243..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * NTFS kernel quota ($Quota) handling.
- *
- * Copyright (c) 2004 Anton Altaparmakov
- */
-
-#include "index.h"
-#include "quota.h"
-#include "debug.h"
-#include "ntfs.h"
-
-/*
- * ntfs_mark_quotas_out_of_date - mark the quotas out of date on an ntfs volume
- * @vol:       ntfs volume on which to mark the quotas out of date
- *
- * Mark the quotas out of date on the ntfs volume @vol and return 'true' on
- * success and 'false' on error.
- */
-bool ntfs_mark_quotas_out_of_date(struct ntfs_volume *vol)
-{
-       struct ntfs_index_context *ictx;
-       struct quota_control_entry *qce;
-       const __le32 qid = QUOTA_DEFAULTS_ID;
-       int err;
-
-       ntfs_debug("Entering.");
-       if (NVolQuotaOutOfDate(vol))
-               goto done;
-       if (!vol->quota_ino || !vol->quota_q_ino) {
-               ntfs_error(vol->sb, "Quota inodes are not open.");
-               return false;
-       }
-       inode_lock(vol->quota_q_ino);
-       ictx = ntfs_index_ctx_get(NTFS_I(vol->quota_q_ino), I30, 4);
-       if (!ictx) {
-               ntfs_error(vol->sb, "Failed to get index context.");
-               goto err_out;
-       }
-       err = ntfs_index_lookup(&qid, sizeof(qid), ictx);
-       if (err) {
-               if (err == -ENOENT)
-                       ntfs_error(vol->sb, "Quota defaults entry is not present.");
-               else
-                       ntfs_error(vol->sb, "Lookup of quota defaults entry failed.");
-               goto err_out;
-       }
-       if (ictx->data_len < offsetof(struct quota_control_entry, sid)) {
-               ntfs_error(vol->sb, "Quota defaults entry size is invalid.  Run chkdsk.");
-               goto err_out;
-       }
-       qce = (struct quota_control_entry *)ictx->data;
-       if (le32_to_cpu(qce->version) != QUOTA_VERSION) {
-               ntfs_error(vol->sb,
-                       "Quota defaults entry version 0x%x is not supported.",
-                       le32_to_cpu(qce->version));
-               goto err_out;
-       }
-       ntfs_debug("Quota defaults flags = 0x%x.", le32_to_cpu(qce->flags));
-       /* If quotas are already marked out of date, no need to do anything. */
-       if (qce->flags & QUOTA_FLAG_OUT_OF_DATE)
-               goto set_done;
-       /*
-        * If quota tracking is neither requested, nor enabled and there are no
-        * pending deletes, no need to mark the quotas out of date.
-        */
-       if (!(qce->flags & (QUOTA_FLAG_TRACKING_ENABLED |
-                       QUOTA_FLAG_TRACKING_REQUESTED |
-                       QUOTA_FLAG_PENDING_DELETES)))
-               goto set_done;
-       /*
-        * Set the QUOTA_FLAG_OUT_OF_DATE bit thus marking quotas out of date.
-        * This is verified on WinXP to be sufficient to cause windows to
-        * rescan the volume on boot and update all quota entries.
-        */
-       qce->flags |= QUOTA_FLAG_OUT_OF_DATE;
-       /* Ensure the modified flags are written to disk. */
-       ntfs_index_entry_mark_dirty(ictx);
-set_done:
-       ntfs_index_ctx_put(ictx);
-       inode_unlock(vol->quota_q_ino);
-       /*
-        * We set the flag so we do not try to mark the quotas out of date
-        * again on remount.
-        */
-       NVolSetQuotaOutOfDate(vol);
-done:
-       ntfs_debug("Done.");
-       return true;
-err_out:
-       if (ictx)
-               ntfs_index_ctx_put(ictx);
-       inode_unlock(vol->quota_q_ino);
-       return false;
-}
diff --git a/fs/ntfs/quota.h b/fs/ntfs/quota.h
deleted file mode 100644 (file)
index 4b73226..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Defines for NTFS kernel quota ($Quota) handling.
- *
- * Copyright (c) 2004 Anton Altaparmakov
- */
-
-#ifndef _LINUX_NTFS_QUOTA_H
-#define _LINUX_NTFS_QUOTA_H
-
-#include "volume.h"
-
-bool ntfs_mark_quotas_out_of_date(struct ntfs_volume *vol);
-
-#endif /* _LINUX_NTFS_QUOTA_H */
index e30fcce628c29bbcaac1336fc1e3db6463352031..312acb41c2ed5d9fdce9873705d276b056d0efb0 100644 (file)
@@ -17,7 +17,6 @@
 
 #include "sysctl.h"
 #include "logfile.h"
-#include "quota.h"
 #include "index.h"
 #include "ntfs.h"
 #include "ea.h"
@@ -240,8 +239,7 @@ static int ntfs_reconfigure(struct fs_context *fc)
         * flags are set.  Also, empty the logfile journal as it would become
         * stale as soon as something is written to the volume and mark the
         * volume dirty so that chkdsk is run if the volume is not umounted
-        * cleanly.  Finally, mark the quotas out of date so Windows rescans
-        * the volume on boot and updates them.
+        * cleanly.
         *
         * When remounting read-only, mark the volume clean if no volume errors
         * have occurred.
@@ -274,12 +272,6 @@ static int ntfs_reconfigure(struct fs_context *fc)
                        NVolSetErrors(vol);
                        return -EROFS;
                }
-               if (!ntfs_mark_quotas_out_of_date(vol)) {
-                       ntfs_error(sb, "Failed to mark quotas out of date%s",
-                                       es);
-                       NVolSetErrors(vol);
-                       return -EROFS;
-               }
        } else if (!sb_rdonly(sb) && (fc->sb_flags & SB_RDONLY)) {
                /* Remounting read-only. */
                if (!NVolErrors(vol)) {
@@ -1175,73 +1167,6 @@ iput_out:
        return ret;
 }
 
-/*
- * load_and_init_quota - load and setup the quota file for a volume if present
- * @vol:       ntfs super block describing device whose quota file to load
- *
- * Return 'true' on success or 'false' on error.  If $Quota is not present, we
- * leave vol->quota_ino as NULL and return success.
- */
-static bool load_and_init_quota(struct ntfs_volume *vol)
-{
-       static const __le16 Quota[7] = { cpu_to_le16('$'),
-                       cpu_to_le16('Q'), cpu_to_le16('u'),
-                       cpu_to_le16('o'), cpu_to_le16('t'),
-                       cpu_to_le16('a'), 0 };
-       static __le16 Q[3] = { cpu_to_le16('$'),
-                       cpu_to_le16('Q'), 0 };
-       struct ntfs_name *name = NULL;
-       u64 mref;
-       struct inode *tmp_ino;
-
-       ntfs_debug("Entering.");
-       /*
-        * Find the inode number for the quota file by looking up the filename
-        * $Quota in the extended system files directory $Extend.
-        */
-       inode_lock(vol->extend_ino);
-       mref = ntfs_lookup_inode_by_name(NTFS_I(vol->extend_ino), Quota, 6,
-                       &name);
-       inode_unlock(vol->extend_ino);
-       kfree(name);
-       if (IS_ERR_MREF(mref)) {
-               /*
-                * If the file does not exist, quotas are disabled and have
-                * never been enabled on this volume, just return success.
-                */
-               if (MREF_ERR(mref) == -ENOENT) {
-                       ntfs_debug("$Quota not present.  Volume does not have quotas enabled.");
-                       /*
-                        * No need to try to set quotas out of date if they are
-                        * not enabled.
-                        */
-                       NVolSetQuotaOutOfDate(vol);
-                       return true;
-               }
-               /* A real error occurred. */
-               ntfs_error(vol->sb, "Failed to find inode number for $Quota.");
-               return false;
-       }
-       /* Get the inode. */
-       tmp_ino = ntfs_iget(vol->sb, MREF(mref));
-       if (IS_ERR(tmp_ino)) {
-               if (!IS_ERR(tmp_ino))
-                       iput(tmp_ino);
-               ntfs_error(vol->sb, "Failed to load $Quota.");
-               return false;
-       }
-       vol->quota_ino = tmp_ino;
-       /* Get the $Q index allocation attribute. */
-       tmp_ino = ntfs_index_iget(vol->quota_ino, Q, 2);
-       if (IS_ERR(tmp_ino)) {
-               ntfs_error(vol->sb, "Failed to load $Quota/$Q index.");
-               return false;
-       }
-       vol->quota_q_ino = tmp_ino;
-       ntfs_debug("Done.");
-       return true;
-}
-
 /*
  * load_and_init_attrdef - load the attribute definitions table for a volume
  * @vol:       ntfs super block describing device whose attrdef to load
@@ -1653,18 +1578,6 @@ get_ctx_vol_failed:
                ntfs_error(sb, "Failed to load $Extend.");
                goto iput_sec_err_out;
        }
-       /* Find the quota file, load it if present, and set it up. */
-       if (!load_and_init_quota(vol) &&
-           vol->on_errors == ON_ERRORS_REMOUNT_RO) {
-               static const char *es1 = "Failed to load $Quota";
-               static const char *es2 = ".  Run chkdsk.";
-
-               sb->s_flags |= SB_RDONLY;
-               ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
-               /* This will prevent a read-write remount. */
-               NVolSetErrors(vol);
-       }
-
        return true;
 
 iput_sec_err_out:
@@ -1762,10 +1675,6 @@ static void ntfs_put_super(struct super_block *sb)
 
        /* NTFS 3.0+ specific. */
        if (vol->major_ver >= 3) {
-               if (vol->quota_q_ino)
-                       ntfs_commit_inode(vol->quota_q_ino);
-               if (vol->quota_ino)
-                       ntfs_commit_inode(vol->quota_ino);
                if (vol->extend_ino)
                        ntfs_commit_inode(vol->extend_ino);
                if (vol->secure_ino)
@@ -1814,14 +1723,6 @@ static void ntfs_put_super(struct super_block *sb)
 
        /* NTFS 3.0+ specific clean up. */
        if (vol->major_ver >= 3) {
-               if (vol->quota_q_ino) {
-                       iput(vol->quota_q_ino);
-                       vol->quota_q_ino = NULL;
-               }
-               if (vol->quota_ino) {
-                       iput(vol->quota_ino);
-                       vol->quota_ino = NULL;
-               }
                if (vol->extend_ino) {
                        iput(vol->extend_ino);
                        vol->extend_ino = NULL;
@@ -2460,14 +2361,6 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
        vol->vol_ino = NULL;
        /* NTFS 3.0+ specific clean up. */
        if (vol->major_ver >= 3) {
-               if (vol->quota_q_ino) {
-                       iput(vol->quota_q_ino);
-                       vol->quota_q_ino = NULL;
-               }
-               if (vol->quota_ino) {
-                       iput(vol->quota_ino);
-                       vol->quota_ino = NULL;
-               }
                if (vol->extend_ino) {
                        iput(vol->extend_ino);
                        vol->extend_ino = NULL;
index af41427ec622cbd45e3e2c3dab242095569dfe7d..e13e1423b2a926f8193a6ad6b883f35adfced32b 100644 (file)
@@ -76,8 +76,6 @@
  * @root_ino: The VFS inode of the root directory.
  * @secure_ino: The VFS inode of $Secure (NTFS3.0+ only, otherwise NULL).
  * @extend_ino: The VFS inode of $Extend (NTFS3.0+ only, otherwise NULL).
- * @quota_ino: The VFS inode of $Quota.
- * @quota_q_ino: Attribute inode for $Quota/$Q.
  * @nls_map: NLS (National Language Support) table.
  * @nls_utf8: NLS table for UTF-8.
  * @free_waitq: Wait queue for threads waiting for free clusters or MFT records.
@@ -141,8 +139,6 @@ struct ntfs_volume {
        struct inode *root_ino;
        struct inode *secure_ino;
        struct inode *extend_ino;
-       struct inode *quota_ino;
-       struct inode *quota_q_ino;
        struct nls_table *nls_map;
        bool nls_utf8;
        wait_queue_head_t free_waitq;
@@ -165,7 +161,6 @@ struct ntfs_volume {
  *                             Otherwise be case insensitive but still
  *                             create file names in POSIX namespace.
  * NV_LogFileEmpty             LogFile journal is empty.
- * NV_QuotaOutOfDate           Quota is out of date.
  * NV_UsnJrnlStamped           UsnJrnl has been stamped.
  * NV_ReadOnly                 Volume is mounted read-only.
  * NV_Compression              Volume supports compression.
@@ -186,7 +181,6 @@ enum {
        NV_ShowSystemFiles,
        NV_CaseSensitive,
        NV_LogFileEmpty,
-       NV_QuotaOutOfDate,
        NV_UsnJrnlStamped,
        NV_ReadOnly,
        NV_Compression,
@@ -223,7 +217,6 @@ DEFINE_NVOL_BIT_OPS(Errors)
 DEFINE_NVOL_BIT_OPS(ShowSystemFiles)
 DEFINE_NVOL_BIT_OPS(CaseSensitive)
 DEFINE_NVOL_BIT_OPS(LogFileEmpty)
-DEFINE_NVOL_BIT_OPS(QuotaOutOfDate)
 DEFINE_NVOL_BIT_OPS(UsnJrnlStamped)
 DEFINE_NVOL_BIT_OPS(ReadOnly)
 DEFINE_NVOL_BIT_OPS(Compression)