* [PATCH 1/3] ntfs: return view index entry data from lookup
2026-05-11 16:06 [PATCH 0/3] ntfs: fix quota out-of-date marking DaeMyung Kang
@ 2026-05-11 16:06 ` DaeMyung Kang
2026-05-13 2:14 ` Hyunchul Lee
2026-05-11 16:06 ` [PATCH 2/3] ntfs: use $Q when marking quotas out of date DaeMyung Kang
2026-05-11 16:06 ` [PATCH 3/3] ntfs: mark quotas out of date on initial rw mount DaeMyung Kang
2 siblings, 1 reply; 11+ messages in thread
From: DaeMyung Kang @ 2026-05-11 16:06 UTC (permalink / raw)
To: linkinjeon, hyc.lee; +Cc: linux-fsdevel, linux-kernel, DaeMyung Kang
ntfs_index_lookup() always exposes the matched entry key through
icx->data. That is correct for file name indexes, where $I30 callers
expect the key to be a struct file_name_attr and update it in place.
NTFS view indexes store a separate value in index_entry.data.vi. For
example, $Quota/$Q uses the owner_id as the key and stores the
quota_control_entry in the entry value. Returning the key makes quota code
see only the 4-byte owner_id instead of the quota control entry.
Preserve the existing $FILE_NAME index behavior, but return the entry value
for view indexes. Use the index root type for that layout decision:
indexes with ir->type == AT_FILE_NAME expose the entry key, while view
indexes have type 0 and expose the entry value through data.vi. Validate
the value offset and length before exposing the pointer, and clear
icx->data when the key is not found because the context then describes an
insertion point rather than a matched value. Use unsigned arithmetic for
the minimum data offset check, account for the VCN stored at the end of
INDEX_ENTRY_NODE entries, and clear the returned context pointers before
returning an entry-data validation error.
Move the matched-entry data exposure and validation into a small helper,
ntfs_index_lookup_set_data(), so the done label stays flat and the bounds
check has a single return.
Signed-off-by: DaeMyung Kang <charsyam@gmail.com>
---
fs/ntfs/index.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
fs/ntfs/index.h | 3 +-
2 files changed, 73 insertions(+), 5 deletions(-)
diff --git a/fs/ntfs/index.c b/fs/ntfs/index.c
index a547bdc..30dfcbb 100644
--- a/fs/ntfs/index.c
+++ b/fs/ntfs/index.c
@@ -696,6 +696,53 @@ static int ntfs_icx_parent_dec(struct ntfs_index_context *icx)
}
/*
+ * ntfs_index_lookup_set_data - populate icx->data for the matched entry
+ *
+ * For directory $FILE_NAME indexes the caller updates the key in place, so
+ * expose the key. For view indexes the value lives at data.vi; validate
+ * its offset and length before exposing the pointer. Return 0 on success,
+ * or -EIO if the entry value is out of bounds.
+ */
+static int ntfs_index_lookup_set_data(struct ntfs_index_context *icx,
+ struct index_root *ir,
+ struct index_entry *ie)
+{
+ u16 data_len, data_off, entry_len, found_key_len;
+ unsigned int data_end, min_data_off;
+
+ if (ie->flags & INDEX_ENTRY_END)
+ return -EIO;
+
+ found_key_len = le16_to_cpu(ie->key_length);
+ if (ir->type == AT_FILE_NAME) {
+ icx->data = (u8 *)ie + offsetof(struct index_entry, key);
+ icx->data_len = found_key_len;
+ return 0;
+ }
+
+ entry_len = le16_to_cpu(ie->length);
+ data_off = le16_to_cpu(ie->data.vi.data_offset);
+ data_len = le16_to_cpu(ie->data.vi.data_length);
+ data_end = entry_len;
+ if (ie->flags & INDEX_ENTRY_NODE) {
+ /* The trailing child VCN is not part of the entry value. */
+ if (data_end < sizeof(s64))
+ return -EIO;
+ data_end -= sizeof(s64);
+ }
+
+ min_data_off = offsetof(struct index_entry, key) + found_key_len;
+ if (data_off < min_data_off || data_off > data_end)
+ return -EIO;
+ if (data_len > data_end - data_off)
+ return -EIO;
+
+ icx->data = (u8 *)ie + data_off;
+ icx->data_len = data_len;
+ return 0;
+}
+
+/*
* ntfs_index_lookup - find a key in an index and return its index entry
* @key: key for which to search in the index
* @key_len: length of @key in bytes
@@ -710,7 +757,8 @@ static int ntfs_icx_parent_dec(struct ntfs_index_context *icx)
* If the @key is found in the index, 0 is returned and @icx is setup to
* describe the index entry containing the matching @key. @icx->entry is the
* index entry and @icx->data and @icx->data_len are the index entry data and
- * its length in bytes, respectively.
+ * its length in bytes, respectively. For file name indexes @icx->data points
+ * to the entry key; for view indexes @icx->data points to the entry value.
*
* If the @key is not found in the index, -ENOENT is returned and
* @icx is setup to describe the index entry whose key collates immediately
@@ -836,11 +884,30 @@ err_out:
return err;
done:
icx->entry = ie;
- icx->data = (u8 *)ie + offsetof(struct index_entry, key);
- icx->data_len = le16_to_cpu(ie->key_length);
+ if (err) {
+ /* When the key is not found, ie is an insertion point. */
+ icx->data = NULL;
+ icx->data_len = 0;
+ ntfs_debug("Done.\n");
+ return err;
+ }
+ err = ntfs_index_lookup_set_data(icx, ir, ie);
+ if (err) {
+ ntfs_error(sb,
+ "Index entry data out of bounds in inode 0x%llx.",
+ (unsigned long long)ni->mft_no);
+ icx->entry = NULL;
+ icx->data = NULL;
+ icx->data_len = 0;
+ if (!icx->is_in_root) {
+ kvfree(ib);
+ ib = NULL;
+ icx->ib = NULL;
+ }
+ goto err_out;
+ }
ntfs_debug("Done.\n");
return err;
-
}
static struct index_block *ntfs_ib_alloc(s64 ib_vcn, u32 ib_size,
diff --git a/fs/ntfs/index.h b/fs/ntfs/index.h
index e68d6fa..4b8c5c8 100644
--- a/fs/ntfs/index.h
+++ b/fs/ntfs/index.h
@@ -58,7 +58,8 @@
* To obtain a context call ntfs_index_ctx_get().
*
* We use this context to allow ntfs_index_lookup() to return the found index
* @entry and its @data without having to allocate a buffer and copy the @entry
- * and/or its @data into it.
+ * and/or its @data into it. For file name indexes @data points to the entry
+ * key; for view indexes @data points to the entry value.
*
* When finished with the @entry and its @data, call ntfs_index_ctx_put() to
* free the context and other associated resources.
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH 1/3] ntfs: return view index entry data from lookup
2026-05-11 16:06 ` [PATCH 1/3] ntfs: return view index entry data from lookup DaeMyung Kang
@ 2026-05-13 2:14 ` Hyunchul Lee
0 siblings, 0 replies; 11+ messages in thread
From: Hyunchul Lee @ 2026-05-13 2:14 UTC (permalink / raw)
To: DaeMyung Kang; +Cc: linkinjeon, linux-fsdevel, linux-kernel
2026년 5월 12일 (화) 오전 1:06, DaeMyung Kang <charsyam@gmail.com>님이 작성:
>
> ntfs_index_lookup() always exposes the matched entry key through
> icx->data. That is correct for file name indexes, where $I30 callers
> expect the key to be a struct file_name_attr and update it in place.
>
> NTFS view indexes store a separate value in index_entry.data.vi. For
> example, $Quota/$Q uses the owner_id as the key and stores the
> quota_control_entry in the entry value. Returning the key makes quota code
> see only the 4-byte owner_id instead of the quota control entry.
>
> Preserve the existing $FILE_NAME index behavior, but return the entry value
> for view indexes. Use the index root type for that layout decision:
> indexes with ir->type == AT_FILE_NAME expose the entry key, while view
> indexes have type 0 and expose the entry value through data.vi. Validate
> the value offset and length before exposing the pointer, and clear
> icx->data when the key is not found because the context then describes an
> insertion point rather than a matched value. Use unsigned arithmetic for
> the minimum data offset check, account for the VCN stored at the end of
> INDEX_ENTRY_NODE entries, and clear the returned context pointers before
> returning an entry-data validation error.
>
> Move the matched-entry data exposure and validation into a small helper,
> ntfs_index_lookup_set_data(), so the done label stays flat and the bounds
> check has a single return.
>
> Signed-off-by: DaeMyung Kang <charsyam@gmail.com>
Looks good to me.
Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
> ---
> fs/ntfs/index.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
> fs/ntfs/index.h | 3 +-
> 2 files changed, 73 insertions(+), 5 deletions(-)
>
> diff --git a/fs/ntfs/index.c b/fs/ntfs/index.c
> index a547bdc..30dfcbb 100644
> --- a/fs/ntfs/index.c
> +++ b/fs/ntfs/index.c
> @@ -696,6 +696,53 @@ static int ntfs_icx_parent_dec(struct ntfs_index_context *icx)
> }
>
> /*
> + * ntfs_index_lookup_set_data - populate icx->data for the matched entry
> + *
> + * For directory $FILE_NAME indexes the caller updates the key in place, so
> + * expose the key. For view indexes the value lives at data.vi; validate
> + * its offset and length before exposing the pointer. Return 0 on success,
> + * or -EIO if the entry value is out of bounds.
> + */
> +static int ntfs_index_lookup_set_data(struct ntfs_index_context *icx,
> + struct index_root *ir,
> + struct index_entry *ie)
> +{
> + u16 data_len, data_off, entry_len, found_key_len;
> + unsigned int data_end, min_data_off;
> +
> + if (ie->flags & INDEX_ENTRY_END)
> + return -EIO;
> +
> + found_key_len = le16_to_cpu(ie->key_length);
> + if (ir->type == AT_FILE_NAME) {
> + icx->data = (u8 *)ie + offsetof(struct index_entry, key);
> + icx->data_len = found_key_len;
> + return 0;
> + }
> +
> + entry_len = le16_to_cpu(ie->length);
> + data_off = le16_to_cpu(ie->data.vi.data_offset);
> + data_len = le16_to_cpu(ie->data.vi.data_length);
> + data_end = entry_len;
> + if (ie->flags & INDEX_ENTRY_NODE) {
> + /* The trailing child VCN is not part of the entry value. */
> + if (data_end < sizeof(s64))
> + return -EIO;
> + data_end -= sizeof(s64);
> + }
> +
> + min_data_off = offsetof(struct index_entry, key) + found_key_len;
> + if (data_off < min_data_off || data_off > data_end)
> + return -EIO;
> + if (data_len > data_end - data_off)
> + return -EIO;
> +
> + icx->data = (u8 *)ie + data_off;
> + icx->data_len = data_len;
> + return 0;
> +}
> +
> +/*
> * ntfs_index_lookup - find a key in an index and return its index entry
> * @key: key for which to search in the index
> * @key_len: length of @key in bytes
> @@ -710,7 +757,8 @@ static int ntfs_icx_parent_dec(struct ntfs_index_context *icx)
> * If the @key is found in the index, 0 is returned and @icx is setup to
> * describe the index entry containing the matching @key. @icx->entry is the
> * index entry and @icx->data and @icx->data_len are the index entry data and
> - * its length in bytes, respectively.
> + * its length in bytes, respectively. For file name indexes @icx->data points
> + * to the entry key; for view indexes @icx->data points to the entry value.
> *
> * If the @key is not found in the index, -ENOENT is returned and
> * @icx is setup to describe the index entry whose key collates immediately
> @@ -836,11 +884,30 @@ err_out:
> return err;
> done:
> icx->entry = ie;
> - icx->data = (u8 *)ie + offsetof(struct index_entry, key);
> - icx->data_len = le16_to_cpu(ie->key_length);
> + if (err) {
> + /* When the key is not found, ie is an insertion point. */
> + icx->data = NULL;
> + icx->data_len = 0;
> + ntfs_debug("Done.\n");
> + return err;
> + }
> + err = ntfs_index_lookup_set_data(icx, ir, ie);
> + if (err) {
> + ntfs_error(sb,
> + "Index entry data out of bounds in inode 0x%llx.",
> + (unsigned long long)ni->mft_no);
> + icx->entry = NULL;
> + icx->data = NULL;
> + icx->data_len = 0;
> + if (!icx->is_in_root) {
> + kvfree(ib);
> + ib = NULL;
> + icx->ib = NULL;
> + }
> + goto err_out;
> + }
> ntfs_debug("Done.\n");
> return err;
> -
> }
>
> static struct index_block *ntfs_ib_alloc(s64 ib_vcn, u32 ib_size,
> diff --git a/fs/ntfs/index.h b/fs/ntfs/index.h
> index e68d6fa..4b8c5c8 100644
> --- a/fs/ntfs/index.h
> +++ b/fs/ntfs/index.h
> @@ -58,7 +58,8 @@
> * To obtain a context call ntfs_index_ctx_get().
> *
> * We use this context to allow ntfs_index_lookup() to return the found index
> * @entry and its @data without having to allocate a buffer and copy the @entry
> - * and/or its @data into it.
> + * and/or its @data into it. For file name indexes @data points to the entry
> + * key; for view indexes @data points to the entry value.
> *
> * When finished with the @entry and its @data, call ntfs_index_ctx_put() to
> * free the context and other associated resources.
> --
> 2.43.0
--
Thanks,
Hyunchul
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 2/3] ntfs: use $Q when marking quotas out of date
2026-05-11 16:06 [PATCH 0/3] ntfs: fix quota out-of-date marking DaeMyung Kang
2026-05-11 16:06 ` [PATCH 1/3] ntfs: return view index entry data from lookup DaeMyung Kang
@ 2026-05-11 16:06 ` DaeMyung Kang
2026-05-13 14:53 ` Namjae Jeon
2026-05-11 16:06 ` [PATCH 3/3] ntfs: mark quotas out of date on initial rw mount DaeMyung Kang
2 siblings, 1 reply; 11+ messages in thread
From: DaeMyung Kang @ 2026-05-11 16:06 UTC (permalink / raw)
To: linkinjeon, hyc.lee; +Cc: linux-fsdevel, linux-kernel, DaeMyung Kang
ntfs_mark_quotas_out_of_date() operates on vol->quota_q_ino, which is the
$Quota/$Q index inode opened by load_and_init_quota(). However, it creates
the index context with the $I30 name.
That asks the $Quota file for an $INDEX_ROOT named $I30 and fails before
the quota defaults entry can be looked up. Use the $Q index name when
marking quotas out of date.
Signed-off-by: DaeMyung Kang <charsyam@gmail.com>
---
fs/ntfs/quota.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/ntfs/quota.c b/fs/ntfs/quota.c
index b443243..7086951 100644
--- a/fs/ntfs/quota.c
+++ b/fs/ntfs/quota.c
@@ -21,6 +21,7 @@ bool ntfs_mark_quotas_out_of_date(struct ntfs_volume *vol)
{
struct ntfs_index_context *ictx;
struct quota_control_entry *qce;
+ static __le16 Q[3] = { cpu_to_le16('$'), cpu_to_le16('Q'), 0 };
const __le32 qid = QUOTA_DEFAULTS_ID;
int err;
@@ -32,7 +33,7 @@ bool ntfs_mark_quotas_out_of_date(struct ntfs_volume *vol)
return false;
}
inode_lock(vol->quota_q_ino);
- ictx = ntfs_index_ctx_get(NTFS_I(vol->quota_q_ino), I30, 4);
+ ictx = ntfs_index_ctx_get(NTFS_I(vol->quota_q_ino), Q, 2);
if (!ictx) {
ntfs_error(vol->sb, "Failed to get index context.");
goto err_out;
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 3/3] ntfs: mark quotas out of date on initial rw mount
2026-05-11 16:06 [PATCH 0/3] ntfs: fix quota out-of-date marking DaeMyung Kang
2026-05-11 16:06 ` [PATCH 1/3] ntfs: return view index entry data from lookup DaeMyung Kang
2026-05-11 16:06 ` [PATCH 2/3] ntfs: use $Q when marking quotas out of date DaeMyung Kang
@ 2026-05-11 16:06 ` DaeMyung Kang
2026-05-13 23:46 ` Hyunchul Lee
2 siblings, 1 reply; 11+ messages in thread
From: DaeMyung Kang @ 2026-05-11 16:06 UTC (permalink / raw)
To: linkinjeon, hyc.lee; +Cc: linux-fsdevel, linux-kernel, DaeMyung Kang
The remount read-write path marks quotas out of date after emptying the
logfile, but initial read-write mount only loads $Quota and never calls
ntfs_mark_quotas_out_of_date().
That leaves quota tracking metadata looking up to date even though the
driver can modify the volume. Call the same helper after $Quota is loaded
during initial read-write mount. If marking quotas out of date fails and
the mount policy is on_errors=remount-ro, convert the mount to read-only
and set the volume error state, matching the nearby $Quota load failure
handling.
This intentionally follows the initial mount error policy rather than the
remount-rw path, where a quota marking failure rejects the remount with
-EROFS.
Move the load/mark/policy handling into a small helper,
ntfs_init_quota_for_mount(), which captures each call result in a local,
derives the failure reason, and gates the read-only downgrade on policy
in one place. This avoids calling helpers inside compound if conditions
and keeps ntfs_load_system_files() flat.
Signed-off-by: DaeMyung Kang <charsyam@gmail.com>
---
fs/ntfs/super.c | 46 +++++++++++++++++++++++++++++++++--------------
1 file changed, 35 insertions(+), 11 deletions(-)
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 22dc786..8fa298f 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1221,6 +1221,39 @@ static bool load_and_init_quota(struct ntfs_volume *vol)
return true;
}
+/*
+ * ntfs_init_quota_for_mount - finish quota setup at mount time
+ * @sb: super block of the volume being mounted
+ * @vol: ntfs volume to set up
+ *
+ * Load $Quota and, on a read-write mount, mark quotas out of date so that
+ * Windows rescans them on next boot. On failure, downgrade the mount to
+ * read-only when on_errors=remount-ro, matching the volume error policy.
+ */
+static void ntfs_init_quota_for_mount(struct super_block *sb,
+ struct ntfs_volume *vol)
+{
+ bool quota_loaded, quota_marked = true;
+ const char *reason = NULL;
+
+ quota_loaded = load_and_init_quota(vol);
+ if (quota_loaded && !sb_rdonly(sb))
+ quota_marked = ntfs_mark_quotas_out_of_date(vol);
+
+ if (!quota_loaded)
+ reason = "Failed to load $Quota";
+ else if (!quota_marked)
+ reason = "Failed to mark quotas out of date";
+
+ if (!reason || vol->on_errors != ON_ERRORS_REMOUNT_RO)
+ return;
+
+ sb->s_flags |= SB_RDONLY;
+ ntfs_error(sb, "%s. Mounting read-only. Run chkdsk.", reason);
+ /* This will prevent a read-write remount. */
+ NVolSetErrors(vol);
+}
+
/*
* load_and_init_attrdef - load the attribute definitions table for a volume
* @vol: ntfs super block describing device whose attrdef to load
@@ -1638,16 +1671,7 @@ 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);
- }
+ /* Find the quota file, load it if present, and set it up. */
+ ntfs_init_quota_for_mount(sb, vol);
return true;
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH 3/3] ntfs: mark quotas out of date on initial rw mount
2026-05-11 16:06 ` [PATCH 3/3] ntfs: mark quotas out of date on initial rw mount DaeMyung Kang
@ 2026-05-13 23:46 ` Hyunchul Lee
2026-05-14 13:25 ` CharSyam
0 siblings, 1 reply; 11+ messages in thread
From: Hyunchul Lee @ 2026-05-13 23:46 UTC (permalink / raw)
To: DaeMyung Kang; +Cc: linkinjeon, linux-fsdevel, linux-kernel
Hello daemyung,
2026년 5월 12일 (화) 오전 1:06, DaeMyung Kang <charsyam@gmail.com>님이 작성:
>
> The remount read-write path marks quotas out of date after emptying the
> logfile, but initial read-write mount only loads $Quota and never calls
> ntfs_mark_quotas_out_of_date().
We set both the owner id and quota charged in $STANDARD_INFORMATION
to 0, so it is questionable whether setting the out of date flag in $Quota/$Q
has any meaning.
>
> That leaves quota tracking metadata looking up to date even though the
> driver can modify the volume. Call the same helper after $Quota is loaded
> during initial read-write mount. If marking quotas out of date fails and
> the mount policy is on_errors=remount-ro, convert the mount to read-only
> and set the volume error state, matching the nearby $Quota load failure
> handling.
>
> This intentionally follows the initial mount error policy rather than the
> remount-rw path, where a quota marking failure rejects the remount with
> -EROFS.
>
> Move the load/mark/policy handling into a small helper,
> ntfs_init_quota_for_mount(), which captures each call result in a local,
> derives the failure reason, and gates the read-only downgrade on policy
> in one place. This avoids calling helpers inside compound if conditions
> and keeps ntfs_load_system_files() flat.
>
> Signed-off-by: DaeMyung Kang <charsyam@gmail.com>
> ---
> fs/ntfs/super.c | 46 +++++++++++++++++++++++++++++++++--------------
> 1 file changed, 35 insertions(+), 11 deletions(-)
>
> diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
> index 22dc786..8fa298f 100644
> --- a/fs/ntfs/super.c
> +++ b/fs/ntfs/super.c
> @@ -1221,6 +1221,39 @@ static bool load_and_init_quota(struct ntfs_volume *vol)
> return true;
> }
>
> +/*
> + * ntfs_init_quota_for_mount - finish quota setup at mount time
> + * @sb: super block of the volume being mounted
> + * @vol: ntfs volume to set up
> + *
> + * Load $Quota and, on a read-write mount, mark quotas out of date so that
> + * Windows rescans them on next boot. On failure, downgrade the mount to
> + * read-only when on_errors=remount-ro, matching the volume error policy.
> + */
> +static void ntfs_init_quota_for_mount(struct super_block *sb,
> + struct ntfs_volume *vol)
> +{
> + bool quota_loaded, quota_marked = true;
> + const char *reason = NULL;
> +
> + quota_loaded = load_and_init_quota(vol);
> + if (quota_loaded && !sb_rdonly(sb))
> + quota_marked = ntfs_mark_quotas_out_of_date(vol);
> +
> + if (!quota_loaded)
> + reason = "Failed to load $Quota";
> + else if (!quota_marked)
> + reason = "Failed to mark quotas out of date";
> +
> + if (!reason || vol->on_errors != ON_ERRORS_REMOUNT_RO)
> + return;
> +
> + sb->s_flags |= SB_RDONLY;
> + ntfs_error(sb, "%s. Mounting read-only. Run chkdsk.", reason);
> + /* This will prevent a read-write remount. */
> + NVolSetErrors(vol);
> +}
> +
> /*
> * load_and_init_attrdef - load the attribute definitions table for a volume
> * @vol: ntfs super block describing device whose attrdef to load
> @@ -1638,16 +1671,7 @@ 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);
> - }
> + /* Find the quota file, load it if present, and set it up. */
> + ntfs_init_quota_for_mount(sb, vol);
>
> return true;
> --
> 2.43.0
>
--
Thanks,
Hyunchul
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH 3/3] ntfs: mark quotas out of date on initial rw mount
2026-05-13 23:46 ` Hyunchul Lee
@ 2026-05-14 13:25 ` CharSyam
2026-05-14 23:50 ` Hyunchul Lee
0 siblings, 1 reply; 11+ messages in thread
From: CharSyam @ 2026-05-14 13:25 UTC (permalink / raw)
To: Hyunchul Lee; +Cc: linkinjeon, linux-fsdevel, linux-kernel
Thanks for the review.
You're right that the driver does not maintain quota accounting: it
creates v1.2 $STANDARD_INFORMATION for new inodes, and it does not update
the v3 quota fields or $Quota usage accounting.
Given that I do not have modern Windows validation for the exact quota
rescan behavior, I'll drop 3/3 from v3 and resend just 1/3 and 2/3.
Thanks,
DaeMyung
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH 3/3] ntfs: mark quotas out of date on initial rw mount
2026-05-14 13:25 ` CharSyam
@ 2026-05-14 23:50 ` Hyunchul Lee
2026-05-15 0:35 ` CharSyam
0 siblings, 1 reply; 11+ messages in thread
From: Hyunchul Lee @ 2026-05-14 23:50 UTC (permalink / raw)
To: CharSyam; +Cc: linkinjeon, linux-fsdevel, linux-kernel
2026년 5월 14일 (목) 오후 10:25, CharSyam <charsyam@gmail.com>님이 작성:
>
> Thanks for the review.
>
> You're right that the driver does not maintain quota accounting: it
> creates v1.2 $STANDARD_INFORMATION for new inodes, and it does not update
> the v3 quota fields or $Quota usage accounting.
>
> Given that I do not have modern Windows validation for the exact quota
> rescan behavior, I'll drop 3/3 from v3 and resend just 1/3 and 2/3.
I think setting the out-of-date flag in patch 2/3 is also not meaningful.
How about removing ntfs_mark_quotas_out_of_date() related codes for now?
>
> Thanks,
> DaeMyung
--
Thanks,
Hyunchul
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/3] ntfs: mark quotas out of date on initial rw mount
2026-05-14 23:50 ` Hyunchul Lee
@ 2026-05-15 0:35 ` CharSyam
2026-05-15 1:13 ` Hyunchul Lee
0 siblings, 1 reply; 11+ messages in thread
From: CharSyam @ 2026-05-15 0:35 UTC (permalink / raw)
To: Hyunchul Lee; +Cc: linkinjeon, linux-fsdevel, linux-kernel
Hi. Hyunchul.
I agree that the out-of-date marking path looks questionable.
After re-checking the code, the current ntfs driver does not appear to
implement quota accounting: new inodes get v1.2 $STANDARD_INFORMATION, and
the driver does not maintain the v3 owner_id/quota_charged fields or $Quota
usage records. So fixing ntfs_mark_quotas_out_of_date() only makes an
existing path set QUOTA_FLAG_OUT_OF_DATE, but that does not seem meaningful
without the metadata Windows would need to rescan.
Given that, I am wondering what removal scope you would prefer:
1. Drop only this patch and leave the existing broken remount-rw quota
marking path as-is for now.
2. Remove ntfs_mark_quotas_out_of_date() and its remount-rw call site.
3. Remove the broader unused quota-loading state as well ($Quota/$Q inode
loading, quota_ino/quota_q_ino, NV_QuotaOutOfDate, quota.o), while keeping
the on-disk quota layout definitions.
My current preference is option 3, because once the marking helper is gone,
the loaded $Quota inodes do not seem to have another user. But since this
changes the series from a bug fix into removing unsupported quota handling,
I would like to confirm the intended direction first.
Thanks.
DaeMyung.
2026년 5월 15일 (금) 오전 8:50, Hyunchul Lee <hyc.lee@gmail.com>님이 작성:
>
> 2026년 5월 14일 (목) 오후 10:25, CharSyam <charsyam@gmail.com>님이 작성:
> >
> > Thanks for the review.
> >
> > You're right that the driver does not maintain quota accounting: it
> > creates v1.2 $STANDARD_INFORMATION for new inodes, and it does not update
> > the v3 quota fields or $Quota usage accounting.
> >
> > Given that I do not have modern Windows validation for the exact quota
> > rescan behavior, I'll drop 3/3 from v3 and resend just 1/3 and 2/3.
>
> I think setting the out-of-date flag in patch 2/3 is also not meaningful.
> How about removing ntfs_mark_quotas_out_of_date() related codes for now?
>
> >
> > Thanks,
> > DaeMyung
>
>
>
>
> --
> Thanks,
> Hyunchul
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH 3/3] ntfs: mark quotas out of date on initial rw mount
2026-05-15 0:35 ` CharSyam
@ 2026-05-15 1:13 ` Hyunchul Lee
0 siblings, 0 replies; 11+ messages in thread
From: Hyunchul Lee @ 2026-05-15 1:13 UTC (permalink / raw)
To: CharSyam; +Cc: linkinjeon, linux-fsdevel, linux-kernel
2026년 5월 15일 (금) 오전 9:35, CharSyam <charsyam@gmail.com>님이 작성:
>
> Hi. Hyunchul.
>
> I agree that the out-of-date marking path looks questionable.
>
> After re-checking the code, the current ntfs driver does not appear to
> implement quota accounting: new inodes get v1.2 $STANDARD_INFORMATION, and
> the driver does not maintain the v3 owner_id/quota_charged fields or $Quota
> usage records. So fixing ntfs_mark_quotas_out_of_date() only makes an
> existing path set QUOTA_FLAG_OUT_OF_DATE, but that does not seem meaningful
> without the metadata Windows would need to rescan.
>
> Given that, I am wondering what removal scope you would prefer:
>
> 1. Drop only this patch and leave the existing broken remount-rw quota
> marking path as-is for now.
> 2. Remove ntfs_mark_quotas_out_of_date() and its remount-rw call site.
> 3. Remove the broader unused quota-loading state as well ($Quota/$Q inode
> loading, quota_ino/quota_q_ino, NV_QuotaOutOfDate, quota.o), while keeping
> the on-disk quota layout definitions.
>
> My current preference is option 3, because once the marking helper is gone,
> the loaded $Quota inodes do not seem to have another user. But since this
> changes the series from a bug fix into removing unsupported quota handling,
> I would like to confirm the intended direction first.
I also think option 3 is the most appropriate. I would appreciate it
if you could
prepare a patch implementing option 3.
>
> Thanks.
> DaeMyung.
>
> 2026년 5월 15일 (금) 오전 8:50, Hyunchul Lee <hyc.lee@gmail.com>님이 작성:
> >
> > 2026년 5월 14일 (목) 오후 10:25, CharSyam <charsyam@gmail.com>님이 작성:
> > >
> > > Thanks for the review.
> > >
> > > You're right that the driver does not maintain quota accounting: it
> > > creates v1.2 $STANDARD_INFORMATION for new inodes, and it does not update
> > > the v3 quota fields or $Quota usage accounting.
> > >
> > > Given that I do not have modern Windows validation for the exact quota
> > > rescan behavior, I'll drop 3/3 from v3 and resend just 1/3 and 2/3.
> >
> > I think setting the out-of-date flag in patch 2/3 is also not meaningful.
> > How about removing ntfs_mark_quotas_out_of_date() related codes for now?
> >
> > >
> > > Thanks,
> > > DaeMyung
> >
> >
> >
> >
> > --
> > Thanks,
> > Hyunchul
--
Thanks,
Hyunchul
^ permalink raw reply [flat|nested] 11+ messages in thread