From: Baolin Liu <liubaolin12138@163.com>
To: linkinjeon@kernel.org, hyc.lee@gmail.com
Cc: ntfs@lists.linux.dev, linux-kernel@vger.kernel.org,
chenxiaosong@chenxiaosong.com, Baolin Liu <liubaolin@kylinos.cn>
Subject: [PATCH v2 04/10] ntfs: preserve EA attribute lookup errors
Date: Sun, 20 Sep 2026 16:31:25 +0800 [thread overview]
Message-ID: <20260920083131.1880061-5-liubaolin12138@163.com> (raw)
In-Reply-To: <20260920083131.1880061-1-liubaolin12138@163.com>
From: Baolin Liu <liubaolin@kylinos.cn>
ntfs_attr_exist() treats lookup failures as absence. Using it while
updating EAs can select creation or removal paths after an allocation
or I/O failure.
Use an EA-local lookup helper that preserves errors from mapping the
MFT record, allocating the search context and looking up the attribute.
Check both EA attributes before modifying either and return EUCLEAN if
only one exists. Keep the known presence state for the final update.
Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>
---
fs/ntfs/ea.c | 51 ++++++++++++++++++++++++++++++++++++---------------
1 file changed, 36 insertions(+), 15 deletions(-)
diff --git a/fs/ntfs/ea.c b/fs/ntfs/ea.c
index 5c6facae4ed5..f5a112495fc9 100644
--- a/fs/ntfs/ea.c
+++ b/fs/ntfs/ea.c
@@ -181,6 +181,29 @@ static inline int ea_packed_size(const struct ea_attr *p_ea)
return 5 + p_ea->ea_name_length + le16_to_cpu(p_ea->ea_value_length);
}
+/* Unlike ntfs_attr_exist(), preserve lookup errors. */
+static int ntfs_ea_attr_lookup(struct ntfs_inode *ni, __le32 type)
+{
+ struct ntfs_attr_search_ctx *ctx;
+ struct mft_record *mrec;
+ int err;
+
+ mrec = map_mft_record(ni);
+ if (IS_ERR(mrec))
+ return PTR_ERR(mrec);
+ ctx = ntfs_attr_get_search_ctx(ni, mrec);
+ if (!ctx) {
+ err = -ENOMEM;
+ goto out;
+ }
+ err = ntfs_attr_lookup(type, AT_UNNAMED, 0, CASE_SENSITIVE,
+ 0, NULL, 0, ctx);
+ ntfs_attr_put_search_ctx(ctx);
+out:
+ unmap_mft_record(ni);
+ return err;
+}
+
/*
* Set a new EA, and set EA_INFORMATION accordingly
*
@@ -198,7 +221,8 @@ static int ntfs_set_ea(struct inode *inode, const char *name, size_t name_len,
{
struct ntfs_inode *ni = NTFS_I(inode);
struct ea_information *p_ea_info = NULL;
- int ea_packed, err = 0;
+ int ea_packed, err = 0, ea_err;
+ bool has_ea;
struct ea_attr *p_ea;
u32 ea_info_qsize = 0;
char *ea_buf = NULL;
@@ -211,7 +235,16 @@ static int ntfs_set_ea(struct inode *inode, const char *name, size_t name_len,
if (name_len > 255)
return -ENAMETOOLONG;
- if (ntfs_attr_exist(ni, AT_EA_INFORMATION, AT_UNNAMED, 0)) {
+ err = ntfs_ea_attr_lookup(ni, AT_EA_INFORMATION);
+ if (err && err != -ENOENT)
+ return err;
+ ea_err = ntfs_ea_attr_lookup(ni, AT_EA);
+ if (ea_err && ea_err != -ENOENT)
+ return ea_err;
+ if (!err != !ea_err)
+ return -EUCLEAN;
+ has_ea = !err;
+ if (has_ea) {
p_ea_info = ntfs_attr_readall(ni, AT_EA_INFORMATION, NULL, 0,
&ea_info_size);
if (IS_ERR(p_ea_info)) {
@@ -230,15 +263,9 @@ static int ntfs_set_ea(struct inode *inode, const char *name, size_t name_len,
ea_buf = NULL;
goto out;
}
- if (!ea_buf) {
- ea_info_qsize = 0;
- kvfree(p_ea_info);
- goto create_ea_info;
- }
ea_info_qsize = le32_to_cpu(p_ea_info->ea_query_length);
} else {
-create_ea_info:
p_ea_info = kzalloc_obj(struct ea_information, GFP_NOFS);
if (!p_ea_info)
return -ENOMEM;
@@ -249,12 +276,6 @@ static int ntfs_set_ea(struct inode *inode, const char *name, size_t name_len,
if (err)
goto out;
- if (ntfs_attr_exist(ni, AT_EA, AT_UNNAMED, 0)) {
- err = ntfs_attr_remove(ni, AT_EA, AT_UNNAMED, 0);
- if (err)
- goto out;
- }
-
goto alloc_new_ea;
}
@@ -404,7 +425,7 @@ static int ntfs_set_ea(struct inode *inode, const char *name, size_t name_len,
/*
* no EA or EA_INFORMATION : add them
*/
- if (!ntfs_attr_exist(ni, AT_EA, AT_UNNAMED, 0)) {
+ if (!has_ea) {
err = ntfs_attr_add(ni, AT_EA, AT_UNNAMED, 0, ea_buf,
ea_info_qsize + new_ea_size);
if (err)
--
2.51.0
next prev parent reply other threads:[~2026-09-20 8:32 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-20 8:31 [PATCH v2 00/10] ntfs: persist Linux file attributes in an EA Baolin Liu
2026-09-20 8:31 ` [PATCH v2 01/10] ntfs: keep the EA presence flag after creating the first entry Baolin Liu
2026-09-20 8:31 ` [PATCH v2 02/10] ntfs: validate EA chains and link zero-terminated tails Baolin Liu
2026-09-21 6:17 ` Namjae Jeon
2026-09-21 10:34 ` liubaolin
2026-09-20 8:31 ` [PATCH v2 03/10] ntfs: propagate EA write and truncate errors Baolin Liu
2026-09-20 8:31 ` Baolin Liu [this message]
2026-09-20 8:31 ` [PATCH v2 05/10] ntfs: distinguish empty EA values from removal Baolin Liu
2026-09-20 8:31 ` [PATCH v2 06/10] ntfs: restore EA attributes when an update fails Baolin Liu
2026-09-20 8:31 ` [PATCH v2 07/10] ntfs: add fileattr query support Baolin Liu
2026-09-20 8:31 ` [PATCH v2 08/10] ntfs: persist immutable in the $LXFLAGS EA Baolin Liu
2026-09-22 1:21 ` Hyunchul Lee
2026-09-22 3:26 ` liubaolin
2026-09-22 5:25 ` Hyunchul Lee
2026-09-22 6:02 ` liubaolin
2026-09-20 8:31 ` [PATCH v2 09/10] ntfs: persist append-only " Baolin Liu
2026-09-20 8:31 ` [PATCH v2 10/10] ntfs: persist nodump " Baolin Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260920083131.1880061-5-liubaolin12138@163.com \
--to=liubaolin12138@163.com \
--cc=chenxiaosong@chenxiaosong.com \
--cc=hyc.lee@gmail.com \
--cc=linkinjeon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=liubaolin@kylinos.cn \
--cc=ntfs@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®