Skip to content

Commit f50bece

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 8173dcf commit f50bece

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
@@ -1969,6 +1969,16 @@ static inline bool ext4_verity_in_progress(struct inode *inode)
19691969

19701970
#define NEXT_ORPHAN(inode) EXT4_I(inode)->i_dtime
19711971

1972+
/*
1973+
* Check whether the inode is tracked as orphan (either in orphan file or
1974+
* orphan list).
1975+
*/
1976+
static inline bool ext4_inode_orphan_tracked(struct inode *inode)
1977+
{
1978+
return ext4_test_inode_state(inode, EXT4_STATE_ORPHAN_FILE) ||
1979+
!list_empty(&EXT4_I(inode)->i_orphan);
1980+
}
1981+
19721982
/*
19731983
* Codes for operating systems
19741984
*/

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
@@ -4330,7 +4330,7 @@ static int ext4_fill_raw_inode(struct inode *inode, struct ext4_inode *raw_inode
43304330
* old inodes get re-used with the upper 16 bits of the
43314331
* uid/gid intact.
43324332
*/
4333-
if (ei->i_dtime && list_empty(&ei->i_orphan)) {
4333+
if (ei->i_dtime && !ext4_inode_orphan_tracked(inode)) {
43344334
raw_inode->i_uid_high = 0;
43354335
raw_inode->i_gid_high = 0;
43364336
} 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
@@ -1461,9 +1461,9 @@ static void ext4_free_in_core_inode(struct inode *inode)
14611461

14621462
static void ext4_destroy_inode(struct inode *inode)
14631463
{
1464-
if (!list_empty(&(EXT4_I(inode)->i_orphan))) {
1464+
if (ext4_inode_orphan_tracked(inode)) {
14651465
ext4_msg(inode->i_sb, KERN_ERR,
1466-
"Inode %lu (%p): orphan list check failed!",
1466+
"Inode %lu (%p): inode tracked as orphan!",
14671467
inode->i_ino, EXT4_I(inode));
14681468
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 4,
14691469
EXT4_I(inode), sizeof(struct ext4_inode_info),

0 commit comments

Comments
 (0)