[PATCH v2 2/5] ntfs: fix error handling in ntfs_extent_inode_open and propagate errors
From: Baolin Liu
Date: Fri Sep 04 2026 - 05:13:20 EST
From: Baolin Liu <liubaolin@xxxxxxxxxx>
ntfs_extent_inode_open() has two issues:
1. When map_mft_record() fails, it returns the non-NULL 'ni' pointer
instead of an error, causing the caller to treat the failure as success.
2. It returns NULL for all errors, losing information about what actually
went wrong (-EIO, -ENOMEM, -EINVAL, etc.).
Fix both by converting the function to return ERR_PTR() on error, and
update the single caller (ntfs_inode_attach_all_extents) to check with
IS_ERR() and propagate the actual error code with PTR_ERR().
Fixes: af0db57d4293 ("ntfs: update inode operations")
Signed-off-by: Baolin Liu <liubaolin@xxxxxxxxxx>
---
fs/ntfs/inode.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 5aedc045f65a..xxxxxxxxxxxx 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -2904,8 +2904,7 @@ static inline void ntfs_init_big_inode(struct inode *vi)
* abort if deprotection or checks fail.
*
* Finally attach the ntfs inode to its base inode @base_ni and return a
- * pointer to the ntfs_inode structure on success or NULL on error, with errno
- * set to the error code.
+ * pointer to the ntfs_inode structure on success or ERR_PTR() on error.
*
* Note, extent inodes are never closed directly. They are automatically
* disposed off by the closing of the base inode.
@@ -2921,7 +2920,7 @@ static struct ntfs_inode *ntfs_extent_inode_open(struct ntfs_inode *base_ni,
struct super_block *sb;
if (!base_ni)
- return NULL;
+ return ERR_PTR(-EINVAL);
sb = base_ni->vol->sb;
ntfs_debug("Opening extent inode %llu (base mft record %llu).\n",
@@ -2940,7 +2939,7 @@ static struct ntfs_inode *ntfs_extent_inode_open(struct ntfs_inode *base_ni,
if (IS_ERR(ni_mrec)) {
ntfs_error(sb, "failed to map mft record for %llu",
ni->mft_no);
- goto out;
+ return ERR_PTR(PTR_ERR(ni_mrec));
}
/* Verify the sequence number if given. */
seq_no = MSEQNO_LE(mref);
@@ -2949,7 +2948,7 @@ static struct ntfs_inode *ntfs_extent_inode_open(struct ntfs_inode *base_ni,
ntfs_error(sb, "Found stale extent mft reference mft=%llu",
ni->mft_no);
unmap_mft_record(ni);
- goto out;
+ return ERR_PTR(-EINVAL);
}
unmap_mft_record(ni);
goto out;
@@ -2958,7 +2957,7 @@ static struct ntfs_inode *ntfs_extent_inode_open(struct ntfs_inode *base_ni,
/* Wasn't there, we need to load the extent inode. */
ni = ntfs_new_extent_inode(base_ni->vol->sb, mft_no);
if (!ni)
- goto out;
+ return ERR_PTR(-ENOMEM);
ni->seq_no = (u16)MSEQNO_LE(mref);
ni->nr_extents = -1;
@@ -2968,8 +2967,10 @@ static struct ntfs_inode *ntfs_extent_inode_open(struct ntfs_inode *base_ni,
i = (base_ni->nr_extents + 4) * sizeof(struct ntfs_inode *);
extent_nis = kvzalloc(i, GFP_NOFS);
- if (!extent_nis)
+ if (!extent_nis) {
+ ni = ERR_PTR(-ENOMEM);
goto err_out;
+ }
if (base_ni->nr_extents) {
memcpy(extent_nis, base_ni->ext.extent_ntfs_inos,
i - 4 * sizeof(struct ntfs_inode *));
@@ -2984,7 +2985,6 @@ static struct ntfs_inode *ntfs_extent_inode_open(struct ntfs_inode *base_ni,
return ni;
err_out:
ntfs_destroy_ext_inode(ni);
- ni = NULL;
goto out;
}
@@ -3025,9 +3025,12 @@ int ntfs_inode_attach_all_extents(struct ntfs_inode *ni)
while ((u8 *)ale < ni->attr_list + ni->attr_list_size) {
if (ni->mft_no != MREF_LE(ale->mft_reference) &&
prev_attached != MREF_LE(ale->mft_reference)) {
- if (!ntfs_extent_inode_open(ni, ale->mft_reference)) {
+ struct ntfs_inode *ext_ni;
+
+ ext_ni = ntfs_extent_inode_open(ni, ale->mft_reference);
+ if (IS_ERR(ext_ni)) {
ntfs_debug("Couldn't attach extent inode.\n");
- return -1;
+ return PTR_ERR(ext_ni);
}
prev_attached = MREF_LE(ale->mft_reference);
}
--
2.51.0