diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2009-11-17 04:01:34 -0500 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2009-11-17 04:01:34 -0500 |
commit | bb9074ff58fe745e4f244f76209241909c82ec9c (patch) | |
tree | cf6be00ab88b1e315f6b74a896a370440f677599 /fs/btrfs/inode.c | |
parent | 4739a9748e1bd7459f22f7e94e7d85710ca83954 (diff) | |
parent | 156171c71a0dc4bce12b4408bb1591f8fe32dc1a (diff) |
Merge commit 'v2.6.32-rc7'
Resolve the conflict between v2.6.32-rc7 where dn_def_dev_handler
gets a small bug fix and the sysctl tree where I am removing all
sysctl strategy routines.
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 95 |
1 files changed, 80 insertions, 15 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index dae12dc7e159..b3ad168a0bfc 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -538,7 +538,7 @@ static noinline int submit_compressed_extents(struct inode *inode, | |||
538 | struct btrfs_root *root = BTRFS_I(inode)->root; | 538 | struct btrfs_root *root = BTRFS_I(inode)->root; |
539 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; | 539 | struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; |
540 | struct extent_io_tree *io_tree; | 540 | struct extent_io_tree *io_tree; |
541 | int ret; | 541 | int ret = 0; |
542 | 542 | ||
543 | if (list_empty(&async_cow->extents)) | 543 | if (list_empty(&async_cow->extents)) |
544 | return 0; | 544 | return 0; |
@@ -552,6 +552,7 @@ static noinline int submit_compressed_extents(struct inode *inode, | |||
552 | 552 | ||
553 | io_tree = &BTRFS_I(inode)->io_tree; | 553 | io_tree = &BTRFS_I(inode)->io_tree; |
554 | 554 | ||
555 | retry: | ||
555 | /* did the compression code fall back to uncompressed IO? */ | 556 | /* did the compression code fall back to uncompressed IO? */ |
556 | if (!async_extent->pages) { | 557 | if (!async_extent->pages) { |
557 | int page_started = 0; | 558 | int page_started = 0; |
@@ -562,11 +563,11 @@ static noinline int submit_compressed_extents(struct inode *inode, | |||
562 | async_extent->ram_size - 1, GFP_NOFS); | 563 | async_extent->ram_size - 1, GFP_NOFS); |
563 | 564 | ||
564 | /* allocate blocks */ | 565 | /* allocate blocks */ |
565 | cow_file_range(inode, async_cow->locked_page, | 566 | ret = cow_file_range(inode, async_cow->locked_page, |
566 | async_extent->start, | 567 | async_extent->start, |
567 | async_extent->start + | 568 | async_extent->start + |
568 | async_extent->ram_size - 1, | 569 | async_extent->ram_size - 1, |
569 | &page_started, &nr_written, 0); | 570 | &page_started, &nr_written, 0); |
570 | 571 | ||
571 | /* | 572 | /* |
572 | * if page_started, cow_file_range inserted an | 573 | * if page_started, cow_file_range inserted an |
@@ -574,7 +575,7 @@ static noinline int submit_compressed_extents(struct inode *inode, | |||
574 | * and IO for us. Otherwise, we need to submit | 575 | * and IO for us. Otherwise, we need to submit |
575 | * all those pages down to the drive. | 576 | * all those pages down to the drive. |
576 | */ | 577 | */ |
577 | if (!page_started) | 578 | if (!page_started && !ret) |
578 | extent_write_locked_range(io_tree, | 579 | extent_write_locked_range(io_tree, |
579 | inode, async_extent->start, | 580 | inode, async_extent->start, |
580 | async_extent->start + | 581 | async_extent->start + |
@@ -602,7 +603,21 @@ static noinline int submit_compressed_extents(struct inode *inode, | |||
602 | async_extent->compressed_size, | 603 | async_extent->compressed_size, |
603 | 0, alloc_hint, | 604 | 0, alloc_hint, |
604 | (u64)-1, &ins, 1); | 605 | (u64)-1, &ins, 1); |
605 | BUG_ON(ret); | 606 | if (ret) { |
607 | int i; | ||
608 | for (i = 0; i < async_extent->nr_pages; i++) { | ||
609 | WARN_ON(async_extent->pages[i]->mapping); | ||
610 | page_cache_release(async_extent->pages[i]); | ||
611 | } | ||
612 | kfree(async_extent->pages); | ||
613 | async_extent->nr_pages = 0; | ||
614 | async_extent->pages = NULL; | ||
615 | unlock_extent(io_tree, async_extent->start, | ||
616 | async_extent->start + | ||
617 | async_extent->ram_size - 1, GFP_NOFS); | ||
618 | goto retry; | ||
619 | } | ||
620 | |||
606 | em = alloc_extent_map(GFP_NOFS); | 621 | em = alloc_extent_map(GFP_NOFS); |
607 | em->start = async_extent->start; | 622 | em->start = async_extent->start; |
608 | em->len = async_extent->ram_size; | 623 | em->len = async_extent->ram_size; |
@@ -743,8 +758,22 @@ static noinline int cow_file_range(struct inode *inode, | |||
743 | em = search_extent_mapping(&BTRFS_I(inode)->extent_tree, | 758 | em = search_extent_mapping(&BTRFS_I(inode)->extent_tree, |
744 | start, num_bytes); | 759 | start, num_bytes); |
745 | if (em) { | 760 | if (em) { |
746 | alloc_hint = em->block_start; | 761 | /* |
747 | free_extent_map(em); | 762 | * if block start isn't an actual block number then find the |
763 | * first block in this inode and use that as a hint. If that | ||
764 | * block is also bogus then just don't worry about it. | ||
765 | */ | ||
766 | if (em->block_start >= EXTENT_MAP_LAST_BYTE) { | ||
767 | free_extent_map(em); | ||
768 | em = search_extent_mapping(em_tree, 0, 0); | ||
769 | if (em && em->block_start < EXTENT_MAP_LAST_BYTE) | ||
770 | alloc_hint = em->block_start; | ||
771 | if (em) | ||
772 | free_extent_map(em); | ||
773 | } else { | ||
774 | alloc_hint = em->block_start; | ||
775 | free_extent_map(em); | ||
776 | } | ||
748 | } | 777 | } |
749 | read_unlock(&BTRFS_I(inode)->extent_tree.lock); | 778 | read_unlock(&BTRFS_I(inode)->extent_tree.lock); |
750 | btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0); | 779 | btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0); |
@@ -2474,7 +2503,19 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) | |||
2474 | 2503 | ||
2475 | root = BTRFS_I(dir)->root; | 2504 | root = BTRFS_I(dir)->root; |
2476 | 2505 | ||
2506 | /* | ||
2507 | * 5 items for unlink inode | ||
2508 | * 1 for orphan | ||
2509 | */ | ||
2510 | ret = btrfs_reserve_metadata_space(root, 6); | ||
2511 | if (ret) | ||
2512 | return ret; | ||
2513 | |||
2477 | trans = btrfs_start_transaction(root, 1); | 2514 | trans = btrfs_start_transaction(root, 1); |
2515 | if (IS_ERR(trans)) { | ||
2516 | btrfs_unreserve_metadata_space(root, 6); | ||
2517 | return PTR_ERR(trans); | ||
2518 | } | ||
2478 | 2519 | ||
2479 | btrfs_set_trans_block_group(trans, dir); | 2520 | btrfs_set_trans_block_group(trans, dir); |
2480 | 2521 | ||
@@ -2489,6 +2530,7 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) | |||
2489 | nr = trans->blocks_used; | 2530 | nr = trans->blocks_used; |
2490 | 2531 | ||
2491 | btrfs_end_transaction_throttle(trans, root); | 2532 | btrfs_end_transaction_throttle(trans, root); |
2533 | btrfs_unreserve_metadata_space(root, 6); | ||
2492 | btrfs_btree_balance_dirty(root, nr); | 2534 | btrfs_btree_balance_dirty(root, nr); |
2493 | return ret; | 2535 | return ret; |
2494 | } | 2536 | } |
@@ -2569,7 +2611,16 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
2569 | inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) | 2611 | inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) |
2570 | return -ENOTEMPTY; | 2612 | return -ENOTEMPTY; |
2571 | 2613 | ||
2614 | ret = btrfs_reserve_metadata_space(root, 5); | ||
2615 | if (ret) | ||
2616 | return ret; | ||
2617 | |||
2572 | trans = btrfs_start_transaction(root, 1); | 2618 | trans = btrfs_start_transaction(root, 1); |
2619 | if (IS_ERR(trans)) { | ||
2620 | btrfs_unreserve_metadata_space(root, 5); | ||
2621 | return PTR_ERR(trans); | ||
2622 | } | ||
2623 | |||
2573 | btrfs_set_trans_block_group(trans, dir); | 2624 | btrfs_set_trans_block_group(trans, dir); |
2574 | 2625 | ||
2575 | if (unlikely(inode->i_ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { | 2626 | if (unlikely(inode->i_ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { |
@@ -2592,6 +2643,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
2592 | out: | 2643 | out: |
2593 | nr = trans->blocks_used; | 2644 | nr = trans->blocks_used; |
2594 | ret = btrfs_end_transaction_throttle(trans, root); | 2645 | ret = btrfs_end_transaction_throttle(trans, root); |
2646 | btrfs_unreserve_metadata_space(root, 5); | ||
2595 | btrfs_btree_balance_dirty(root, nr); | 2647 | btrfs_btree_balance_dirty(root, nr); |
2596 | 2648 | ||
2597 | if (ret && !err) | 2649 | if (ret && !err) |
@@ -5128,6 +5180,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) | |||
5128 | ei->logged_trans = 0; | 5180 | ei->logged_trans = 0; |
5129 | ei->outstanding_extents = 0; | 5181 | ei->outstanding_extents = 0; |
5130 | ei->reserved_extents = 0; | 5182 | ei->reserved_extents = 0; |
5183 | ei->root = NULL; | ||
5131 | spin_lock_init(&ei->accounting_lock); | 5184 | spin_lock_init(&ei->accounting_lock); |
5132 | btrfs_ordered_inode_tree_init(&ei->ordered_tree); | 5185 | btrfs_ordered_inode_tree_init(&ei->ordered_tree); |
5133 | INIT_LIST_HEAD(&ei->i_orphan); | 5186 | INIT_LIST_HEAD(&ei->i_orphan); |
@@ -5144,6 +5197,14 @@ void btrfs_destroy_inode(struct inode *inode) | |||
5144 | WARN_ON(inode->i_data.nrpages); | 5197 | WARN_ON(inode->i_data.nrpages); |
5145 | 5198 | ||
5146 | /* | 5199 | /* |
5200 | * This can happen where we create an inode, but somebody else also | ||
5201 | * created the same inode and we need to destroy the one we already | ||
5202 | * created. | ||
5203 | */ | ||
5204 | if (!root) | ||
5205 | goto free; | ||
5206 | |||
5207 | /* | ||
5147 | * Make sure we're properly removed from the ordered operation | 5208 | * Make sure we're properly removed from the ordered operation |
5148 | * lists. | 5209 | * lists. |
5149 | */ | 5210 | */ |
@@ -5178,6 +5239,7 @@ void btrfs_destroy_inode(struct inode *inode) | |||
5178 | } | 5239 | } |
5179 | inode_tree_del(inode); | 5240 | inode_tree_del(inode); |
5180 | btrfs_drop_extent_cache(inode, 0, (u64)-1, 0); | 5241 | btrfs_drop_extent_cache(inode, 0, (u64)-1, 0); |
5242 | free: | ||
5181 | kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode)); | 5243 | kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode)); |
5182 | } | 5244 | } |
5183 | 5245 | ||
@@ -5283,11 +5345,14 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
5283 | return -ENOTEMPTY; | 5345 | return -ENOTEMPTY; |
5284 | 5346 | ||
5285 | /* | 5347 | /* |
5286 | * 2 items for dir items | 5348 | * We want to reserve the absolute worst case amount of items. So if |
5287 | * 1 item for orphan entry | 5349 | * both inodes are subvols and we need to unlink them then that would |
5288 | * 1 item for ref | 5350 | * require 4 item modifications, but if they are both normal inodes it |
5351 | * would require 5 item modifications, so we'll assume their normal | ||
5352 | * inodes. So 5 * 2 is 10, plus 1 for the new link, so 11 total items | ||
5353 | * should cover the worst case number of items we'll modify. | ||
5289 | */ | 5354 | */ |
5290 | ret = btrfs_reserve_metadata_space(root, 4); | 5355 | ret = btrfs_reserve_metadata_space(root, 11); |
5291 | if (ret) | 5356 | if (ret) |
5292 | return ret; | 5357 | return ret; |
5293 | 5358 | ||
@@ -5403,7 +5468,7 @@ out_fail: | |||
5403 | if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) | 5468 | if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) |
5404 | up_read(&root->fs_info->subvol_sem); | 5469 | up_read(&root->fs_info->subvol_sem); |
5405 | 5470 | ||
5406 | btrfs_unreserve_metadata_space(root, 4); | 5471 | btrfs_unreserve_metadata_space(root, 11); |
5407 | return ret; | 5472 | return ret; |
5408 | } | 5473 | } |
5409 | 5474 | ||