[lkml]   [2022]   [Jan]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
Patch in this message
Subject[PATCH 5.4 272/320] ext4: dont use the orphan list when migrating an inode
From: Theodore Ts'o <>

commit 6eeaf88fd586f05aaf1d48cb3a139d2a5c6eb055 upstream.

We probably want to remove the indirect block to extents migration
feature after a deprecation window, but until then, let's fix a
potential data loss problem caused by the fact that we put the
tmp_inode on the orphan list. In the unlikely case where we crash and
do a journal recovery, the data blocks belonging to the inode being
migrated are also represented in the tmp_inode on the orphan list ---
and so its data blocks will get marked unallocated, and available for

Instead, stop putting the tmp_inode on the oprhan list. So in the
case where we crash while migrating the inode, we'll leak an inode,
which is not a disaster. It will be easily fixed the next time we run
fsck, and it's better than potentially having blocks getting claimed
by two different files, and losing data as a result.

Signed-off-by: Theodore Ts'o <>
Reviewed-by: Lukas Czerner <>
Signed-off-by: Greg Kroah-Hartman <>
fs/ext4/migrate.c | 19 ++++---------------
1 file changed, 4 insertions(+), 15 deletions(-)

--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -455,12 +455,12 @@ int ext4_ext_migrate(struct inode *inode

- * Worst case we can touch the allocation bitmaps, a bgd
- * block, and a block to link in the orphan list. We do need
- * need to worry about credits for modifying the quota inode.
+ * Worst case we can touch the allocation bitmaps and a block
+ * group descriptor block. We do need need to worry about
+ * credits for modifying the quota inode.
handle = ext4_journal_start(inode, EXT4_HT_MIGRATE,
- 4 + EXT4_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb));
+ 3 + EXT4_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb));

if (IS_ERR(handle)) {
retval = PTR_ERR(handle);
@@ -481,10 +481,6 @@ int ext4_ext_migrate(struct inode *inode
* Use the correct seed for checksum (i.e. the seed from 'inode'). This
* is so that the metadata blocks will have the correct checksum after
* the migration.
- *
- * Note however that, if a crash occurs during the migration process,
- * the recovery process is broken because the tmp_inode checksums will
- * be wrong and the orphans cleanup will fail.
ei = EXT4_I(inode);
EXT4_I(tmp_inode)->i_csum_seed = ei->i_csum_seed;
@@ -496,7 +492,6 @@ int ext4_ext_migrate(struct inode *inode

ext4_ext_tree_init(handle, tmp_inode);
- ext4_orphan_add(handle, tmp_inode);

@@ -521,12 +516,6 @@ int ext4_ext_migrate(struct inode *inode

handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1);
if (IS_ERR(handle)) {
- /*
- * It is impossible to update on-disk structures without
- * a handle, so just rollback in-core changes and live other
- * work to orphan_list_cleanup()
- */
- ext4_orphan_del(NULL, tmp_inode);
retval = PTR_ERR(handle);
goto out_tmp_inode;

 \ /
  Last update: 2022-01-24 21:11    [W:0.738 / U:0.360 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site