[lkml]   [2022]   [Jan]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    Subject[PATCH 4.9 124/157] 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
    @@ -462,12 +462,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);
    @@ -488,10 +488,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;
    @@ -503,7 +499,6 @@ int ext4_ext_migrate(struct inode *inode

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

    @@ -528,12 +523,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 20:14    [W:13.864 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site