aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-01-31 15:30:16 -0500
committerJosef Bacik <josef@redhat.com>2011-03-17 14:21:22 -0400
commita41ad394a03b802497958d7c98a9dcf607266645 (patch)
treef18d97b7feb5c3dcf0d3c1a670d4eaf6b94e8b79 /fs/btrfs/inode.c
parentdc89e9824464e91fa0b06267864ceabe3186fd8b (diff)
Btrfs: convert to the new truncate sequence
->truncate() is going away, instead all of the work needs to be done in ->setattr(). So this converts us over to do this. It's fairly straightforward, just get rid of our .truncate inode operation and call btrfs_truncate() directly from btrfs_setsize. This works out better for us since truncate can technically return ENOSPC, and before we had no way of letting anybody know. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c80
1 files changed, 36 insertions, 44 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 2d2e079713d7..3662ffec17d9 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -84,7 +84,8 @@ static unsigned char btrfs_type_by_mode[S_IFMT >> S_SHIFT] = {
84 [S_IFLNK >> S_SHIFT] = BTRFS_FT_SYMLINK, 84 [S_IFLNK >> S_SHIFT] = BTRFS_FT_SYMLINK,
85}; 85};
86 86
87static void btrfs_truncate(struct inode *inode); 87static int btrfs_setsize(struct inode *inode, loff_t newsize);
88static int btrfs_truncate(struct inode *inode);
88static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end); 89static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end);
89static noinline int cow_file_range(struct inode *inode, 90static noinline int cow_file_range(struct inode *inode,
90 struct page *locked_page, 91 struct page *locked_page,
@@ -2371,6 +2372,11 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
2371 2372
2372 /* if we have links, this was a truncate, lets do that */ 2373 /* if we have links, this was a truncate, lets do that */
2373 if (inode->i_nlink) { 2374 if (inode->i_nlink) {
2375 if (!S_ISREG(inode->i_mode)) {
2376 WARN_ON(1);
2377 iput(inode);
2378 continue;
2379 }
2374 nr_truncate++; 2380 nr_truncate++;
2375 btrfs_truncate(inode); 2381 btrfs_truncate(inode);
2376 } else { 2382 } else {
@@ -3538,7 +3544,7 @@ out:
3538 return ret; 3544 return ret;
3539} 3545}
3540 3546
3541int btrfs_cont_expand(struct inode *inode, loff_t size) 3547int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
3542{ 3548{
3543 struct btrfs_trans_handle *trans; 3549 struct btrfs_trans_handle *trans;
3544 struct btrfs_root *root = BTRFS_I(inode)->root; 3550 struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -3546,7 +3552,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
3546 struct extent_map *em = NULL; 3552 struct extent_map *em = NULL;
3547 struct extent_state *cached_state = NULL; 3553 struct extent_state *cached_state = NULL;
3548 u64 mask = root->sectorsize - 1; 3554 u64 mask = root->sectorsize - 1;
3549 u64 hole_start = (inode->i_size + mask) & ~mask; 3555 u64 hole_start = (oldsize + mask) & ~mask;
3550 u64 block_end = (size + mask) & ~mask; 3556 u64 block_end = (size + mask) & ~mask;
3551 u64 last_byte; 3557 u64 last_byte;
3552 u64 cur_offset; 3558 u64 cur_offset;
@@ -3617,27 +3623,17 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
3617 return err; 3623 return err;
3618} 3624}
3619 3625
3620static int btrfs_setattr_size(struct inode *inode, struct iattr *attr) 3626static int btrfs_setsize(struct inode *inode, loff_t newsize)
3621{ 3627{
3622 struct btrfs_root *root = BTRFS_I(inode)->root; 3628 struct btrfs_root *root = BTRFS_I(inode)->root;
3623 struct btrfs_trans_handle *trans; 3629 struct btrfs_trans_handle *trans;
3630 loff_t oldsize = i_size_read(inode);
3624 unsigned long nr; 3631 unsigned long nr;
3625 int ret; 3632 int ret;
3626 3633
3627 if (attr->ia_size == inode->i_size) 3634 if (newsize == oldsize)
3628 return 0; 3635 return 0;
3629 3636
3630 if (attr->ia_size > inode->i_size) {
3631 unsigned long limit;
3632 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
3633 if (attr->ia_size > inode->i_sb->s_maxbytes)
3634 return -EFBIG;
3635 if (limit != RLIM_INFINITY && attr->ia_size > limit) {
3636 send_sig(SIGXFSZ, current, 0);
3637 return -EFBIG;
3638 }
3639 }
3640
3641 trans = btrfs_start_transaction(root, 5); 3637 trans = btrfs_start_transaction(root, 5);
3642 if (IS_ERR(trans)) 3638 if (IS_ERR(trans))
3643 return PTR_ERR(trans); 3639 return PTR_ERR(trans);
@@ -3651,16 +3647,16 @@ static int btrfs_setattr_size(struct inode *inode, struct iattr *attr)
3651 btrfs_end_transaction(trans, root); 3647 btrfs_end_transaction(trans, root);
3652 btrfs_btree_balance_dirty(root, nr); 3648 btrfs_btree_balance_dirty(root, nr);
3653 3649
3654 if (attr->ia_size > inode->i_size) { 3650 if (newsize > oldsize) {
3655 ret = btrfs_cont_expand(inode, attr->ia_size); 3651 i_size_write(inode, newsize);
3652 btrfs_ordered_update_i_size(inode, i_size_read(inode), NULL);
3653 truncate_pagecache(inode, oldsize, newsize);
3654 ret = btrfs_cont_expand(inode, oldsize, newsize);
3656 if (ret) { 3655 if (ret) {
3657 btrfs_truncate(inode); 3656 btrfs_setsize(inode, oldsize);
3658 return ret; 3657 return ret;
3659 } 3658 }
3660 3659
3661 i_size_write(inode, attr->ia_size);
3662 btrfs_ordered_update_i_size(inode, inode->i_size, NULL);
3663
3664 trans = btrfs_start_transaction(root, 0); 3660 trans = btrfs_start_transaction(root, 0);
3665 BUG_ON(IS_ERR(trans)); 3661 BUG_ON(IS_ERR(trans));
3666 btrfs_set_trans_block_group(trans, inode); 3662 btrfs_set_trans_block_group(trans, inode);
@@ -3676,22 +3672,22 @@ static int btrfs_setattr_size(struct inode *inode, struct iattr *attr)
3676 nr = trans->blocks_used; 3672 nr = trans->blocks_used;
3677 btrfs_end_transaction(trans, root); 3673 btrfs_end_transaction(trans, root);
3678 btrfs_btree_balance_dirty(root, nr); 3674 btrfs_btree_balance_dirty(root, nr);
3679 return 0; 3675 } else {
3680 }
3681 3676
3682 /* 3677 /*
3683 * We're truncating a file that used to have good data down to 3678 * We're truncating a file that used to have good data down to
3684 * zero. Make sure it gets into the ordered flush list so that 3679 * zero. Make sure it gets into the ordered flush list so that
3685 * any new writes get down to disk quickly. 3680 * any new writes get down to disk quickly.
3686 */ 3681 */
3687 if (attr->ia_size == 0) 3682 if (newsize == 0)
3688 BTRFS_I(inode)->ordered_data_close = 1; 3683 BTRFS_I(inode)->ordered_data_close = 1;
3689 3684
3690 /* we don't support swapfiles, so vmtruncate shouldn't fail */ 3685 /* we don't support swapfiles, so vmtruncate shouldn't fail */
3691 ret = vmtruncate(inode, attr->ia_size); 3686 truncate_setsize(inode, newsize);
3692 BUG_ON(ret); 3687 ret = btrfs_truncate(inode);
3688 }
3693 3689
3694 return 0; 3690 return ret;
3695} 3691}
3696 3692
3697static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) 3693static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
@@ -3708,7 +3704,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
3708 return err; 3704 return err;
3709 3705
3710 if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { 3706 if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) {
3711 err = btrfs_setattr_size(inode, attr); 3707 err = btrfs_setsize(inode, attr->ia_size);
3712 if (err) 3708 if (err)
3713 return err; 3709 return err;
3714 } 3710 }
@@ -6478,7 +6474,7 @@ out:
6478 return ret; 6474 return ret;
6479} 6475}
6480 6476
6481static void btrfs_truncate(struct inode *inode) 6477static int btrfs_truncate(struct inode *inode)
6482{ 6478{
6483 struct btrfs_root *root = BTRFS_I(inode)->root; 6479 struct btrfs_root *root = BTRFS_I(inode)->root;
6484 int ret; 6480 int ret;
@@ -6486,14 +6482,9 @@ static void btrfs_truncate(struct inode *inode)
6486 unsigned long nr; 6482 unsigned long nr;
6487 u64 mask = root->sectorsize - 1; 6483 u64 mask = root->sectorsize - 1;
6488 6484
6489 if (!S_ISREG(inode->i_mode)) {
6490 WARN_ON(1);
6491 return;
6492 }
6493
6494 ret = btrfs_truncate_page(inode->i_mapping, inode->i_size); 6485 ret = btrfs_truncate_page(inode->i_mapping, inode->i_size);
6495 if (ret) 6486 if (ret)
6496 return; 6487 return ret;
6497 6488
6498 btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1); 6489 btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1);
6499 btrfs_ordered_update_i_size(inode, inode->i_size, NULL); 6490 btrfs_ordered_update_i_size(inode, inode->i_size, NULL);
@@ -6568,6 +6559,8 @@ static void btrfs_truncate(struct inode *inode)
6568 ret = btrfs_end_transaction_throttle(trans, root); 6559 ret = btrfs_end_transaction_throttle(trans, root);
6569 BUG_ON(ret); 6560 BUG_ON(ret);
6570 btrfs_btree_balance_dirty(root, nr); 6561 btrfs_btree_balance_dirty(root, nr);
6562
6563 return ret;
6571} 6564}
6572 6565
6573/* 6566/*
@@ -7367,7 +7360,6 @@ static const struct address_space_operations btrfs_symlink_aops = {
7367}; 7360};
7368 7361
7369static const struct inode_operations btrfs_file_inode_operations = { 7362static const struct inode_operations btrfs_file_inode_operations = {
7370 .truncate = btrfs_truncate,
7371 .getattr = btrfs_getattr, 7363 .getattr = btrfs_getattr,
7372 .setattr = btrfs_setattr, 7364 .setattr = btrfs_setattr,
7373 .setxattr = btrfs_setxattr, 7365 .setxattr = btrfs_setxattr,