diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 0c466ccbed69..a1eb6d15fc28 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5901,6 +5901,23 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry, if (attr->ia_size == inode->i_size) inc_ivers = false; + /* + * If file has inline data but new size exceeds inline capacity, + * convert to extent-based storage first to prevent inconsistent + * state (inline flag set but size exceeds inline capacity). + */ + if (ext4_has_inline_data(inode) && + attr->ia_size > EXT4_I(inode)->i_inline_size) { + printk(KERN_WARNING "EXT4-fs: Converting inline data: inode=%lu old_size=%lld new_size=%lld inline_size=%u\n", + inode->i_ino, + inode->i_size, + attr->ia_size, + EXT4_I(inode)->i_inline_size); + error = ext4_convert_inline_data(inode); + if (error) + goto err_out; + } + if (shrink) { if (ext4_should_order_data(inode)) { error = ext4_begin_ordered_truncate(inode,