Message ID | 4F79C245.8010101@redhat.com |
---|---|
State | Accepted, archived |
Headers | show |
On Mon, Apr 02, 2012 at 11:14:13AM -0400, Brian Foster wrote: > From: Brian Foster <bfoster@redhat.com> > > 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 fix up the counter to handle only what we've reserved. > This condition is reproduced by xfstests 270 against ext2 with > delalloc enabled. > > Signed-off-by: Brian Foster <bfoster@redhat.com> Hi Brian, Thanks for looking into this xfstests failure and proposing a bug fix. My apologies for not getting back to you until now. I modified your commit description a little, but the patch looks good to me. - Ted Author: Brian Foster <bfoster@redhat.com> Date: Sun Jul 22 23:59:40 2012 -0400 ext4: don't let i_reserved_meta_blocks go negative 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 blo Mar 28 08:58:02 localhost kernel: [ 171.526346] EXT4-fs (loop1): This should 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 -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index c77b0bd..b58845c 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -279,6 +279,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;