Skip to content

Commit

Permalink
ext4: don't let i_reserved_meta_blocks go negative
Browse files Browse the repository at this point in the history
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>
Cc: stable@vger.kernel.org
  • Loading branch information
Brian Foster authored and Theodore Ts'o committed Jul 23, 2012
1 parent 968dee7 commit 97795d2
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions fs/ext4/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,15 @@ void ext4_da_update_reserve_space(struct inode *inode,
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;
Expand Down

0 comments on commit 97795d2

Please sign in to comment.