diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 48 |
1 files changed, 24 insertions, 24 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 237da012f7d0..611b66d73e80 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -5084,7 +5084,8 @@ void btrfs_evict_inode(struct inode *inode) | |||
5084 | goto no_delete; | 5084 | goto no_delete; |
5085 | } | 5085 | } |
5086 | /* do we really want it for ->i_nlink > 0 and zero btrfs_root_refs? */ | 5086 | /* do we really want it for ->i_nlink > 0 and zero btrfs_root_refs? */ |
5087 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | 5087 | if (!special_file(inode->i_mode)) |
5088 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | ||
5088 | 5089 | ||
5089 | btrfs_free_io_failure_record(inode, 0, (u64)-1); | 5090 | btrfs_free_io_failure_record(inode, 0, (u64)-1); |
5090 | 5091 | ||
@@ -6909,8 +6910,7 @@ out: | |||
6909 | 6910 | ||
6910 | trace_btrfs_get_extent(root, em); | 6911 | trace_btrfs_get_extent(root, em); |
6911 | 6912 | ||
6912 | if (path) | 6913 | btrfs_free_path(path); |
6913 | btrfs_free_path(path); | ||
6914 | if (trans) { | 6914 | if (trans) { |
6915 | ret = btrfs_end_transaction(trans, root); | 6915 | ret = btrfs_end_transaction(trans, root); |
6916 | if (!err) | 6916 | if (!err) |
@@ -7409,6 +7409,10 @@ static struct extent_map *create_pinned_em(struct inode *inode, u64 start, | |||
7409 | return em; | 7409 | return em; |
7410 | } | 7410 | } |
7411 | 7411 | ||
7412 | struct btrfs_dio_data { | ||
7413 | u64 outstanding_extents; | ||
7414 | u64 reserve; | ||
7415 | }; | ||
7412 | 7416 | ||
7413 | static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, | 7417 | static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, |
7414 | struct buffer_head *bh_result, int create) | 7418 | struct buffer_head *bh_result, int create) |
@@ -7416,10 +7420,10 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, | |||
7416 | struct extent_map *em; | 7420 | struct extent_map *em; |
7417 | struct btrfs_root *root = BTRFS_I(inode)->root; | 7421 | struct btrfs_root *root = BTRFS_I(inode)->root; |
7418 | struct extent_state *cached_state = NULL; | 7422 | struct extent_state *cached_state = NULL; |
7423 | struct btrfs_dio_data *dio_data = NULL; | ||
7419 | u64 start = iblock << inode->i_blkbits; | 7424 | u64 start = iblock << inode->i_blkbits; |
7420 | u64 lockstart, lockend; | 7425 | u64 lockstart, lockend; |
7421 | u64 len = bh_result->b_size; | 7426 | u64 len = bh_result->b_size; |
7422 | u64 *outstanding_extents = NULL; | ||
7423 | int unlock_bits = EXTENT_LOCKED; | 7427 | int unlock_bits = EXTENT_LOCKED; |
7424 | int ret = 0; | 7428 | int ret = 0; |
7425 | 7429 | ||
@@ -7437,7 +7441,7 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, | |||
7437 | * that anything that needs to check if there's a transction doesn't get | 7441 | * that anything that needs to check if there's a transction doesn't get |
7438 | * confused. | 7442 | * confused. |
7439 | */ | 7443 | */ |
7440 | outstanding_extents = current->journal_info; | 7444 | dio_data = current->journal_info; |
7441 | current->journal_info = NULL; | 7445 | current->journal_info = NULL; |
7442 | } | 7446 | } |
7443 | 7447 | ||
@@ -7569,17 +7573,18 @@ unlock: | |||
7569 | * within our reservation, otherwise we need to adjust our inode | 7573 | * within our reservation, otherwise we need to adjust our inode |
7570 | * counter appropriately. | 7574 | * counter appropriately. |
7571 | */ | 7575 | */ |
7572 | if (*outstanding_extents) { | 7576 | if (dio_data->outstanding_extents) { |
7573 | (*outstanding_extents)--; | 7577 | (dio_data->outstanding_extents)--; |
7574 | } else { | 7578 | } else { |
7575 | spin_lock(&BTRFS_I(inode)->lock); | 7579 | spin_lock(&BTRFS_I(inode)->lock); |
7576 | BTRFS_I(inode)->outstanding_extents++; | 7580 | BTRFS_I(inode)->outstanding_extents++; |
7577 | spin_unlock(&BTRFS_I(inode)->lock); | 7581 | spin_unlock(&BTRFS_I(inode)->lock); |
7578 | } | 7582 | } |
7579 | 7583 | ||
7580 | current->journal_info = outstanding_extents; | ||
7581 | btrfs_free_reserved_data_space(inode, len); | 7584 | btrfs_free_reserved_data_space(inode, len); |
7582 | set_bit(BTRFS_INODE_DIO_READY, &BTRFS_I(inode)->runtime_flags); | 7585 | WARN_ON(dio_data->reserve < len); |
7586 | dio_data->reserve -= len; | ||
7587 | current->journal_info = dio_data; | ||
7583 | } | 7588 | } |
7584 | 7589 | ||
7585 | /* | 7590 | /* |
@@ -7602,8 +7607,8 @@ unlock: | |||
7602 | unlock_err: | 7607 | unlock_err: |
7603 | clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend, | 7608 | clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend, |
7604 | unlock_bits, 1, 0, &cached_state, GFP_NOFS); | 7609 | unlock_bits, 1, 0, &cached_state, GFP_NOFS); |
7605 | if (outstanding_extents) | 7610 | if (dio_data) |
7606 | current->journal_info = outstanding_extents; | 7611 | current->journal_info = dio_data; |
7607 | return ret; | 7612 | return ret; |
7608 | } | 7613 | } |
7609 | 7614 | ||
@@ -8330,7 +8335,8 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, | |||
8330 | { | 8335 | { |
8331 | struct file *file = iocb->ki_filp; | 8336 | struct file *file = iocb->ki_filp; |
8332 | struct inode *inode = file->f_mapping->host; | 8337 | struct inode *inode = file->f_mapping->host; |
8333 | u64 outstanding_extents = 0; | 8338 | struct btrfs_root *root = BTRFS_I(inode)->root; |
8339 | struct btrfs_dio_data dio_data = { 0 }; | ||
8334 | size_t count = 0; | 8340 | size_t count = 0; |
8335 | int flags = 0; | 8341 | int flags = 0; |
8336 | bool wakeup = true; | 8342 | bool wakeup = true; |
@@ -8368,7 +8374,7 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, | |||
8368 | ret = btrfs_delalloc_reserve_space(inode, count); | 8374 | ret = btrfs_delalloc_reserve_space(inode, count); |
8369 | if (ret) | 8375 | if (ret) |
8370 | goto out; | 8376 | goto out; |
8371 | outstanding_extents = div64_u64(count + | 8377 | dio_data.outstanding_extents = div64_u64(count + |
8372 | BTRFS_MAX_EXTENT_SIZE - 1, | 8378 | BTRFS_MAX_EXTENT_SIZE - 1, |
8373 | BTRFS_MAX_EXTENT_SIZE); | 8379 | BTRFS_MAX_EXTENT_SIZE); |
8374 | 8380 | ||
@@ -8377,7 +8383,8 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, | |||
8377 | * do the accounting properly if we go over the number we | 8383 | * do the accounting properly if we go over the number we |
8378 | * originally calculated. Abuse current->journal_info for this. | 8384 | * originally calculated. Abuse current->journal_info for this. |
8379 | */ | 8385 | */ |
8380 | current->journal_info = &outstanding_extents; | 8386 | dio_data.reserve = round_up(count, root->sectorsize); |
8387 | current->journal_info = &dio_data; | ||
8381 | } else if (test_bit(BTRFS_INODE_READDIO_NEED_LOCK, | 8388 | } else if (test_bit(BTRFS_INODE_READDIO_NEED_LOCK, |
8382 | &BTRFS_I(inode)->runtime_flags)) { | 8389 | &BTRFS_I(inode)->runtime_flags)) { |
8383 | inode_dio_end(inode); | 8390 | inode_dio_end(inode); |
@@ -8392,16 +8399,9 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, | |||
8392 | if (iov_iter_rw(iter) == WRITE) { | 8399 | if (iov_iter_rw(iter) == WRITE) { |
8393 | current->journal_info = NULL; | 8400 | current->journal_info = NULL; |
8394 | if (ret < 0 && ret != -EIOCBQUEUED) { | 8401 | if (ret < 0 && ret != -EIOCBQUEUED) { |
8395 | /* | 8402 | if (dio_data.reserve) |
8396 | * If the error comes from submitting stage, | 8403 | btrfs_delalloc_release_space(inode, |
8397 | * btrfs_get_blocsk_direct() has free'd data space, | 8404 | dio_data.reserve); |
8398 | * and metadata space will be handled by | ||
8399 | * finish_ordered_fn, don't do that again to make | ||
8400 | * sure bytes_may_use is correct. | ||
8401 | */ | ||
8402 | if (!test_and_clear_bit(BTRFS_INODE_DIO_READY, | ||
8403 | &BTRFS_I(inode)->runtime_flags)) | ||
8404 | btrfs_delalloc_release_space(inode, count); | ||
8405 | } else if (ret >= 0 && (size_t)ret < count) | 8405 | } else if (ret >= 0 && (size_t)ret < count) |
8406 | btrfs_delalloc_release_space(inode, | 8406 | btrfs_delalloc_release_space(inode, |
8407 | count - (size_t)ret); | 8407 | count - (size_t)ret); |