diff options
-rw-r--r-- | fs/btrfs/extent-tree.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index afc3ac5e57d7..d133edfcd449 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -4535,16 +4535,25 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) | |||
4535 | int extra_reserve = 0; | 4535 | int extra_reserve = 0; |
4536 | enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_FLUSH_ALL; | 4536 | enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_FLUSH_ALL; |
4537 | int ret; | 4537 | int ret; |
4538 | bool delalloc_lock = true; | ||
4538 | 4539 | ||
4539 | /* Need to be holding the i_mutex here if we aren't free space cache */ | 4540 | /* If we are a free space inode we need to not flush since we will be in |
4540 | if (btrfs_is_free_space_inode(inode)) | 4541 | * the middle of a transaction commit. We also don't need the delalloc |
4542 | * mutex since we won't race with anybody. We need this mostly to make | ||
4543 | * lockdep shut its filthy mouth. | ||
4544 | */ | ||
4545 | if (btrfs_is_free_space_inode(inode)) { | ||
4541 | flush = BTRFS_RESERVE_NO_FLUSH; | 4546 | flush = BTRFS_RESERVE_NO_FLUSH; |
4547 | delalloc_lock = false; | ||
4548 | } | ||
4542 | 4549 | ||
4543 | if (flush != BTRFS_RESERVE_NO_FLUSH && | 4550 | if (flush != BTRFS_RESERVE_NO_FLUSH && |
4544 | btrfs_transaction_in_commit(root->fs_info)) | 4551 | btrfs_transaction_in_commit(root->fs_info)) |
4545 | schedule_timeout(1); | 4552 | schedule_timeout(1); |
4546 | 4553 | ||
4547 | mutex_lock(&BTRFS_I(inode)->delalloc_mutex); | 4554 | if (delalloc_lock) |
4555 | mutex_lock(&BTRFS_I(inode)->delalloc_mutex); | ||
4556 | |||
4548 | num_bytes = ALIGN(num_bytes, root->sectorsize); | 4557 | num_bytes = ALIGN(num_bytes, root->sectorsize); |
4549 | 4558 | ||
4550 | spin_lock(&BTRFS_I(inode)->lock); | 4559 | spin_lock(&BTRFS_I(inode)->lock); |
@@ -4577,7 +4586,8 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) | |||
4577 | spin_lock(&BTRFS_I(inode)->lock); | 4586 | spin_lock(&BTRFS_I(inode)->lock); |
4578 | calc_csum_metadata_size(inode, num_bytes, 0); | 4587 | calc_csum_metadata_size(inode, num_bytes, 0); |
4579 | spin_unlock(&BTRFS_I(inode)->lock); | 4588 | spin_unlock(&BTRFS_I(inode)->lock); |
4580 | mutex_unlock(&BTRFS_I(inode)->delalloc_mutex); | 4589 | if (delalloc_lock) |
4590 | mutex_unlock(&BTRFS_I(inode)->delalloc_mutex); | ||
4581 | return ret; | 4591 | return ret; |
4582 | } | 4592 | } |
4583 | } | 4593 | } |
@@ -4616,7 +4626,8 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) | |||
4616 | btrfs_qgroup_free(root, num_bytes + | 4626 | btrfs_qgroup_free(root, num_bytes + |
4617 | nr_extents * root->leafsize); | 4627 | nr_extents * root->leafsize); |
4618 | } | 4628 | } |
4619 | mutex_unlock(&BTRFS_I(inode)->delalloc_mutex); | 4629 | if (delalloc_lock) |
4630 | mutex_unlock(&BTRFS_I(inode)->delalloc_mutex); | ||
4620 | return ret; | 4631 | return ret; |
4621 | } | 4632 | } |
4622 | 4633 | ||
@@ -4628,7 +4639,9 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) | |||
4628 | } | 4639 | } |
4629 | BTRFS_I(inode)->reserved_extents += nr_extents; | 4640 | BTRFS_I(inode)->reserved_extents += nr_extents; |
4630 | spin_unlock(&BTRFS_I(inode)->lock); | 4641 | spin_unlock(&BTRFS_I(inode)->lock); |
4631 | mutex_unlock(&BTRFS_I(inode)->delalloc_mutex); | 4642 | |
4643 | if (delalloc_lock) | ||
4644 | mutex_unlock(&BTRFS_I(inode)->delalloc_mutex); | ||
4632 | 4645 | ||
4633 | if (to_reserve) | 4646 | if (to_reserve) |
4634 | trace_btrfs_space_reservation(root->fs_info,"delalloc", | 4647 | trace_btrfs_space_reservation(root->fs_info,"delalloc", |