diff options
author | Chris Mason <chris.mason@fusionio.com> | 2013-01-21 20:26:55 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-01-21 20:26:55 -0500 |
commit | daf2c08911522d1739c55baf35f03531a29c87ef (patch) | |
tree | 380d89b955baebd90ca5ac1cf6527f963cf7dae7 /fs/btrfs/inode.c | |
parent | 2cf687039676c2b6e1ee96b0b89090aca94babcd (diff) | |
parent | 3972f2603d8570effaf633cea52b12c7c2773c11 (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.c | 82 |
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 | ||
91 | static int btrfs_setsize(struct inode *inode, loff_t newsize); | 91 | static int btrfs_setsize(struct inode *inode, struct iattr *attr); |
92 | static int btrfs_truncate(struct inode *inode); | 92 | static int btrfs_truncate(struct inode *inode); |
93 | static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent); | 93 | static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent); |
94 | static noinline int cow_file_range(struct inode *inode, | 94 | static 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 | ||
3751 | static int btrfs_setsize(struct inode *inode, loff_t newsize) | 3764 | static 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) { |