aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@fusionio.com>2013-01-21 20:26:55 -0500
committerChris Mason <chris.mason@fusionio.com>2013-01-21 20:26:55 -0500
commitdaf2c08911522d1739c55baf35f03531a29c87ef (patch)
tree380d89b955baebd90ca5ac1cf6527f963cf7dae7 /fs/btrfs/inode.c
parent2cf687039676c2b6e1ee96b0b89090aca94babcd (diff)
parent3972f2603d8570effaf633cea52b12c7c2773c11 (diff)
Merge branch 'for-chris' of git://git.kernel.org/pub/scm/linux/kernel/git/josef/btrfs-next into linus
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c82
1 files changed, 61 insertions, 21 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 67ed24ae86bb..9bc6c40b182d 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -88,7 +88,7 @@ static unsigned char btrfs_type_by_mode[S_IFMT >> S_SHIFT] = {
88 [S_IFLNK >> S_SHIFT] = BTRFS_FT_SYMLINK, 88 [S_IFLNK >> S_SHIFT] = BTRFS_FT_SYMLINK,
89}; 89};
90 90
91static int btrfs_setsize(struct inode *inode, loff_t newsize); 91static int btrfs_setsize(struct inode *inode, struct iattr *attr);
92static int btrfs_truncate(struct inode *inode); 92static int btrfs_truncate(struct inode *inode);
93static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent); 93static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent);
94static noinline int cow_file_range(struct inode *inode, 94static noinline int cow_file_range(struct inode *inode,
@@ -2478,6 +2478,18 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
2478 continue; 2478 continue;
2479 } 2479 }
2480 nr_truncate++; 2480 nr_truncate++;
2481
2482 /* 1 for the orphan item deletion. */
2483 trans = btrfs_start_transaction(root, 1);
2484 if (IS_ERR(trans)) {
2485 ret = PTR_ERR(trans);
2486 goto out;
2487 }
2488 ret = btrfs_orphan_add(trans, inode);
2489 btrfs_end_transaction(trans, root);
2490 if (ret)
2491 goto out;
2492
2481 ret = btrfs_truncate(inode); 2493 ret = btrfs_truncate(inode);
2482 } else { 2494 } else {
2483 nr_unlink++; 2495 nr_unlink++;
@@ -3665,6 +3677,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
3665 block_end - cur_offset, 0); 3677 block_end - cur_offset, 0);
3666 if (IS_ERR(em)) { 3678 if (IS_ERR(em)) {
3667 err = PTR_ERR(em); 3679 err = PTR_ERR(em);
3680 em = NULL;
3668 break; 3681 break;
3669 } 3682 }
3670 last_byte = min(extent_map_end(em), block_end); 3683 last_byte = min(extent_map_end(em), block_end);
@@ -3748,16 +3761,27 @@ next:
3748 return err; 3761 return err;
3749} 3762}
3750 3763
3751static int btrfs_setsize(struct inode *inode, loff_t newsize) 3764static int btrfs_setsize(struct inode *inode, struct iattr *attr)
3752{ 3765{
3753 struct btrfs_root *root = BTRFS_I(inode)->root; 3766 struct btrfs_root *root = BTRFS_I(inode)->root;
3754 struct btrfs_trans_handle *trans; 3767 struct btrfs_trans_handle *trans;
3755 loff_t oldsize = i_size_read(inode); 3768 loff_t oldsize = i_size_read(inode);
3769 loff_t newsize = attr->ia_size;
3770 int mask = attr->ia_valid;
3756 int ret; 3771 int ret;
3757 3772
3758 if (newsize == oldsize) 3773 if (newsize == oldsize)
3759 return 0; 3774 return 0;
3760 3775
3776 /*
3777 * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a
3778 * special case where we need to update the times despite not having
3779 * these flags set. For all other operations the VFS set these flags
3780 * explicitly if it wants a timestamp update.
3781 */
3782 if (newsize != oldsize && (!(mask & (ATTR_CTIME | ATTR_MTIME))))
3783 inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb);
3784
3761 if (newsize > oldsize) { 3785 if (newsize > oldsize) {
3762 truncate_pagecache(inode, oldsize, newsize); 3786 truncate_pagecache(inode, oldsize, newsize);
3763 ret = btrfs_cont_expand(inode, oldsize, newsize); 3787 ret = btrfs_cont_expand(inode, oldsize, newsize);
@@ -3783,9 +3807,34 @@ static int btrfs_setsize(struct inode *inode, loff_t newsize)
3783 set_bit(BTRFS_INODE_ORDERED_DATA_CLOSE, 3807 set_bit(BTRFS_INODE_ORDERED_DATA_CLOSE,
3784 &BTRFS_I(inode)->runtime_flags); 3808 &BTRFS_I(inode)->runtime_flags);
3785 3809
3810 /*
3811 * 1 for the orphan item we're going to add
3812 * 1 for the orphan item deletion.
3813 */
3814 trans = btrfs_start_transaction(root, 2);
3815 if (IS_ERR(trans))
3816 return PTR_ERR(trans);
3817
3818 /*
3819 * We need to do this in case we fail at _any_ point during the
3820 * actual truncate. Once we do the truncate_setsize we could
3821 * invalidate pages which forces any outstanding ordered io to
3822 * be instantly completed which will give us extents that need
3823 * to be truncated. If we fail to get an orphan inode down we
3824 * could have left over extents that were never meant to live,
3825 * so we need to garuntee from this point on that everything
3826 * will be consistent.
3827 */
3828 ret = btrfs_orphan_add(trans, inode);
3829 btrfs_end_transaction(trans, root);
3830 if (ret)
3831 return ret;
3832
3786 /* we don't support swapfiles, so vmtruncate shouldn't fail */ 3833 /* we don't support swapfiles, so vmtruncate shouldn't fail */
3787 truncate_setsize(inode, newsize); 3834 truncate_setsize(inode, newsize);
3788 ret = btrfs_truncate(inode); 3835 ret = btrfs_truncate(inode);
3836 if (ret && inode->i_nlink)
3837 btrfs_orphan_del(NULL, inode);
3789 } 3838 }
3790 3839
3791 return ret; 3840 return ret;
@@ -3805,7 +3854,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
3805 return err; 3854 return err;
3806 3855
3807 if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { 3856 if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) {
3808 err = btrfs_setsize(inode, attr->ia_size); 3857 err = btrfs_setsize(inode, attr);
3809 if (err) 3858 if (err)
3810 return err; 3859 return err;
3811 } 3860 }
@@ -5586,10 +5635,13 @@ struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *pag
5586 return em; 5635 return em;
5587 if (em) { 5636 if (em) {
5588 /* 5637 /*
5589 * if our em maps to a hole, there might 5638 * if our em maps to
5590 * actually be delalloc bytes behind it 5639 * - a hole or
5640 * - a pre-alloc extent,
5641 * there might actually be delalloc bytes behind it.
5591 */ 5642 */
5592 if (em->block_start != EXTENT_MAP_HOLE) 5643 if (em->block_start != EXTENT_MAP_HOLE &&
5644 !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))
5593 return em; 5645 return em;
5594 else 5646 else
5595 hole_em = em; 5647 hole_em = em;
@@ -5671,6 +5723,8 @@ struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *pag
5671 */ 5723 */
5672 em->block_start = hole_em->block_start; 5724 em->block_start = hole_em->block_start;
5673 em->block_len = hole_len; 5725 em->block_len = hole_len;
5726 if (test_bit(EXTENT_FLAG_PREALLOC, &hole_em->flags))
5727 set_bit(EXTENT_FLAG_PREALLOC, &em->flags);
5674 } else { 5728 } else {
5675 em->start = range_start; 5729 em->start = range_start;
5676 em->len = found; 5730 em->len = found;
@@ -6929,11 +6983,9 @@ static int btrfs_truncate(struct inode *inode)
6929 6983
6930 /* 6984 /*
6931 * 1 for the truncate slack space 6985 * 1 for the truncate slack space
6932 * 1 for the orphan item we're going to add
6933 * 1 for the orphan item deletion
6934 * 1 for updating the inode. 6986 * 1 for updating the inode.
6935 */ 6987 */
6936 trans = btrfs_start_transaction(root, 4); 6988 trans = btrfs_start_transaction(root, 2);
6937 if (IS_ERR(trans)) { 6989 if (IS_ERR(trans)) {
6938 err = PTR_ERR(trans); 6990 err = PTR_ERR(trans);
6939 goto out; 6991 goto out;
@@ -6944,12 +6996,6 @@ static int btrfs_truncate(struct inode *inode)
6944 min_size); 6996 min_size);
6945 BUG_ON(ret); 6997 BUG_ON(ret);
6946 6998
6947 ret = btrfs_orphan_add(trans, inode);
6948 if (ret) {
6949 btrfs_end_transaction(trans, root);
6950 goto out;
6951 }
6952
6953 /* 6999 /*
6954 * setattr is responsible for setting the ordered_data_close flag, 7000 * setattr is responsible for setting the ordered_data_close flag,
6955 * but that is only tested during the last file release. That 7001 * but that is only tested during the last file release. That
@@ -7018,12 +7064,6 @@ static int btrfs_truncate(struct inode *inode)
7018 ret = btrfs_orphan_del(trans, inode); 7064 ret = btrfs_orphan_del(trans, inode);
7019 if (ret) 7065 if (ret)
7020 err = ret; 7066 err = ret;
7021 } else if (ret && inode->i_nlink > 0) {
7022 /*
7023 * Failed to do the truncate, remove us from the in memory
7024 * orphan list.
7025 */
7026 ret = btrfs_orphan_del(NULL, inode);
7027 } 7067 }
7028 7068
7029 if (trans) { 7069 if (trans) {