Skip to content

Commit 1d73b52

Browse files
jankaragregkh
authored andcommitted
ext4: fix checks for orphan inodes
commit acf943e upstream. When orphan file feature is enabled, inode can be tracked as orphan either in the standard orphan list or in the orphan file. The first can be tested by checking ei->i_orphan list head, the second is recorded by EXT4_STATE_ORPHAN_FILE inode state flag. There are several places where we want to check whether inode is tracked as orphan and only some of them properly check for both possibilities. Luckily the consequences are mostly minor, the worst that can happen is that we track an inode as orphan although we don't need to and e2fsck then complains (resulting in occasional ext4/307 xfstest failures). Fix the problem by introducing a helper for checking whether an inode is tracked as orphan and use it in appropriate places. Fixes: 4a79a98 ("ext4: Improve scalability of ext4 orphan file handling") Cc: stable@kernel.org Signed-off-by: Jan Kara <jack@suse.cz> Reviewed-by: Zhang Yi <yi.zhang@huawei.com> Message-ID: <20250925123038.20264-2-jack@suse.cz> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 00110f3 commit 1d73b52

File tree

5 files changed

+15
-9
lines changed

5 files changed

+15
-9
lines changed

fs/ext4/ext4.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1981,6 +1981,16 @@ static inline bool ext4_verity_in_progress(struct inode *inode)
19811981

19821982
#define NEXT_ORPHAN(inode) EXT4_I(inode)->i_dtime
19831983

1984+
/*
1985+
* Check whether the inode is tracked as orphan (either in orphan file or
1986+
* orphan list).
1987+
*/
1988+
static inline bool ext4_inode_orphan_tracked(struct inode *inode)
1989+
{
1990+
return ext4_test_inode_state(inode, EXT4_STATE_ORPHAN_FILE) ||
1991+
!list_empty(&EXT4_I(inode)->i_orphan);
1992+
}
1993+
19841994
/*
19851995
* Codes for operating systems
19861996
*/

fs/ext4/file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ static void ext4_inode_extension_cleanup(struct inode *inode, bool need_trunc)
354354
* to cleanup the orphan list in ext4_handle_inode_extension(). Do it
355355
* now.
356356
*/
357-
if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) {
357+
if (ext4_inode_orphan_tracked(inode) && inode->i_nlink) {
358358
handle_t *handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
359359

360360
if (IS_ERR(handle)) {

fs/ext4/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4748,7 +4748,7 @@ static int ext4_fill_raw_inode(struct inode *inode, struct ext4_inode *raw_inode
47484748
* old inodes get re-used with the upper 16 bits of the
47494749
* uid/gid intact.
47504750
*/
4751-
if (ei->i_dtime && list_empty(&ei->i_orphan)) {
4751+
if (ei->i_dtime && !ext4_inode_orphan_tracked(inode)) {
47524752
raw_inode->i_uid_high = 0;
47534753
raw_inode->i_gid_high = 0;
47544754
} else {

fs/ext4/orphan.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
109109

110110
WARN_ON_ONCE(!(inode->i_state & (I_NEW | I_FREEING)) &&
111111
!inode_is_locked(inode));
112-
/*
113-
* Inode orphaned in orphan file or in orphan list?
114-
*/
115-
if (ext4_test_inode_state(inode, EXT4_STATE_ORPHAN_FILE) ||
116-
!list_empty(&EXT4_I(inode)->i_orphan))
112+
if (ext4_inode_orphan_tracked(inode))
117113
return 0;
118114

119115
/*

fs/ext4/super.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,9 +1438,9 @@ static void ext4_free_in_core_inode(struct inode *inode)
14381438

14391439
static void ext4_destroy_inode(struct inode *inode)
14401440
{
1441-
if (!list_empty(&(EXT4_I(inode)->i_orphan))) {
1441+
if (ext4_inode_orphan_tracked(inode)) {
14421442
ext4_msg(inode->i_sb, KERN_ERR,
1443-
"Inode %lu (%p): orphan list check failed!",
1443+
"Inode %lu (%p): inode tracked as orphan!",
14441444
inode->i_ino, EXT4_I(inode));
14451445
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 4,
14461446
EXT4_I(inode), sizeof(struct ext4_inode_info),

0 commit comments

Comments
 (0)