aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/extent_io.h4
-rw-r--r--fs/btrfs/inode.c59
2 files changed, 45 insertions, 18 deletions
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 3e4fad4a909d..48a30d0e71fb 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -14,7 +14,7 @@
14#define EXTENT_DEFRAG (1U << 6) 14#define EXTENT_DEFRAG (1U << 6)
15#define EXTENT_BOUNDARY (1U << 9) 15#define EXTENT_BOUNDARY (1U << 9)
16#define EXTENT_NODATASUM (1U << 10) 16#define EXTENT_NODATASUM (1U << 10)
17#define EXTENT_DO_ACCOUNTING (1U << 11) 17#define EXTENT_CLEAR_META_RESV (1U << 11)
18#define EXTENT_FIRST_DELALLOC (1U << 12) 18#define EXTENT_FIRST_DELALLOC (1U << 12)
19#define EXTENT_NEED_WAIT (1U << 13) 19#define EXTENT_NEED_WAIT (1U << 13)
20#define EXTENT_DAMAGED (1U << 14) 20#define EXTENT_DAMAGED (1U << 14)
@@ -22,6 +22,8 @@
22#define EXTENT_QGROUP_RESERVED (1U << 16) 22#define EXTENT_QGROUP_RESERVED (1U << 16)
23#define EXTENT_CLEAR_DATA_RESV (1U << 17) 23#define EXTENT_CLEAR_DATA_RESV (1U << 17)
24#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) 24#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK)
25#define EXTENT_DO_ACCOUNTING (EXTENT_CLEAR_META_RESV | \
26 EXTENT_CLEAR_DATA_RESV)
25#define EXTENT_CTLBITS (EXTENT_DO_ACCOUNTING | EXTENT_FIRST_DELALLOC) 27#define EXTENT_CTLBITS (EXTENT_DO_ACCOUNTING | EXTENT_FIRST_DELALLOC)
26 28
27/* 29/*
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index b8b2a3cbdbe1..bfe04afa6277 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -943,10 +943,13 @@ static noinline int cow_file_range(struct inode *inode,
943 u64 num_bytes; 943 u64 num_bytes;
944 unsigned long ram_size; 944 unsigned long ram_size;
945 u64 disk_num_bytes; 945 u64 disk_num_bytes;
946 u64 cur_alloc_size; 946 u64 cur_alloc_size = 0;
947 u64 blocksize = fs_info->sectorsize; 947 u64 blocksize = fs_info->sectorsize;
948 struct btrfs_key ins; 948 struct btrfs_key ins;
949 struct extent_map *em; 949 struct extent_map *em;
950 unsigned clear_bits;
951 unsigned long page_ops;
952 bool extent_reserved = false;
950 int ret = 0; 953 int ret = 0;
951 954
952 if (btrfs_is_free_space_inode(BTRFS_I(inode))) { 955 if (btrfs_is_free_space_inode(BTRFS_I(inode))) {
@@ -991,14 +994,14 @@ static noinline int cow_file_range(struct inode *inode,
991 start + num_bytes - 1, 0); 994 start + num_bytes - 1, 0);
992 995
993 while (disk_num_bytes > 0) { 996 while (disk_num_bytes > 0) {
994 unsigned long op;
995
996 cur_alloc_size = disk_num_bytes; 997 cur_alloc_size = disk_num_bytes;
997 ret = btrfs_reserve_extent(root, cur_alloc_size, cur_alloc_size, 998 ret = btrfs_reserve_extent(root, cur_alloc_size, cur_alloc_size,
998 fs_info->sectorsize, 0, alloc_hint, 999 fs_info->sectorsize, 0, alloc_hint,
999 &ins, 1, 1); 1000 &ins, 1, 1);
1000 if (ret < 0) 1001 if (ret < 0)
1001 goto out_unlock; 1002 goto out_unlock;
1003 cur_alloc_size = ins.offset;
1004 extent_reserved = true;
1002 1005
1003 ram_size = ins.offset; 1006 ram_size = ins.offset;
1004 em = create_io_em(inode, start, ins.offset, /* len */ 1007 em = create_io_em(inode, start, ins.offset, /* len */
@@ -1013,7 +1016,6 @@ static noinline int cow_file_range(struct inode *inode,
1013 goto out_reserve; 1016 goto out_reserve;
1014 free_extent_map(em); 1017 free_extent_map(em);
1015 1018
1016 cur_alloc_size = ins.offset;
1017 ret = btrfs_add_ordered_extent(inode, start, ins.objectid, 1019 ret = btrfs_add_ordered_extent(inode, start, ins.objectid,
1018 ram_size, cur_alloc_size, 0); 1020 ram_size, cur_alloc_size, 0);
1019 if (ret) 1021 if (ret)
@@ -1048,14 +1050,14 @@ static noinline int cow_file_range(struct inode *inode,
1048 * Do set the Private2 bit so we know this page was properly 1050 * Do set the Private2 bit so we know this page was properly
1049 * setup for writepage 1051 * setup for writepage
1050 */ 1052 */
1051 op = unlock ? PAGE_UNLOCK : 0; 1053 page_ops = unlock ? PAGE_UNLOCK : 0;
1052 op |= PAGE_SET_PRIVATE2; 1054 page_ops |= PAGE_SET_PRIVATE2;
1053 1055
1054 extent_clear_unlock_delalloc(inode, start, 1056 extent_clear_unlock_delalloc(inode, start,
1055 start + ram_size - 1, 1057 start + ram_size - 1,
1056 delalloc_end, locked_page, 1058 delalloc_end, locked_page,
1057 EXTENT_LOCKED | EXTENT_DELALLOC, 1059 EXTENT_LOCKED | EXTENT_DELALLOC,
1058 op); 1060 page_ops);
1059 if (disk_num_bytes < cur_alloc_size) 1061 if (disk_num_bytes < cur_alloc_size)
1060 disk_num_bytes = 0; 1062 disk_num_bytes = 0;
1061 else 1063 else
@@ -1063,6 +1065,7 @@ static noinline int cow_file_range(struct inode *inode,
1063 num_bytes -= cur_alloc_size; 1065 num_bytes -= cur_alloc_size;
1064 alloc_hint = ins.objectid + ins.offset; 1066 alloc_hint = ins.objectid + ins.offset;
1065 start += cur_alloc_size; 1067 start += cur_alloc_size;
1068 extent_reserved = false;
1066 1069
1067 /* 1070 /*
1068 * btrfs_reloc_clone_csums() error, since start is increased 1071 * btrfs_reloc_clone_csums() error, since start is increased
@@ -1081,12 +1084,35 @@ out_reserve:
1081 btrfs_dec_block_group_reservations(fs_info, ins.objectid); 1084 btrfs_dec_block_group_reservations(fs_info, ins.objectid);
1082 btrfs_free_reserved_extent(fs_info, ins.objectid, ins.offset, 1); 1085 btrfs_free_reserved_extent(fs_info, ins.objectid, ins.offset, 1);
1083out_unlock: 1086out_unlock:
1087 clear_bits = EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DEFRAG |
1088 EXTENT_CLEAR_META_RESV;
1089 page_ops = PAGE_UNLOCK | PAGE_CLEAR_DIRTY | PAGE_SET_WRITEBACK |
1090 PAGE_END_WRITEBACK;
1091 /*
1092 * If we reserved an extent for our delalloc range (or a subrange) and
1093 * failed to create the respective ordered extent, then it means that
1094 * when we reserved the extent we decremented the extent's size from
1095 * the data space_info's bytes_may_use counter and incremented the
1096 * space_info's bytes_reserved counter by the same amount. We must make
1097 * sure extent_clear_unlock_delalloc() does not try to decrement again
1098 * the data space_info's bytes_may_use counter, therefore we do not pass
1099 * it the flag EXTENT_CLEAR_DATA_RESV.
1100 */
1101 if (extent_reserved) {
1102 extent_clear_unlock_delalloc(inode, start,
1103 start + cur_alloc_size,
1104 start + cur_alloc_size,
1105 locked_page,
1106 clear_bits,
1107 page_ops);
1108 start += cur_alloc_size;
1109 if (start >= end)
1110 goto out;
1111 }
1084 extent_clear_unlock_delalloc(inode, start, end, delalloc_end, 1112 extent_clear_unlock_delalloc(inode, start, end, delalloc_end,
1085 locked_page, 1113 locked_page,
1086 EXTENT_LOCKED | EXTENT_DO_ACCOUNTING | 1114 clear_bits | EXTENT_CLEAR_DATA_RESV,
1087 EXTENT_DELALLOC | EXTENT_DEFRAG, 1115 page_ops);
1088 PAGE_UNLOCK | PAGE_CLEAR_DIRTY |
1089 PAGE_SET_WRITEBACK | PAGE_END_WRITEBACK);
1090 goto out; 1116 goto out;
1091} 1117}
1092 1118
@@ -1776,7 +1802,7 @@ static void btrfs_clear_bit_hook(struct btrfs_inode *inode,
1776 1802
1777 if (*bits & EXTENT_FIRST_DELALLOC) { 1803 if (*bits & EXTENT_FIRST_DELALLOC) {
1778 *bits &= ~EXTENT_FIRST_DELALLOC; 1804 *bits &= ~EXTENT_FIRST_DELALLOC;
1779 } else if (!(*bits & EXTENT_DO_ACCOUNTING)) { 1805 } else if (!(*bits & EXTENT_CLEAR_META_RESV)) {
1780 spin_lock(&inode->lock); 1806 spin_lock(&inode->lock);
1781 inode->outstanding_extents -= num_extents; 1807 inode->outstanding_extents -= num_extents;
1782 spin_unlock(&inode->lock); 1808 spin_unlock(&inode->lock);
@@ -1787,7 +1813,7 @@ static void btrfs_clear_bit_hook(struct btrfs_inode *inode,
1787 * don't need to call dellalloc_release_metadata if there is an 1813 * don't need to call dellalloc_release_metadata if there is an
1788 * error. 1814 * error.
1789 */ 1815 */
1790 if (*bits & EXTENT_DO_ACCOUNTING && 1816 if (*bits & EXTENT_CLEAR_META_RESV &&
1791 root != fs_info->tree_root) 1817 root != fs_info->tree_root)
1792 btrfs_delalloc_release_metadata(inode, len); 1818 btrfs_delalloc_release_metadata(inode, len);
1793 1819
@@ -1795,10 +1821,9 @@ static void btrfs_clear_bit_hook(struct btrfs_inode *inode,
1795 if (btrfs_is_testing(fs_info)) 1821 if (btrfs_is_testing(fs_info))
1796 return; 1822 return;
1797 1823
1798 if (root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID 1824 if (root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID &&
1799 && do_list && !(state->state & EXTENT_NORESERVE) 1825 do_list && !(state->state & EXTENT_NORESERVE) &&
1800 && (*bits & (EXTENT_DO_ACCOUNTING | 1826 (*bits & EXTENT_CLEAR_DATA_RESV))
1801 EXTENT_CLEAR_DATA_RESV)))
1802 btrfs_free_reserved_data_space_noquota( 1827 btrfs_free_reserved_data_space_noquota(
1803 &inode->vfs_inode, 1828 &inode->vfs_inode,
1804 state->start, len); 1829 state->start, len);