[PATCH v3 3/6] ntfs: report inode metadata errors to fsnotify

From: Baolin Liu

Date: Thu Sep 24 2026 - 05:02:38 EST


From: Baolin Liu <liubaolin@xxxxxxxxxx>

Inode initialization, writeback and LogFile failures currently mark the
volume as having errors without notifying filesystem health monitors.

Report these failures against the affected VFS inode, using the base
inode for attribute and index inodes. Preserve the existing treatment of
allocation failures, unsupported formats and interrupted operations.
Do not propagate reporting state between inode and attribute operations;
fanotify can merge queued error events.

Signed-off-by: Baolin Liu <liubaolin@xxxxxxxxxx>
---
fs/ntfs/inode.c | 12 ++++++++----
fs/ntfs/logfile.c | 2 +-
2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 9583b2c6c7a2..591aab2850be 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -1257,7 +1257,7 @@ static int ntfs_read_locked_inode(struct inode *vi)
ntfs_error(vol->sb,
"Failed with error code %i. Marking corrupt inode 0x%llx as bad. Run chkdsk.",
err, ni->mft_no);
- NVolSetErrors(vol);
+ ntfs_report_file_metadata_error(vi, err);
}
return err;
}
@@ -1486,7 +1486,7 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)
base_ni->mft_no);
if (err != -ENOENT && err != -ENOMEM &&
err != -EINTR && err != -ERESTARTSYS)
- NVolSetErrors(vol);
+ ntfs_report_file_metadata_error(base_vi, err);
return err;
}

@@ -1741,7 +1741,7 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi)
err, ni->mft_no, ni->name_len);
if (err != -EOPNOTSUPP && err != -ENOMEM &&
err != -EINTR && err != -ERESTARTSYS)
- NVolSetErrors(vol);
+ ntfs_report_file_metadata_error(base_vi, err);
return err;
}

@@ -2898,7 +2898,10 @@ int __ntfs_write_inode(struct inode *vi, int sync)
mark_inode_dirty(vi);
else {
ntfs_error(vi->i_sb, "Failed (error %i): Run chkdsk.", -err);
- NVolSetErrors(ni->vol);
+ if (err != -EINTR && err != -ERESTARTSYS)
+ ntfs_report_file_metadata_error(vi, err);
+ else
+ NVolSetErrors(ni->vol);
}
if (need_iput)
iput(vi);
@@ -2967,6 +2970,7 @@ static struct ntfs_inode *ntfs_extent_inode_open(struct ntfs_inode *base_ni,
seq_no != le16_to_cpu(ni_mrec->sequence_number)) {
ntfs_error(sb, "Found stale extent mft reference mft=%llu",
ni->mft_no);
+ ntfs_report_file_metadata_error(VFS_I(base_ni), -EIO);
unmap_mft_record(ni);
return ERR_PTR(-EIO);
}
diff --git a/fs/ntfs/logfile.c b/fs/ntfs/logfile.c
index 1404664dacc0..6897faf849c1 100644
--- a/fs/ntfs/logfile.c
+++ b/fs/ntfs/logfile.c
@@ -768,7 +768,7 @@ bool ntfs_empty_logfile(struct inode *log_vi)
rl_err:
ntfs_error(sb, "Runlist is corrupt. Unmount and run chkdsk.");
dirty_err:
- NVolSetErrors(vol);
+ ntfs_report_file_metadata_error(log_vi, -EIO);
err = -EIO;
err:
kvfree(empty_buf);
--
2.51.0