]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ext2: Fix lost inode updates for IS_SYNC inodes
authorJan Kara <jack@suse.cz>
Mon, 27 Jul 2026 10:49:24 +0000 (12:49 +0200)
committerChristian Brauner <brauner@kernel.org>
Mon, 27 Jul 2026 14:25:32 +0000 (16:25 +0200)
ext2_setsize() and ext2_xattr_set2() had a construct like:

if (IS_SYNC(inode)) {
sync_inode_metadata(inode, 1);
} else {
mark_inode_dirty(inode);
}

which leads to lost inode updates for IS_SYNC inodes because
sync_inode_metadata() does anything only if the inode is already dirty
and hence inode updates may be simply lost. Fix the problem by
unconditionally marking the inode dirty and *then* call
sync_inode_metadata().

CC: stable@vger.kernel.org
Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20260727104923.3828017-26-jack@suse.cz
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
fs/ext2/inode.c
fs/ext2/xattr.c

index 29808629cce56fd4958e56d962eb1dc2536bd743..269b1c9fba5f77e6fd967a523c7fcd593bf6b00b 100644 (file)
@@ -1258,12 +1258,9 @@ static int ext2_setsize(struct inode *inode, loff_t newsize)
        filemap_invalidate_unlock(inode->i_mapping);
 
        inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
-       if (inode_needs_sync(inode)) {
-               mmb_sync(&EXT2_I(inode)->i_metadata_bhs);
+       mark_inode_dirty(inode);
+       if (inode_needs_sync(inode))
                sync_inode_metadata(inode, 1);
-       } else {
-               mark_inode_dirty(inode);
-       }
 
        return 0;
 }
index e55d16abf422f4345dde473e64e619b593c113ad..be63f89402a38172f890775bcd84fc9c6568ebe2 100644 (file)
@@ -777,6 +777,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
        /* Update the inode. */
        EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
        inode_set_ctime_current(inode);
+       mark_inode_dirty(inode);
        if (IS_SYNC(inode)) {
                error = sync_inode_metadata(inode, 1);
                /* In case sync failed due to ENOSPC the inode was actually
@@ -789,8 +790,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
                        }
                        goto cleanup;
                }
-       } else
-               mark_inode_dirty(inode);
+       }
 
        error = 0;
        if (old_bh && old_bh != new_bh) {