From: Josef Bacik Date: Wed, 20 Jul 2016 23:48:45 +0000 (-0700) Subject: Btrfs: avoid deadlocks during reservations in btrfs_truncate_block X-Git-Tag: v4.8-rc1~38^2~3 X-Git-Url: http://git.cascardo.eti.br/?a=commitdiff_plain;h=bac357dcec2956f01df9da5365be257741b534dc;p=cascardo%2Flinux.git Btrfs: avoid deadlocks during reservations in btrfs_truncate_block The new enospc code makes it possible to deadlock if we don't use FLUSH_LIMIT during reservations inside a transaction. This enforces the correct flush type to avoid both deadlocks and assertions Signed-off-by: Chris Mason Signed-off-by: Josef Bacik --- diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 3a129c42658e..9fcb8c97083b 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -5939,10 +5939,15 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) * the middle of a transaction commit. We also don't need the delalloc * mutex since we won't race with anybody. We need this mostly to make * lockdep shut its filthy mouth. + * + * If we have a transaction open (can happen if we call truncate_block + * from truncate), then we need FLUSH_LIMIT so we don't deadlock. */ if (btrfs_is_free_space_inode(inode)) { flush = BTRFS_RESERVE_NO_FLUSH; delalloc_lock = false; + } else if (current->journal_info) { + flush = BTRFS_RESERVE_FLUSH_LIMIT; } if (flush != BTRFS_RESERVE_NO_FLUSH &&