aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/inode.c64
1 files changed, 45 insertions, 19 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3662ffec17d9..d83025063ee7 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3597,13 +3597,15 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
3597 err = btrfs_drop_extents(trans, inode, cur_offset, 3597 err = btrfs_drop_extents(trans, inode, cur_offset,
3598 cur_offset + hole_size, 3598 cur_offset + hole_size,
3599 &hint_byte, 1); 3599 &hint_byte, 1);
3600 BUG_ON(err); 3600 if (err)
3601 break;
3601 3602
3602 err = btrfs_insert_file_extent(trans, root, 3603 err = btrfs_insert_file_extent(trans, root,
3603 inode->i_ino, cur_offset, 0, 3604 inode->i_ino, cur_offset, 0,
3604 0, hole_size, 0, hole_size, 3605 0, hole_size, 0, hole_size,
3605 0, 0, 0); 3606 0, 0, 0);
3606 BUG_ON(err); 3607 if (err)
3608 break;
3607 3609
3608 btrfs_drop_extent_cache(inode, hole_start, 3610 btrfs_drop_extent_cache(inode, hole_start,
3609 last_byte - 1, 0); 3611 last_byte - 1, 0);
@@ -3641,7 +3643,10 @@ static int btrfs_setsize(struct inode *inode, loff_t newsize)
3641 btrfs_set_trans_block_group(trans, inode); 3643 btrfs_set_trans_block_group(trans, inode);
3642 3644
3643 ret = btrfs_orphan_add(trans, inode); 3645 ret = btrfs_orphan_add(trans, inode);
3644 BUG_ON(ret); 3646 if (ret) {
3647 btrfs_end_transaction(trans, root);
3648 return ret;
3649 }
3645 3650
3646 nr = trans->blocks_used; 3651 nr = trans->blocks_used;
3647 btrfs_end_transaction(trans, root); 3652 btrfs_end_transaction(trans, root);
@@ -3658,17 +3663,24 @@ static int btrfs_setsize(struct inode *inode, loff_t newsize)
3658 } 3663 }
3659 3664
3660 trans = btrfs_start_transaction(root, 0); 3665 trans = btrfs_start_transaction(root, 0);
3661 BUG_ON(IS_ERR(trans)); 3666 if (IS_ERR(trans))
3667 return PTR_ERR(trans);
3668
3662 btrfs_set_trans_block_group(trans, inode); 3669 btrfs_set_trans_block_group(trans, inode);
3663 trans->block_rsv = root->orphan_block_rsv; 3670 trans->block_rsv = root->orphan_block_rsv;
3664 BUG_ON(!trans->block_rsv); 3671 BUG_ON(!trans->block_rsv);
3665 3672
3673 /*
3674 * If this fails just leave the orphan item so that it can get
3675 * cleaned up next time we mount.
3676 */
3666 ret = btrfs_update_inode(trans, root, inode); 3677 ret = btrfs_update_inode(trans, root, inode);
3667 BUG_ON(ret); 3678 if (ret) {
3668 if (inode->i_nlink > 0) { 3679 btrfs_end_transaction(trans, root);
3669 ret = btrfs_orphan_del(trans, inode); 3680 return ret;
3670 BUG_ON(ret);
3671 } 3681 }
3682 if (inode->i_nlink > 0)
3683 ret = btrfs_orphan_del(trans, inode);
3672 nr = trans->blocks_used; 3684 nr = trans->blocks_used;
3673 btrfs_end_transaction(trans, root); 3685 btrfs_end_transaction(trans, root);
3674 btrfs_btree_balance_dirty(root, nr); 3686 btrfs_btree_balance_dirty(root, nr);
@@ -6478,6 +6490,7 @@ static int btrfs_truncate(struct inode *inode)
6478{ 6490{
6479 struct btrfs_root *root = BTRFS_I(inode)->root; 6491 struct btrfs_root *root = BTRFS_I(inode)->root;
6480 int ret; 6492 int ret;
6493 int err = 0;
6481 struct btrfs_trans_handle *trans; 6494 struct btrfs_trans_handle *trans;
6482 unsigned long nr; 6495 unsigned long nr;
6483 u64 mask = root->sectorsize - 1; 6496 u64 mask = root->sectorsize - 1;
@@ -6490,7 +6503,8 @@ static int btrfs_truncate(struct inode *inode)
6490 btrfs_ordered_update_i_size(inode, inode->i_size, NULL); 6503 btrfs_ordered_update_i_size(inode, inode->i_size, NULL);
6491 6504
6492 trans = btrfs_start_transaction(root, 0); 6505 trans = btrfs_start_transaction(root, 0);
6493 BUG_ON(IS_ERR(trans)); 6506 if (IS_ERR(trans))
6507 return PTR_ERR(trans);
6494 btrfs_set_trans_block_group(trans, inode); 6508 btrfs_set_trans_block_group(trans, inode);
6495 trans->block_rsv = root->orphan_block_rsv; 6509 trans->block_rsv = root->orphan_block_rsv;
6496 6510
@@ -6517,29 +6531,38 @@ static int btrfs_truncate(struct inode *inode)
6517 while (1) { 6531 while (1) {
6518 if (!trans) { 6532 if (!trans) {
6519 trans = btrfs_start_transaction(root, 0); 6533 trans = btrfs_start_transaction(root, 0);
6520 BUG_ON(IS_ERR(trans)); 6534 if (IS_ERR(trans))
6535 return PTR_ERR(trans);
6521 btrfs_set_trans_block_group(trans, inode); 6536 btrfs_set_trans_block_group(trans, inode);
6522 trans->block_rsv = root->orphan_block_rsv; 6537 trans->block_rsv = root->orphan_block_rsv;
6523 } 6538 }
6524 6539
6525 ret = btrfs_block_rsv_check(trans, root, 6540 ret = btrfs_block_rsv_check(trans, root,
6526 root->orphan_block_rsv, 0, 5); 6541 root->orphan_block_rsv, 0, 5);
6527 if (ret) { 6542 if (ret == -EAGAIN) {
6528 BUG_ON(ret != -EAGAIN);
6529 ret = btrfs_commit_transaction(trans, root); 6543 ret = btrfs_commit_transaction(trans, root);
6530 BUG_ON(ret); 6544 if (ret)
6545 return ret;
6531 trans = NULL; 6546 trans = NULL;
6532 continue; 6547 continue;
6548 } else if (ret) {
6549 err = ret;
6550 break;
6533 } 6551 }
6534 6552
6535 ret = btrfs_truncate_inode_items(trans, root, inode, 6553 ret = btrfs_truncate_inode_items(trans, root, inode,
6536 inode->i_size, 6554 inode->i_size,
6537 BTRFS_EXTENT_DATA_KEY); 6555 BTRFS_EXTENT_DATA_KEY);
6538 if (ret != -EAGAIN) 6556 if (ret != -EAGAIN) {
6557 err = ret;
6539 break; 6558 break;
6559 }
6540 6560
6541 ret = btrfs_update_inode(trans, root, inode); 6561 ret = btrfs_update_inode(trans, root, inode);
6542 BUG_ON(ret); 6562 if (ret) {
6563 err = ret;
6564 break;
6565 }
6543 6566
6544 nr = trans->blocks_used; 6567 nr = trans->blocks_used;
6545 btrfs_end_transaction(trans, root); 6568 btrfs_end_transaction(trans, root);
@@ -6549,18 +6572,21 @@ static int btrfs_truncate(struct inode *inode)
6549 6572
6550 if (ret == 0 && inode->i_nlink > 0) { 6573 if (ret == 0 && inode->i_nlink > 0) {
6551 ret = btrfs_orphan_del(trans, inode); 6574 ret = btrfs_orphan_del(trans, inode);
6552 BUG_ON(ret); 6575 if (ret)
6576 err = ret;
6553 } 6577 }
6554 6578
6555 ret = btrfs_update_inode(trans, root, inode); 6579 ret = btrfs_update_inode(trans, root, inode);
6556 BUG_ON(ret); 6580 if (ret && !err)
6581 err = ret;
6557 6582
6558 nr = trans->blocks_used; 6583 nr = trans->blocks_used;
6559 ret = btrfs_end_transaction_throttle(trans, root); 6584 ret = btrfs_end_transaction_throttle(trans, root);
6560 BUG_ON(ret); 6585 if (ret && !err)
6586 err = ret;
6561 btrfs_btree_balance_dirty(root, nr); 6587 btrfs_btree_balance_dirty(root, nr);
6562 6588
6563 return ret; 6589 return err;
6564} 6590}
6565 6591
6566/* 6592/*