lkml.org 
[lkml]   [2012]   [Aug]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[ 096/122] ext4: dont let i_reserved_meta_blocks go negative
    Date
    From: Greg KH <gregkh@linuxfoundation.org>

    3.5-stable review patch. If anyone has any objections, please let me know.

    ------------------

    From: Brian Foster <bfoster@redhat.com>

    commit 97795d2a5b8d3c8dc4365d4bd3404191840453ba upstream.

    If we hit a condition where we have allocated metadata blocks that
    were not appropriately reserved, we risk underflow of
    ei->i_reserved_meta_blocks. In turn, this can throw
    sbi->s_dirtyclusters_counter significantly out of whack and undermine
    the nondelalloc fallback logic in ext4_nonda_switch(). Warn if this
    occurs and set i_allocated_meta_blocks to avoid this problem.

    This condition is reproduced by xfstests 270 against ext2 with
    delalloc enabled:

    Mar 28 08:58:02 localhost kernel: [ 171.526344] EXT4-fs (loop1): delayed block allocation failed for inode 14 at logical offset 64486 with max blocks 64 with error -28
    Mar 28 08:58:02 localhost kernel: [ 171.526346] EXT4-fs (loop1): This should not happen!! Data will be lost

    270 ultimately fails with an inconsistent filesystem and requires an
    fsck to repair. The cause of the error is an underflow in
    ext4_da_update_reserve_space() due to an unreserved meta block
    allocation.

    Signed-off-by: Brian Foster <bfoster@redhat.com>
    Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/ext4/inode.c | 9 +++++++++
    1 file changed, 9 insertions(+)

    --- a/fs/ext4/inode.c
    +++ b/fs/ext4/inode.c
    @@ -346,6 +346,15 @@ void ext4_da_update_reserve_space(struct
    used = ei->i_reserved_data_blocks;
    }

    + if (unlikely(ei->i_allocated_meta_blocks > ei->i_reserved_meta_blocks)) {
    + ext4_msg(inode->i_sb, KERN_NOTICE, "%s: ino %lu, allocated %d "
    + "with only %d reserved metadata blocks\n", __func__,
    + inode->i_ino, ei->i_allocated_meta_blocks,
    + ei->i_reserved_meta_blocks);
    + WARN_ON(1);
    + ei->i_allocated_meta_blocks = ei->i_reserved_meta_blocks;
    + }
    +
    /* Update per-inode reservations */
    ei->i_reserved_data_blocks -= used;
    ei->i_reserved_meta_blocks -= ei->i_allocated_meta_blocks;



    \
     
     \ /
      Last update: 2012-08-08 02:01    [W:4.082 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site