aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorNamjae Jeon <linkinjeon@kernel.org>2026-09-07 13:34:44 +0900
committerNamjae Jeon <linkinjeon@kernel.org>2026-09-13 11:41:49 +0900
commitfc440366c47000b768d013e347f60e81d60328ca (patch)
tree5c8c2398a7e85040fbc45715be939a34c8f6d684
parentntfs: ignore interrupted inode reads as corruption (diff)
ntfs: discard inodes that fail initialization
Discard a newly allocated normal, attribute, or index inode when initialization fails. Keeping an incompletely initialized inode in the inode cache can expose stale sequence data to later directory lookups. Fixes: d7aa04984f12 ("ntfs: return errors from inode initialization") Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
-rw-r--r--fs/ntfs/inode.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 210adf589319..b1f9a72ea963 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -170,17 +170,18 @@ struct inode *ntfs_iget(struct super_block *sb, u64 mft_no)
/* If this is a freshly allocated inode, need to read it now. */
if (inode_state_read_once(vi) & I_NEW) {
err = ntfs_read_locked_inode(vi);
- unlock_new_inode(vi);
+ if (err)
+ discard_new_inode(vi);
+ else
+ unlock_new_inode(vi);
}
/*
* There is no point in keeping bad inodes around. This also
* simplifies things in that we never need to check for bad inodes
* elsewhere.
*/
- if (unlikely(err)) {
- iput(vi);
+ if (unlikely(err))
vi = ERR_PTR(err);
- }
return vi;
}
@@ -231,17 +232,18 @@ struct inode *ntfs_attr_iget(struct inode *base_vi, __le32 type,
/* If this is a freshly allocated inode, need to read it now. */
if (inode_state_read_once(vi) & I_NEW) {
err = ntfs_read_locked_attr_inode(base_vi, vi);
- unlock_new_inode(vi);
+ if (err)
+ discard_new_inode(vi);
+ else
+ unlock_new_inode(vi);
}
/*
* There is no point in keeping bad attribute inodes around. This also
* simplifies things in that we never need to check for bad attribute
* inodes elsewhere.
*/
- if (unlikely(err)) {
- iput(vi);
+ if (unlikely(err))
vi = ERR_PTR(err);
- }
return vi;
}
@@ -286,17 +288,18 @@ struct inode *ntfs_index_iget(struct inode *base_vi, __le16 *name,
/* If this is a freshly allocated inode, need to read it now. */
if (inode_state_read_once(vi) & I_NEW) {
err = ntfs_read_locked_index_inode(base_vi, vi);
- unlock_new_inode(vi);
+ if (err)
+ discard_new_inode(vi);
+ else
+ unlock_new_inode(vi);
}
/*
* There is no point in keeping bad index inodes around. This also
* simplifies things in that we never need to check for bad index
* inodes elsewhere.
*/
- if (unlikely(err)) {
- iput(vi);
+ if (unlikely(err))
vi = ERR_PTR(err);
- }
return vi;
}