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", |
