diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 185 |
1 files changed, 129 insertions, 56 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5cc64ab9c48..7cd8ab0ef04 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -954,6 +954,7 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page, | |||
954 | 1, 0, NULL, GFP_NOFS); | 954 | 1, 0, NULL, GFP_NOFS); |
955 | while (start < end) { | 955 | while (start < end) { |
956 | async_cow = kmalloc(sizeof(*async_cow), GFP_NOFS); | 956 | async_cow = kmalloc(sizeof(*async_cow), GFP_NOFS); |
957 | BUG_ON(!async_cow); | ||
957 | async_cow->inode = inode; | 958 | async_cow->inode = inode; |
958 | async_cow->root = root; | 959 | async_cow->root = root; |
959 | async_cow->locked_page = locked_page; | 960 | async_cow->locked_page = locked_page; |
@@ -1770,9 +1771,12 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1770 | add_pending_csums(trans, inode, ordered_extent->file_offset, | 1771 | add_pending_csums(trans, inode, ordered_extent->file_offset, |
1771 | &ordered_extent->list); | 1772 | &ordered_extent->list); |
1772 | 1773 | ||
1773 | btrfs_ordered_update_i_size(inode, 0, ordered_extent); | 1774 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); |
1774 | ret = btrfs_update_inode(trans, root, inode); | 1775 | if (!ret) { |
1775 | BUG_ON(ret); | 1776 | ret = btrfs_update_inode(trans, root, inode); |
1777 | BUG_ON(ret); | ||
1778 | } | ||
1779 | ret = 0; | ||
1776 | out: | 1780 | out: |
1777 | if (nolock) { | 1781 | if (nolock) { |
1778 | if (trans) | 1782 | if (trans) |
@@ -2590,6 +2594,13 @@ static void fill_inode_item(struct btrfs_trans_handle *trans, | |||
2590 | struct btrfs_inode_item *item, | 2594 | struct btrfs_inode_item *item, |
2591 | struct inode *inode) | 2595 | struct inode *inode) |
2592 | { | 2596 | { |
2597 | if (!leaf->map_token) | ||
2598 | map_private_extent_buffer(leaf, (unsigned long)item, | ||
2599 | sizeof(struct btrfs_inode_item), | ||
2600 | &leaf->map_token, &leaf->kaddr, | ||
2601 | &leaf->map_start, &leaf->map_len, | ||
2602 | KM_USER1); | ||
2603 | |||
2593 | btrfs_set_inode_uid(leaf, item, inode->i_uid); | 2604 | btrfs_set_inode_uid(leaf, item, inode->i_uid); |
2594 | btrfs_set_inode_gid(leaf, item, inode->i_gid); | 2605 | btrfs_set_inode_gid(leaf, item, inode->i_gid); |
2595 | btrfs_set_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size); | 2606 | btrfs_set_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size); |
@@ -2618,6 +2629,11 @@ static void fill_inode_item(struct btrfs_trans_handle *trans, | |||
2618 | btrfs_set_inode_rdev(leaf, item, inode->i_rdev); | 2629 | btrfs_set_inode_rdev(leaf, item, inode->i_rdev); |
2619 | btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags); | 2630 | btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags); |
2620 | btrfs_set_inode_block_group(leaf, item, BTRFS_I(inode)->block_group); | 2631 | btrfs_set_inode_block_group(leaf, item, BTRFS_I(inode)->block_group); |
2632 | |||
2633 | if (leaf->map_token) { | ||
2634 | unmap_extent_buffer(leaf, leaf->map_token, KM_USER1); | ||
2635 | leaf->map_token = NULL; | ||
2636 | } | ||
2621 | } | 2637 | } |
2622 | 2638 | ||
2623 | /* | 2639 | /* |
@@ -4207,10 +4223,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
4207 | struct btrfs_key found_key; | 4223 | struct btrfs_key found_key; |
4208 | struct btrfs_path *path; | 4224 | struct btrfs_path *path; |
4209 | int ret; | 4225 | int ret; |
4210 | u32 nritems; | ||
4211 | struct extent_buffer *leaf; | 4226 | struct extent_buffer *leaf; |
4212 | int slot; | 4227 | int slot; |
4213 | int advance; | ||
4214 | unsigned char d_type; | 4228 | unsigned char d_type; |
4215 | int over = 0; | 4229 | int over = 0; |
4216 | u32 di_cur; | 4230 | u32 di_cur; |
@@ -4253,27 +4267,19 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
4253 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 4267 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
4254 | if (ret < 0) | 4268 | if (ret < 0) |
4255 | goto err; | 4269 | goto err; |
4256 | advance = 0; | ||
4257 | 4270 | ||
4258 | while (1) { | 4271 | while (1) { |
4259 | leaf = path->nodes[0]; | 4272 | leaf = path->nodes[0]; |
4260 | nritems = btrfs_header_nritems(leaf); | ||
4261 | slot = path->slots[0]; | 4273 | slot = path->slots[0]; |
4262 | if (advance || slot >= nritems) { | 4274 | if (slot >= btrfs_header_nritems(leaf)) { |
4263 | if (slot >= nritems - 1) { | 4275 | ret = btrfs_next_leaf(root, path); |
4264 | ret = btrfs_next_leaf(root, path); | 4276 | if (ret < 0) |
4265 | if (ret) | 4277 | goto err; |
4266 | break; | 4278 | else if (ret > 0) |
4267 | leaf = path->nodes[0]; | 4279 | break; |
4268 | nritems = btrfs_header_nritems(leaf); | 4280 | continue; |
4269 | slot = path->slots[0]; | ||
4270 | } else { | ||
4271 | slot++; | ||
4272 | path->slots[0]++; | ||
4273 | } | ||
4274 | } | 4281 | } |
4275 | 4282 | ||
4276 | advance = 1; | ||
4277 | item = btrfs_item_nr(leaf, slot); | 4283 | item = btrfs_item_nr(leaf, slot); |
4278 | btrfs_item_key_to_cpu(leaf, &found_key, slot); | 4284 | btrfs_item_key_to_cpu(leaf, &found_key, slot); |
4279 | 4285 | ||
@@ -4282,7 +4288,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
4282 | if (btrfs_key_type(&found_key) != key_type) | 4288 | if (btrfs_key_type(&found_key) != key_type) |
4283 | break; | 4289 | break; |
4284 | if (found_key.offset < filp->f_pos) | 4290 | if (found_key.offset < filp->f_pos) |
4285 | continue; | 4291 | goto next; |
4286 | 4292 | ||
4287 | filp->f_pos = found_key.offset; | 4293 | filp->f_pos = found_key.offset; |
4288 | 4294 | ||
@@ -4335,6 +4341,8 @@ skip: | |||
4335 | di_cur += di_len; | 4341 | di_cur += di_len; |
4336 | di = (struct btrfs_dir_item *)((char *)di + di_len); | 4342 | di = (struct btrfs_dir_item *)((char *)di + di_len); |
4337 | } | 4343 | } |
4344 | next: | ||
4345 | path->slots[0]++; | ||
4338 | } | 4346 | } |
4339 | 4347 | ||
4340 | /* Reached end of directory/root. Bump pos past the last item. */ | 4348 | /* Reached end of directory/root. Bump pos past the last item. */ |
@@ -4527,14 +4535,17 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
4527 | BUG_ON(!path); | 4535 | BUG_ON(!path); |
4528 | 4536 | ||
4529 | inode = new_inode(root->fs_info->sb); | 4537 | inode = new_inode(root->fs_info->sb); |
4530 | if (!inode) | 4538 | if (!inode) { |
4539 | btrfs_free_path(path); | ||
4531 | return ERR_PTR(-ENOMEM); | 4540 | return ERR_PTR(-ENOMEM); |
4541 | } | ||
4532 | 4542 | ||
4533 | if (dir) { | 4543 | if (dir) { |
4534 | trace_btrfs_inode_request(dir); | 4544 | trace_btrfs_inode_request(dir); |
4535 | 4545 | ||
4536 | ret = btrfs_set_inode_index(dir, index); | 4546 | ret = btrfs_set_inode_index(dir, index); |
4537 | if (ret) { | 4547 | if (ret) { |
4548 | btrfs_free_path(path); | ||
4538 | iput(inode); | 4549 | iput(inode); |
4539 | return ERR_PTR(ret); | 4550 | return ERR_PTR(ret); |
4540 | } | 4551 | } |
@@ -4721,9 +4732,10 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
4721 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, | 4732 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
4722 | dentry->d_name.len, dir->i_ino, objectid, | 4733 | dentry->d_name.len, dir->i_ino, objectid, |
4723 | BTRFS_I(dir)->block_group, mode, &index); | 4734 | BTRFS_I(dir)->block_group, mode, &index); |
4724 | err = PTR_ERR(inode); | 4735 | if (IS_ERR(inode)) { |
4725 | if (IS_ERR(inode)) | 4736 | err = PTR_ERR(inode); |
4726 | goto out_unlock; | 4737 | goto out_unlock; |
4738 | } | ||
4727 | 4739 | ||
4728 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); | 4740 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); |
4729 | if (err) { | 4741 | if (err) { |
@@ -4782,9 +4794,10 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
4782 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, | 4794 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
4783 | dentry->d_name.len, dir->i_ino, objectid, | 4795 | dentry->d_name.len, dir->i_ino, objectid, |
4784 | BTRFS_I(dir)->block_group, mode, &index); | 4796 | BTRFS_I(dir)->block_group, mode, &index); |
4785 | err = PTR_ERR(inode); | 4797 | if (IS_ERR(inode)) { |
4786 | if (IS_ERR(inode)) | 4798 | err = PTR_ERR(inode); |
4787 | goto out_unlock; | 4799 | goto out_unlock; |
4800 | } | ||
4788 | 4801 | ||
4789 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); | 4802 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); |
4790 | if (err) { | 4803 | if (err) { |
@@ -4834,9 +4847,6 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
4834 | if (inode->i_nlink == ~0U) | 4847 | if (inode->i_nlink == ~0U) |
4835 | return -EMLINK; | 4848 | return -EMLINK; |
4836 | 4849 | ||
4837 | btrfs_inc_nlink(inode); | ||
4838 | inode->i_ctime = CURRENT_TIME; | ||
4839 | |||
4840 | err = btrfs_set_inode_index(dir, &index); | 4850 | err = btrfs_set_inode_index(dir, &index); |
4841 | if (err) | 4851 | if (err) |
4842 | goto fail; | 4852 | goto fail; |
@@ -4852,6 +4862,9 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
4852 | goto fail; | 4862 | goto fail; |
4853 | } | 4863 | } |
4854 | 4864 | ||
4865 | btrfs_inc_nlink(inode); | ||
4866 | inode->i_ctime = CURRENT_TIME; | ||
4867 | |||
4855 | btrfs_set_trans_block_group(trans, dir); | 4868 | btrfs_set_trans_block_group(trans, dir); |
4856 | ihold(inode); | 4869 | ihold(inode); |
4857 | 4870 | ||
@@ -4989,6 +5002,8 @@ static noinline int uncompress_inline(struct btrfs_path *path, | |||
4989 | inline_size = btrfs_file_extent_inline_item_len(leaf, | 5002 | inline_size = btrfs_file_extent_inline_item_len(leaf, |
4990 | btrfs_item_nr(leaf, path->slots[0])); | 5003 | btrfs_item_nr(leaf, path->slots[0])); |
4991 | tmp = kmalloc(inline_size, GFP_NOFS); | 5004 | tmp = kmalloc(inline_size, GFP_NOFS); |
5005 | if (!tmp) | ||
5006 | return -ENOMEM; | ||
4992 | ptr = btrfs_file_extent_inline_start(item); | 5007 | ptr = btrfs_file_extent_inline_start(item); |
4993 | 5008 | ||
4994 | read_extent_buffer(leaf, tmp, ptr, inline_size); | 5009 | read_extent_buffer(leaf, tmp, ptr, inline_size); |
@@ -5221,7 +5236,7 @@ again: | |||
5221 | btrfs_mark_buffer_dirty(leaf); | 5236 | btrfs_mark_buffer_dirty(leaf); |
5222 | } | 5237 | } |
5223 | set_extent_uptodate(io_tree, em->start, | 5238 | set_extent_uptodate(io_tree, em->start, |
5224 | extent_map_end(em) - 1, GFP_NOFS); | 5239 | extent_map_end(em) - 1, NULL, GFP_NOFS); |
5225 | goto insert; | 5240 | goto insert; |
5226 | } else { | 5241 | } else { |
5227 | printk(KERN_ERR "btrfs unknown found_type %d\n", found_type); | 5242 | printk(KERN_ERR "btrfs unknown found_type %d\n", found_type); |
@@ -5428,17 +5443,30 @@ out: | |||
5428 | } | 5443 | } |
5429 | 5444 | ||
5430 | static struct extent_map *btrfs_new_extent_direct(struct inode *inode, | 5445 | static struct extent_map *btrfs_new_extent_direct(struct inode *inode, |
5446 | struct extent_map *em, | ||
5431 | u64 start, u64 len) | 5447 | u64 start, u64 len) |
5432 | { | 5448 | { |
5433 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5449 | struct btrfs_root *root = BTRFS_I(inode)->root; |
5434 | struct btrfs_trans_handle *trans; | 5450 | struct btrfs_trans_handle *trans; |
5435 | struct extent_map *em; | ||
5436 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 5451 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
5437 | struct btrfs_key ins; | 5452 | struct btrfs_key ins; |
5438 | u64 alloc_hint; | 5453 | u64 alloc_hint; |
5439 | int ret; | 5454 | int ret; |
5455 | bool insert = false; | ||
5440 | 5456 | ||
5441 | btrfs_drop_extent_cache(inode, start, start + len - 1, 0); | 5457 | /* |
5458 | * Ok if the extent map we looked up is a hole and is for the exact | ||
5459 | * range we want, there is no reason to allocate a new one, however if | ||
5460 | * it is not right then we need to free this one and drop the cache for | ||
5461 | * our range. | ||
5462 | */ | ||
5463 | if (em->block_start != EXTENT_MAP_HOLE || em->start != start || | ||
5464 | em->len != len) { | ||
5465 | free_extent_map(em); | ||
5466 | em = NULL; | ||
5467 | insert = true; | ||
5468 | btrfs_drop_extent_cache(inode, start, start + len - 1, 0); | ||
5469 | } | ||
5442 | 5470 | ||
5443 | trans = btrfs_join_transaction(root, 0); | 5471 | trans = btrfs_join_transaction(root, 0); |
5444 | if (IS_ERR(trans)) | 5472 | if (IS_ERR(trans)) |
@@ -5454,10 +5482,12 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode, | |||
5454 | goto out; | 5482 | goto out; |
5455 | } | 5483 | } |
5456 | 5484 | ||
5457 | em = alloc_extent_map(GFP_NOFS); | ||
5458 | if (!em) { | 5485 | if (!em) { |
5459 | em = ERR_PTR(-ENOMEM); | 5486 | em = alloc_extent_map(GFP_NOFS); |
5460 | goto out; | 5487 | if (!em) { |
5488 | em = ERR_PTR(-ENOMEM); | ||
5489 | goto out; | ||
5490 | } | ||
5461 | } | 5491 | } |
5462 | 5492 | ||
5463 | em->start = start; | 5493 | em->start = start; |
@@ -5467,9 +5497,15 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode, | |||
5467 | em->block_start = ins.objectid; | 5497 | em->block_start = ins.objectid; |
5468 | em->block_len = ins.offset; | 5498 | em->block_len = ins.offset; |
5469 | em->bdev = root->fs_info->fs_devices->latest_bdev; | 5499 | em->bdev = root->fs_info->fs_devices->latest_bdev; |
5500 | |||
5501 | /* | ||
5502 | * We need to do this because if we're using the original em we searched | ||
5503 | * for, we could have EXTENT_FLAG_VACANCY set, and we don't want that. | ||
5504 | */ | ||
5505 | em->flags = 0; | ||
5470 | set_bit(EXTENT_FLAG_PINNED, &em->flags); | 5506 | set_bit(EXTENT_FLAG_PINNED, &em->flags); |
5471 | 5507 | ||
5472 | while (1) { | 5508 | while (insert) { |
5473 | write_lock(&em_tree->lock); | 5509 | write_lock(&em_tree->lock); |
5474 | ret = add_extent_mapping(em_tree, em); | 5510 | ret = add_extent_mapping(em_tree, em); |
5475 | write_unlock(&em_tree->lock); | 5511 | write_unlock(&em_tree->lock); |
@@ -5687,8 +5723,7 @@ must_cow: | |||
5687 | * it above | 5723 | * it above |
5688 | */ | 5724 | */ |
5689 | len = bh_result->b_size; | 5725 | len = bh_result->b_size; |
5690 | free_extent_map(em); | 5726 | em = btrfs_new_extent_direct(inode, em, start, len); |
5691 | em = btrfs_new_extent_direct(inode, start, len); | ||
5692 | if (IS_ERR(em)) | 5727 | if (IS_ERR(em)) |
5693 | return PTR_ERR(em); | 5728 | return PTR_ERR(em); |
5694 | len = min(len, em->len - (start - em->start)); | 5729 | len = min(len, em->len - (start - em->start)); |
@@ -5851,8 +5886,10 @@ again: | |||
5851 | } | 5886 | } |
5852 | 5887 | ||
5853 | add_pending_csums(trans, inode, ordered->file_offset, &ordered->list); | 5888 | add_pending_csums(trans, inode, ordered->file_offset, &ordered->list); |
5854 | btrfs_ordered_update_i_size(inode, 0, ordered); | 5889 | ret = btrfs_ordered_update_i_size(inode, 0, ordered); |
5855 | btrfs_update_inode(trans, root, inode); | 5890 | if (!ret) |
5891 | btrfs_update_inode(trans, root, inode); | ||
5892 | ret = 0; | ||
5856 | out_unlock: | 5893 | out_unlock: |
5857 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, ordered->file_offset, | 5894 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, ordered->file_offset, |
5858 | ordered->file_offset + ordered->len - 1, | 5895 | ordered->file_offset + ordered->len - 1, |
@@ -5938,7 +5975,7 @@ static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev, | |||
5938 | 5975 | ||
5939 | static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | 5976 | static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, |
5940 | int rw, u64 file_offset, int skip_sum, | 5977 | int rw, u64 file_offset, int skip_sum, |
5941 | u32 *csums) | 5978 | u32 *csums, int async_submit) |
5942 | { | 5979 | { |
5943 | int write = rw & REQ_WRITE; | 5980 | int write = rw & REQ_WRITE; |
5944 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5981 | struct btrfs_root *root = BTRFS_I(inode)->root; |
@@ -5949,13 +5986,24 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | |||
5949 | if (ret) | 5986 | if (ret) |
5950 | goto err; | 5987 | goto err; |
5951 | 5988 | ||
5952 | if (write && !skip_sum) { | 5989 | if (skip_sum) |
5990 | goto map; | ||
5991 | |||
5992 | if (write && async_submit) { | ||
5953 | ret = btrfs_wq_submit_bio(root->fs_info, | 5993 | ret = btrfs_wq_submit_bio(root->fs_info, |
5954 | inode, rw, bio, 0, 0, | 5994 | inode, rw, bio, 0, 0, |
5955 | file_offset, | 5995 | file_offset, |
5956 | __btrfs_submit_bio_start_direct_io, | 5996 | __btrfs_submit_bio_start_direct_io, |
5957 | __btrfs_submit_bio_done); | 5997 | __btrfs_submit_bio_done); |
5958 | goto err; | 5998 | goto err; |
5999 | } else if (write) { | ||
6000 | /* | ||
6001 | * If we aren't doing async submit, calculate the csum of the | ||
6002 | * bio now. | ||
6003 | */ | ||
6004 | ret = btrfs_csum_one_bio(root, inode, bio, file_offset, 1); | ||
6005 | if (ret) | ||
6006 | goto err; | ||
5959 | } else if (!skip_sum) { | 6007 | } else if (!skip_sum) { |
5960 | ret = btrfs_lookup_bio_sums_dio(root, inode, bio, | 6008 | ret = btrfs_lookup_bio_sums_dio(root, inode, bio, |
5961 | file_offset, csums); | 6009 | file_offset, csums); |
@@ -5963,7 +6011,8 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | |||
5963 | goto err; | 6011 | goto err; |
5964 | } | 6012 | } |
5965 | 6013 | ||
5966 | ret = btrfs_map_bio(root, rw, bio, 0, 1); | 6014 | map: |
6015 | ret = btrfs_map_bio(root, rw, bio, 0, async_submit); | ||
5967 | err: | 6016 | err: |
5968 | bio_put(bio); | 6017 | bio_put(bio); |
5969 | return ret; | 6018 | return ret; |
@@ -5985,23 +6034,30 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
5985 | int nr_pages = 0; | 6034 | int nr_pages = 0; |
5986 | u32 *csums = dip->csums; | 6035 | u32 *csums = dip->csums; |
5987 | int ret = 0; | 6036 | int ret = 0; |
6037 | int async_submit = 0; | ||
5988 | int write = rw & REQ_WRITE; | 6038 | int write = rw & REQ_WRITE; |
5989 | 6039 | ||
5990 | bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); | ||
5991 | if (!bio) | ||
5992 | return -ENOMEM; | ||
5993 | bio->bi_private = dip; | ||
5994 | bio->bi_end_io = btrfs_end_dio_bio; | ||
5995 | atomic_inc(&dip->pending_bios); | ||
5996 | |||
5997 | map_length = orig_bio->bi_size; | 6040 | map_length = orig_bio->bi_size; |
5998 | ret = btrfs_map_block(map_tree, READ, start_sector << 9, | 6041 | ret = btrfs_map_block(map_tree, READ, start_sector << 9, |
5999 | &map_length, NULL, 0); | 6042 | &map_length, NULL, 0); |
6000 | if (ret) { | 6043 | if (ret) { |
6001 | bio_put(bio); | 6044 | bio_put(orig_bio); |
6002 | return -EIO; | 6045 | return -EIO; |
6003 | } | 6046 | } |
6004 | 6047 | ||
6048 | if (map_length >= orig_bio->bi_size) { | ||
6049 | bio = orig_bio; | ||
6050 | goto submit; | ||
6051 | } | ||
6052 | |||
6053 | async_submit = 1; | ||
6054 | bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); | ||
6055 | if (!bio) | ||
6056 | return -ENOMEM; | ||
6057 | bio->bi_private = dip; | ||
6058 | bio->bi_end_io = btrfs_end_dio_bio; | ||
6059 | atomic_inc(&dip->pending_bios); | ||
6060 | |||
6005 | while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) { | 6061 | while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) { |
6006 | if (unlikely(map_length < submit_len + bvec->bv_len || | 6062 | if (unlikely(map_length < submit_len + bvec->bv_len || |
6007 | bio_add_page(bio, bvec->bv_page, bvec->bv_len, | 6063 | bio_add_page(bio, bvec->bv_page, bvec->bv_len, |
@@ -6015,7 +6071,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
6015 | atomic_inc(&dip->pending_bios); | 6071 | atomic_inc(&dip->pending_bios); |
6016 | ret = __btrfs_submit_dio_bio(bio, inode, rw, | 6072 | ret = __btrfs_submit_dio_bio(bio, inode, rw, |
6017 | file_offset, skip_sum, | 6073 | file_offset, skip_sum, |
6018 | csums); | 6074 | csums, async_submit); |
6019 | if (ret) { | 6075 | if (ret) { |
6020 | bio_put(bio); | 6076 | bio_put(bio); |
6021 | atomic_dec(&dip->pending_bios); | 6077 | atomic_dec(&dip->pending_bios); |
@@ -6052,8 +6108,9 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | |||
6052 | } | 6108 | } |
6053 | } | 6109 | } |
6054 | 6110 | ||
6111 | submit: | ||
6055 | ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum, | 6112 | ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum, |
6056 | csums); | 6113 | csums, async_submit); |
6057 | if (!ret) | 6114 | if (!ret) |
6058 | return 0; | 6115 | return 0; |
6059 | 6116 | ||
@@ -6148,6 +6205,7 @@ static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *io | |||
6148 | unsigned long nr_segs) | 6205 | unsigned long nr_segs) |
6149 | { | 6206 | { |
6150 | int seg; | 6207 | int seg; |
6208 | int i; | ||
6151 | size_t size; | 6209 | size_t size; |
6152 | unsigned long addr; | 6210 | unsigned long addr; |
6153 | unsigned blocksize_mask = root->sectorsize - 1; | 6211 | unsigned blocksize_mask = root->sectorsize - 1; |
@@ -6162,8 +6220,22 @@ static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *io | |||
6162 | addr = (unsigned long)iov[seg].iov_base; | 6220 | addr = (unsigned long)iov[seg].iov_base; |
6163 | size = iov[seg].iov_len; | 6221 | size = iov[seg].iov_len; |
6164 | end += size; | 6222 | end += size; |
6165 | if ((addr & blocksize_mask) || (size & blocksize_mask)) | 6223 | if ((addr & blocksize_mask) || (size & blocksize_mask)) |
6166 | goto out; | 6224 | goto out; |
6225 | |||
6226 | /* If this is a write we don't need to check anymore */ | ||
6227 | if (rw & WRITE) | ||
6228 | continue; | ||
6229 | |||
6230 | /* | ||
6231 | * Check to make sure we don't have duplicate iov_base's in this | ||
6232 | * iovec, if so return EINVAL, otherwise we'll get csum errors | ||
6233 | * when reading back. | ||
6234 | */ | ||
6235 | for (i = seg + 1; i < nr_segs; i++) { | ||
6236 | if (iov[seg].iov_base == iov[i].iov_base) | ||
6237 | goto out; | ||
6238 | } | ||
6167 | } | 6239 | } |
6168 | retval = 0; | 6240 | retval = 0; |
6169 | out: | 6241 | out: |
@@ -7206,9 +7278,10 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
7206 | dentry->d_name.len, dir->i_ino, objectid, | 7278 | dentry->d_name.len, dir->i_ino, objectid, |
7207 | BTRFS_I(dir)->block_group, S_IFLNK|S_IRWXUGO, | 7279 | BTRFS_I(dir)->block_group, S_IFLNK|S_IRWXUGO, |
7208 | &index); | 7280 | &index); |
7209 | err = PTR_ERR(inode); | 7281 | if (IS_ERR(inode)) { |
7210 | if (IS_ERR(inode)) | 7282 | err = PTR_ERR(inode); |
7211 | goto out_unlock; | 7283 | goto out_unlock; |
7284 | } | ||
7212 | 7285 | ||
7213 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); | 7286 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); |
7214 | if (err) { | 7287 | if (err) { |