diff options
author | Josef Bacik | 2016-07-20 16:48:45 -0700 |
---|---|---|
committer | Chris Mason | 2016-07-20 16:58:04 -0700 |
commit | bac357dcec2956f01df9da5365be257741b534dc (patch) | |
tree | f696c4ea2ce8b51c9fe58f9bd5c6411693f7fc2d /fs/btrfs | |
parent | 24502ebb606baa87ba7b9a097a88398bd6edd2f4 (diff) |
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 <clm@fb.com>
Signed-off-by: Josef Bacik <jbacik@fb.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 5 |
1 files changed, 5 insertions, 0 deletions
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 && |