aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQu Wenruo <quwenruo@cn.fujitsu.com>2017-02-27 02:10:38 -0500
committerDavid Sterba <dsterba@suse.com>2017-06-29 14:17:02 -0400
commit364ecf3651e0862152c8b340d7cb3021dc0122c7 (patch)
tree9e1e9d93a88677df69305345f02efae073c042b3
parenta12b877b557dde885bdb6978cec86bf761e63c9a (diff)
btrfs: qgroup: Introduce extent changeset for qgroup reserve functions
Introduce a new parameter, struct extent_changeset for btrfs_qgroup_reserved_data() and its callers. Such extent_changeset was used in btrfs_qgroup_reserve_data() to record which range it reserved in current reserve, so it can free it in error paths. The reason we need to export it to callers is, at buffered write error path, without knowing what exactly which range we reserved in current allocation, we can free space which is not reserved by us. This will lead to qgroup reserved space underflow. Reviewed-by: Chandan Rajendra <chandan@linux.vnet.ibm.com> Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/ctree.h6
-rw-r--r--fs/btrfs/extent-tree.c23
-rw-r--r--fs/btrfs/extent_io.h34
-rw-r--r--fs/btrfs/file.c12
-rw-r--r--fs/btrfs/inode-map.c4
-rw-r--r--fs/btrfs/inode.c18
-rw-r--r--fs/btrfs/ioctl.c5
-rw-r--r--fs/btrfs/qgroup.c51
-rw-r--r--fs/btrfs/qgroup.h3
-rw-r--r--fs/btrfs/relocation.c4
10 files changed, 119 insertions, 41 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 5e33e1d6d5c9..1ee4489dc398 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2708,8 +2708,9 @@ enum btrfs_flush_state {
2708 COMMIT_TRANS = 6, 2708 COMMIT_TRANS = 6,
2709}; 2709};
2710 2710
2711int btrfs_check_data_free_space(struct inode *inode, u64 start, u64 len);
2712int btrfs_alloc_data_chunk_ondemand(struct btrfs_inode *inode, u64 bytes); 2711int btrfs_alloc_data_chunk_ondemand(struct btrfs_inode *inode, u64 bytes);
2712int btrfs_check_data_free_space(struct inode *inode,
2713 struct extent_changeset **reserved, u64 start, u64 len);
2713void btrfs_free_reserved_data_space(struct inode *inode, u64 start, u64 len); 2714void btrfs_free_reserved_data_space(struct inode *inode, u64 start, u64 len);
2714void btrfs_free_reserved_data_space_noquota(struct inode *inode, u64 start, 2715void btrfs_free_reserved_data_space_noquota(struct inode *inode, u64 start,
2715 u64 len); 2716 u64 len);
@@ -2727,7 +2728,8 @@ void btrfs_subvolume_release_metadata(struct btrfs_fs_info *fs_info,
2727 struct btrfs_block_rsv *rsv); 2728 struct btrfs_block_rsv *rsv);
2728int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes); 2729int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes);
2729void btrfs_delalloc_release_metadata(struct btrfs_inode *inode, u64 num_bytes); 2730void btrfs_delalloc_release_metadata(struct btrfs_inode *inode, u64 num_bytes);
2730int btrfs_delalloc_reserve_space(struct inode *inode, u64 start, u64 len); 2731int btrfs_delalloc_reserve_space(struct inode *inode,
2732 struct extent_changeset **reserved, u64 start, u64 len);
2731void btrfs_delalloc_release_space(struct inode *inode, u64 start, u64 len); 2733void btrfs_delalloc_release_space(struct inode *inode, u64 start, u64 len);
2732void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv, unsigned short type); 2734void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv, unsigned short type);
2733struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_fs_info *fs_info, 2735struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_fs_info *fs_info,
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index b0b02c6c71aa..70f85cfdbd46 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3402,6 +3402,7 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group,
3402 struct btrfs_fs_info *fs_info = block_group->fs_info; 3402 struct btrfs_fs_info *fs_info = block_group->fs_info;
3403 struct btrfs_root *root = fs_info->tree_root; 3403 struct btrfs_root *root = fs_info->tree_root;
3404 struct inode *inode = NULL; 3404 struct inode *inode = NULL;
3405 struct extent_changeset *data_reserved = NULL;
3405 u64 alloc_hint = 0; 3406 u64 alloc_hint = 0;
3406 int dcs = BTRFS_DC_ERROR; 3407 int dcs = BTRFS_DC_ERROR;
3407 u64 num_pages = 0; 3408 u64 num_pages = 0;
@@ -3521,7 +3522,7 @@ again:
3521 num_pages *= 16; 3522 num_pages *= 16;
3522 num_pages *= PAGE_SIZE; 3523 num_pages *= PAGE_SIZE;
3523 3524
3524 ret = btrfs_check_data_free_space(inode, 0, num_pages); 3525 ret = btrfs_check_data_free_space(inode, &data_reserved, 0, num_pages);
3525 if (ret) 3526 if (ret)
3526 goto out_put; 3527 goto out_put;
3527 3528
@@ -3552,6 +3553,7 @@ out:
3552 block_group->disk_cache_state = dcs; 3553 block_group->disk_cache_state = dcs;
3553 spin_unlock(&block_group->lock); 3554 spin_unlock(&block_group->lock);
3554 3555
3556 extent_changeset_free(data_reserved);
3555 return ret; 3557 return ret;
3556} 3558}
3557 3559
@@ -4326,12 +4328,8 @@ commit_trans:
4326 return ret; 4328 return ret;
4327} 4329}
4328 4330
4329/* 4331int btrfs_check_data_free_space(struct inode *inode,
4330 * New check_data_free_space() with ability for precious data reservation 4332 struct extent_changeset **reserved, u64 start, u64 len)
4331 * Will replace old btrfs_check_data_free_space(), but for patch split,
4332 * add a new function first and then replace it.
4333 */
4334int btrfs_check_data_free_space(struct inode *inode, u64 start, u64 len)
4335{ 4333{
4336 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); 4334 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
4337 int ret; 4335 int ret;
@@ -4346,9 +4344,11 @@ int btrfs_check_data_free_space(struct inode *inode, u64 start, u64 len)
4346 return ret; 4344 return ret;
4347 4345
4348 /* Use new btrfs_qgroup_reserve_data to reserve precious data space. */ 4346 /* Use new btrfs_qgroup_reserve_data to reserve precious data space. */
4349 ret = btrfs_qgroup_reserve_data(inode, start, len); 4347 ret = btrfs_qgroup_reserve_data(inode, reserved, start, len);
4350 if (ret < 0) 4348 if (ret < 0)
4351 btrfs_free_reserved_data_space_noquota(inode, start, len); 4349 btrfs_free_reserved_data_space_noquota(inode, start, len);
4350 else
4351 ret = 0;
4352 return ret; 4352 return ret;
4353} 4353}
4354 4354
@@ -6175,6 +6175,8 @@ void btrfs_delalloc_release_metadata(struct btrfs_inode *inode, u64 num_bytes)
6175 * @inode: inode we're writing to 6175 * @inode: inode we're writing to
6176 * @start: start range we are writing to 6176 * @start: start range we are writing to
6177 * @len: how long the range we are writing to 6177 * @len: how long the range we are writing to
6178 * @reserved: mandatory parameter, record actually reserved qgroup ranges of
6179 * current reservation.
6178 * 6180 *
6179 * This will do the following things 6181 * This will do the following things
6180 * 6182 *
@@ -6192,11 +6194,12 @@ void btrfs_delalloc_release_metadata(struct btrfs_inode *inode, u64 num_bytes)
6192 * Return 0 for success 6194 * Return 0 for success
6193 * Return <0 for error(-ENOSPC or -EQUOT) 6195 * Return <0 for error(-ENOSPC or -EQUOT)
6194 */ 6196 */
6195int btrfs_delalloc_reserve_space(struct inode *inode, u64 start, u64 len) 6197int btrfs_delalloc_reserve_space(struct inode *inode,
6198 struct extent_changeset **reserved, u64 start, u64 len)
6196{ 6199{
6197 int ret; 6200 int ret;
6198 6201
6199 ret = btrfs_check_data_free_space(inode, start, len); 6202 ret = btrfs_check_data_free_space(inode, reserved, start, len);
6200 if (ret < 0) 6203 if (ret < 0)
6201 return ret; 6204 return ret;
6202 ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), len); 6205 ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), len);
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index ce670d213913..aeafdb35d90b 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -215,6 +215,40 @@ struct extent_changeset {
215 struct ulist range_changed; 215 struct ulist range_changed;
216}; 216};
217 217
218static inline void extent_changeset_init(struct extent_changeset *changeset)
219{
220 changeset->bytes_changed = 0;
221 ulist_init(&changeset->range_changed);
222}
223
224static inline struct extent_changeset *extent_changeset_alloc(void)
225{
226 struct extent_changeset *ret;
227
228 ret = kmalloc(sizeof(*ret), GFP_KERNEL);
229 if (!ret)
230 return NULL;
231
232 extent_changeset_init(ret);
233 return ret;
234}
235
236static inline void extent_changeset_release(struct extent_changeset *changeset)
237{
238 if (!changeset)
239 return;
240 changeset->bytes_changed = 0;
241 ulist_release(&changeset->range_changed);
242}
243
244static inline void extent_changeset_free(struct extent_changeset *changeset)
245{
246 if (!changeset)
247 return;
248 extent_changeset_release(changeset);
249 kfree(changeset);
250}
251
218static inline void extent_set_compress_type(unsigned long *bio_flags, 252static inline void extent_set_compress_type(unsigned long *bio_flags,
219 int compress_type) 253 int compress_type)
220{ 254{
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 5da85b080368..1b5cce51728b 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1581,6 +1581,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
1581 struct btrfs_root *root = BTRFS_I(inode)->root; 1581 struct btrfs_root *root = BTRFS_I(inode)->root;
1582 struct page **pages = NULL; 1582 struct page **pages = NULL;
1583 struct extent_state *cached_state = NULL; 1583 struct extent_state *cached_state = NULL;
1584 struct extent_changeset *data_reserved = NULL;
1584 u64 release_bytes = 0; 1585 u64 release_bytes = 0;
1585 u64 lockstart; 1586 u64 lockstart;
1586 u64 lockend; 1587 u64 lockend;
@@ -1628,7 +1629,9 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
1628 reserve_bytes = round_up(write_bytes + sector_offset, 1629 reserve_bytes = round_up(write_bytes + sector_offset,
1629 fs_info->sectorsize); 1630 fs_info->sectorsize);
1630 1631
1631 ret = btrfs_check_data_free_space(inode, pos, write_bytes); 1632 extent_changeset_release(data_reserved);
1633 ret = btrfs_check_data_free_space(inode, &data_reserved, pos,
1634 write_bytes);
1632 if (ret < 0) { 1635 if (ret < 0) {
1633 if ((BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW | 1636 if ((BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
1634 BTRFS_INODE_PREALLOC)) && 1637 BTRFS_INODE_PREALLOC)) &&
@@ -1802,6 +1805,7 @@ again:
1802 } 1805 }
1803 } 1806 }
1804 1807
1808 extent_changeset_free(data_reserved);
1805 return num_written ? num_written : ret; 1809 return num_written ? num_written : ret;
1806} 1810}
1807 1811
@@ -2772,6 +2776,7 @@ static long btrfs_fallocate(struct file *file, int mode,
2772{ 2776{
2773 struct inode *inode = file_inode(file); 2777 struct inode *inode = file_inode(file);
2774 struct extent_state *cached_state = NULL; 2778 struct extent_state *cached_state = NULL;
2779 struct extent_changeset *data_reserved = NULL;
2775 struct falloc_range *range; 2780 struct falloc_range *range;
2776 struct falloc_range *tmp; 2781 struct falloc_range *tmp;
2777 struct list_head reserve_list; 2782 struct list_head reserve_list;
@@ -2901,8 +2906,8 @@ static long btrfs_fallocate(struct file *file, int mode,
2901 free_extent_map(em); 2906 free_extent_map(em);
2902 break; 2907 break;
2903 } 2908 }
2904 ret = btrfs_qgroup_reserve_data(inode, cur_offset, 2909 ret = btrfs_qgroup_reserve_data(inode, &data_reserved,
2905 last_byte - cur_offset); 2910 cur_offset, last_byte - cur_offset);
2906 if (ret < 0) { 2911 if (ret < 0) {
2907 free_extent_map(em); 2912 free_extent_map(em);
2908 break; 2913 break;
@@ -2974,6 +2979,7 @@ out:
2974 if (ret != 0) 2979 if (ret != 0)
2975 btrfs_free_reserved_data_space(inode, alloc_start, 2980 btrfs_free_reserved_data_space(inode, alloc_start,
2976 alloc_end - cur_offset); 2981 alloc_end - cur_offset);
2982 extent_changeset_free(data_reserved);
2977 return ret; 2983 return ret;
2978} 2984}
2979 2985
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
index 5c6c20ec64d8..d02019747d00 100644
--- a/fs/btrfs/inode-map.c
+++ b/fs/btrfs/inode-map.c
@@ -400,6 +400,7 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
400 struct btrfs_path *path; 400 struct btrfs_path *path;
401 struct inode *inode; 401 struct inode *inode;
402 struct btrfs_block_rsv *rsv; 402 struct btrfs_block_rsv *rsv;
403 struct extent_changeset *data_reserved = NULL;
403 u64 num_bytes; 404 u64 num_bytes;
404 u64 alloc_hint = 0; 405 u64 alloc_hint = 0;
405 int ret; 406 int ret;
@@ -492,7 +493,7 @@ again:
492 /* Just to make sure we have enough space */ 493 /* Just to make sure we have enough space */
493 prealloc += 8 * PAGE_SIZE; 494 prealloc += 8 * PAGE_SIZE;
494 495
495 ret = btrfs_delalloc_reserve_space(inode, 0, prealloc); 496 ret = btrfs_delalloc_reserve_space(inode, &data_reserved, 0, prealloc);
496 if (ret) 497 if (ret)
497 goto out_put; 498 goto out_put;
498 499
@@ -516,6 +517,7 @@ out:
516 trans->bytes_reserved = num_bytes; 517 trans->bytes_reserved = num_bytes;
517 518
518 btrfs_free_path(path); 519 btrfs_free_path(path);
520 extent_changeset_free(data_reserved);
519 return ret; 521 return ret;
520} 522}
521 523
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index b66ea03a3a1c..d9cf6df40d5e 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2037,6 +2037,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
2037 struct btrfs_writepage_fixup *fixup; 2037 struct btrfs_writepage_fixup *fixup;
2038 struct btrfs_ordered_extent *ordered; 2038 struct btrfs_ordered_extent *ordered;
2039 struct extent_state *cached_state = NULL; 2039 struct extent_state *cached_state = NULL;
2040 struct extent_changeset *data_reserved = NULL;
2040 struct page *page; 2041 struct page *page;
2041 struct inode *inode; 2042 struct inode *inode;
2042 u64 page_start; 2043 u64 page_start;
@@ -2074,7 +2075,7 @@ again:
2074 goto again; 2075 goto again;
2075 } 2076 }
2076 2077
2077 ret = btrfs_delalloc_reserve_space(inode, page_start, 2078 ret = btrfs_delalloc_reserve_space(inode, &data_reserved, page_start,
2078 PAGE_SIZE); 2079 PAGE_SIZE);
2079 if (ret) { 2080 if (ret) {
2080 mapping_set_error(page->mapping, ret); 2081 mapping_set_error(page->mapping, ret);
@@ -2094,6 +2095,7 @@ out_page:
2094 unlock_page(page); 2095 unlock_page(page);
2095 put_page(page); 2096 put_page(page);
2096 kfree(fixup); 2097 kfree(fixup);
2098 extent_changeset_free(data_reserved);
2097} 2099}
2098 2100
2099/* 2101/*
@@ -4769,6 +4771,7 @@ int btrfs_truncate_block(struct inode *inode, loff_t from, loff_t len,
4769 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; 4771 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
4770 struct btrfs_ordered_extent *ordered; 4772 struct btrfs_ordered_extent *ordered;
4771 struct extent_state *cached_state = NULL; 4773 struct extent_state *cached_state = NULL;
4774 struct extent_changeset *data_reserved = NULL;
4772 char *kaddr; 4775 char *kaddr;
4773 u32 blocksize = fs_info->sectorsize; 4776 u32 blocksize = fs_info->sectorsize;
4774 pgoff_t index = from >> PAGE_SHIFT; 4777 pgoff_t index = from >> PAGE_SHIFT;
@@ -4783,7 +4786,7 @@ int btrfs_truncate_block(struct inode *inode, loff_t from, loff_t len,
4783 (!len || ((len & (blocksize - 1)) == 0))) 4786 (!len || ((len & (blocksize - 1)) == 0)))
4784 goto out; 4787 goto out;
4785 4788
4786 ret = btrfs_delalloc_reserve_space(inode, 4789 ret = btrfs_delalloc_reserve_space(inode, &data_reserved,
4787 round_down(from, blocksize), blocksize); 4790 round_down(from, blocksize), blocksize);
4788 if (ret) 4791 if (ret)
4789 goto out; 4792 goto out;
@@ -4868,6 +4871,7 @@ out_unlock:
4868 unlock_page(page); 4871 unlock_page(page);
4869 put_page(page); 4872 put_page(page);
4870out: 4873out:
4874 extent_changeset_free(data_reserved);
4871 return ret; 4875 return ret;
4872} 4876}
4873 4877
@@ -8718,6 +8722,7 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
8718 struct inode *inode = file->f_mapping->host; 8722 struct inode *inode = file->f_mapping->host;
8719 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); 8723 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
8720 struct btrfs_dio_data dio_data = { 0 }; 8724 struct btrfs_dio_data dio_data = { 0 };
8725 struct extent_changeset *data_reserved = NULL;
8721 loff_t offset = iocb->ki_pos; 8726 loff_t offset = iocb->ki_pos;
8722 size_t count = 0; 8727 size_t count = 0;
8723 int flags = 0; 8728 int flags = 0;
@@ -8754,7 +8759,8 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
8754 inode_unlock(inode); 8759 inode_unlock(inode);
8755 relock = true; 8760 relock = true;
8756 } 8761 }
8757 ret = btrfs_delalloc_reserve_space(inode, offset, count); 8762 ret = btrfs_delalloc_reserve_space(inode, &data_reserved,
8763 offset, count);
8758 if (ret) 8764 if (ret)
8759 goto out; 8765 goto out;
8760 dio_data.outstanding_extents = count_max_extents(count); 8766 dio_data.outstanding_extents = count_max_extents(count);
@@ -8811,6 +8817,7 @@ out:
8811 if (relock) 8817 if (relock)
8812 inode_lock(inode); 8818 inode_lock(inode);
8813 8819
8820 extent_changeset_free(data_reserved);
8814 return ret; 8821 return ret;
8815} 8822}
8816 8823
@@ -9043,6 +9050,7 @@ int btrfs_page_mkwrite(struct vm_fault *vmf)
9043 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; 9050 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
9044 struct btrfs_ordered_extent *ordered; 9051 struct btrfs_ordered_extent *ordered;
9045 struct extent_state *cached_state = NULL; 9052 struct extent_state *cached_state = NULL;
9053 struct extent_changeset *data_reserved = NULL;
9046 char *kaddr; 9054 char *kaddr;
9047 unsigned long zero_start; 9055 unsigned long zero_start;
9048 loff_t size; 9056 loff_t size;
@@ -9068,7 +9076,7 @@ int btrfs_page_mkwrite(struct vm_fault *vmf)
9068 * end up waiting indefinitely to get a lock on the page currently 9076 * end up waiting indefinitely to get a lock on the page currently
9069 * being processed by btrfs_page_mkwrite() function. 9077 * being processed by btrfs_page_mkwrite() function.
9070 */ 9078 */
9071 ret = btrfs_delalloc_reserve_space(inode, page_start, 9079 ret = btrfs_delalloc_reserve_space(inode, &data_reserved, page_start,
9072 reserved_space); 9080 reserved_space);
9073 if (!ret) { 9081 if (!ret) {
9074 ret = file_update_time(vmf->vma->vm_file); 9082 ret = file_update_time(vmf->vma->vm_file);
@@ -9174,6 +9182,7 @@ again:
9174out_unlock: 9182out_unlock:
9175 if (!ret) { 9183 if (!ret) {
9176 sb_end_pagefault(inode->i_sb); 9184 sb_end_pagefault(inode->i_sb);
9185 extent_changeset_free(data_reserved);
9177 return VM_FAULT_LOCKED; 9186 return VM_FAULT_LOCKED;
9178 } 9187 }
9179 unlock_page(page); 9188 unlock_page(page);
@@ -9181,6 +9190,7 @@ out:
9181 btrfs_delalloc_release_space(inode, page_start, reserved_space); 9190 btrfs_delalloc_release_space(inode, page_start, reserved_space);
9182out_noreserve: 9191out_noreserve:
9183 sb_end_pagefault(inode->i_sb); 9192 sb_end_pagefault(inode->i_sb);
9193 extent_changeset_free(data_reserved);
9184 return ret; 9194 return ret;
9185} 9195}
9186 9196
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index e4116f9248c2..ccee5417d3f6 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1127,6 +1127,7 @@ static int cluster_pages_for_defrag(struct inode *inode,
1127 struct btrfs_ordered_extent *ordered; 1127 struct btrfs_ordered_extent *ordered;
1128 struct extent_state *cached_state = NULL; 1128 struct extent_state *cached_state = NULL;
1129 struct extent_io_tree *tree; 1129 struct extent_io_tree *tree;
1130 struct extent_changeset *data_reserved = NULL;
1130 gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping); 1131 gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping);
1131 1132
1132 file_end = (isize - 1) >> PAGE_SHIFT; 1133 file_end = (isize - 1) >> PAGE_SHIFT;
@@ -1135,7 +1136,7 @@ static int cluster_pages_for_defrag(struct inode *inode,
1135 1136
1136 page_cnt = min_t(u64, (u64)num_pages, (u64)file_end - start_index + 1); 1137 page_cnt = min_t(u64, (u64)num_pages, (u64)file_end - start_index + 1);
1137 1138
1138 ret = btrfs_delalloc_reserve_space(inode, 1139 ret = btrfs_delalloc_reserve_space(inode, &data_reserved,
1139 start_index << PAGE_SHIFT, 1140 start_index << PAGE_SHIFT,
1140 page_cnt << PAGE_SHIFT); 1141 page_cnt << PAGE_SHIFT);
1141 if (ret) 1142 if (ret)
@@ -1247,6 +1248,7 @@ again:
1247 unlock_page(pages[i]); 1248 unlock_page(pages[i]);
1248 put_page(pages[i]); 1249 put_page(pages[i]);
1249 } 1250 }
1251 extent_changeset_free(data_reserved);
1250 return i_done; 1252 return i_done;
1251out: 1253out:
1252 for (i = 0; i < i_done; i++) { 1254 for (i = 0; i < i_done; i++) {
@@ -1256,6 +1258,7 @@ out:
1256 btrfs_delalloc_release_space(inode, 1258 btrfs_delalloc_release_space(inode,
1257 start_index << PAGE_SHIFT, 1259 start_index << PAGE_SHIFT,
1258 page_cnt << PAGE_SHIFT); 1260 page_cnt << PAGE_SHIFT);
1261 extent_changeset_free(data_reserved);
1259 return ret; 1262 return ret;
1260 1263
1261} 1264}
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 475d53c492c8..002088937021 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -2835,43 +2835,60 @@ btrfs_qgroup_rescan_resume(struct btrfs_fs_info *fs_info)
2835 * Return <0 for error (including -EQUOT) 2835 * Return <0 for error (including -EQUOT)
2836 * 2836 *
2837 * NOTE: this function may sleep for memory allocation. 2837 * NOTE: this function may sleep for memory allocation.
2838 * if btrfs_qgroup_reserve_data() is called multiple times with
2839 * same @reserved, caller must ensure when error happens it's OK
2840 * to free *ALL* reserved space.
2838 */ 2841 */
2839int btrfs_qgroup_reserve_data(struct inode *inode, u64 start, u64 len) 2842int btrfs_qgroup_reserve_data(struct inode *inode,
2843 struct extent_changeset **reserved_ret, u64 start,
2844 u64 len)
2840{ 2845{
2841 struct btrfs_root *root = BTRFS_I(inode)->root; 2846 struct btrfs_root *root = BTRFS_I(inode)->root;
2842 struct extent_changeset changeset;
2843 struct ulist_node *unode; 2847 struct ulist_node *unode;
2844 struct ulist_iterator uiter; 2848 struct ulist_iterator uiter;
2849 struct extent_changeset *reserved;
2850 u64 orig_reserved;
2851 u64 to_reserve;
2845 int ret; 2852 int ret;
2846 2853
2847 if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &root->fs_info->flags) || 2854 if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &root->fs_info->flags) ||
2848 !is_fstree(root->objectid) || len == 0) 2855 !is_fstree(root->objectid) || len == 0)
2849 return 0; 2856 return 0;
2850 2857
2851 changeset.bytes_changed = 0; 2858 /* @reserved parameter is mandatory for qgroup */
2852 ulist_init(&changeset.range_changed); 2859 if (WARN_ON(!reserved_ret))
2860 return -EINVAL;
2861 if (!*reserved_ret) {
2862 *reserved_ret = extent_changeset_alloc();
2863 if (!*reserved_ret)
2864 return -ENOMEM;
2865 }
2866 reserved = *reserved_ret;
2867 /* Record already reserved space */
2868 orig_reserved = reserved->bytes_changed;
2853 ret = set_record_extent_bits(&BTRFS_I(inode)->io_tree, start, 2869 ret = set_record_extent_bits(&BTRFS_I(inode)->io_tree, start,
2854 start + len -1, EXTENT_QGROUP_RESERVED, &changeset); 2870 start + len -1, EXTENT_QGROUP_RESERVED, reserved);
2871
2872 /* Newly reserved space */
2873 to_reserve = reserved->bytes_changed - orig_reserved;
2855 trace_btrfs_qgroup_reserve_data(inode, start, len, 2874 trace_btrfs_qgroup_reserve_data(inode, start, len,
2856 changeset.bytes_changed, 2875 to_reserve, QGROUP_RESERVE);
2857 QGROUP_RESERVE);
2858 if (ret < 0) 2876 if (ret < 0)
2859 goto cleanup; 2877 goto cleanup;
2860 ret = qgroup_reserve(root, changeset.bytes_changed, true); 2878 ret = qgroup_reserve(root, to_reserve, true);
2861 if (ret < 0) 2879 if (ret < 0)
2862 goto cleanup; 2880 goto cleanup;
2863 2881
2864 ulist_release(&changeset.range_changed);
2865 return ret; 2882 return ret;
2866 2883
2867cleanup: 2884cleanup:
2868 /* cleanup already reserved ranges */ 2885 /* cleanup *ALL* already reserved ranges */
2869 ULIST_ITER_INIT(&uiter); 2886 ULIST_ITER_INIT(&uiter);
2870 while ((unode = ulist_next(&changeset.range_changed, &uiter))) 2887 while ((unode = ulist_next(&reserved->range_changed, &uiter)))
2871 clear_extent_bit(&BTRFS_I(inode)->io_tree, unode->val, 2888 clear_extent_bit(&BTRFS_I(inode)->io_tree, unode->val,
2872 unode->aux, EXTENT_QGROUP_RESERVED, 0, 0, NULL, 2889 unode->aux, EXTENT_QGROUP_RESERVED, 0, 0, NULL,
2873 GFP_NOFS); 2890 GFP_NOFS);
2874 ulist_release(&changeset.range_changed); 2891 extent_changeset_release(reserved);
2875 return ret; 2892 return ret;
2876} 2893}
2877 2894
@@ -2882,8 +2899,7 @@ static int __btrfs_qgroup_release_data(struct inode *inode, u64 start, u64 len,
2882 int trace_op = QGROUP_RELEASE; 2899 int trace_op = QGROUP_RELEASE;
2883 int ret; 2900 int ret;
2884 2901
2885 changeset.bytes_changed = 0; 2902 extent_changeset_init(&changeset);
2886 ulist_init(&changeset.range_changed);
2887 ret = clear_record_extent_bits(&BTRFS_I(inode)->io_tree, start, 2903 ret = clear_record_extent_bits(&BTRFS_I(inode)->io_tree, start,
2888 start + len -1, EXTENT_QGROUP_RESERVED, &changeset); 2904 start + len -1, EXTENT_QGROUP_RESERVED, &changeset);
2889 if (ret < 0) 2905 if (ret < 0)
@@ -2899,7 +2915,7 @@ static int __btrfs_qgroup_release_data(struct inode *inode, u64 start, u64 len,
2899 changeset.bytes_changed); 2915 changeset.bytes_changed);
2900 ret = changeset.bytes_changed; 2916 ret = changeset.bytes_changed;
2901out: 2917out:
2902 ulist_release(&changeset.range_changed); 2918 extent_changeset_release(&changeset);
2903 return ret; 2919 return ret;
2904} 2920}
2905 2921
@@ -2999,8 +3015,7 @@ void btrfs_qgroup_check_reserved_leak(struct inode *inode)
2999 struct ulist_iterator iter; 3015 struct ulist_iterator iter;
3000 int ret; 3016 int ret;
3001 3017
3002 changeset.bytes_changed = 0; 3018 extent_changeset_init(&changeset);
3003 ulist_init(&changeset.range_changed);
3004 ret = clear_record_extent_bits(&BTRFS_I(inode)->io_tree, 0, (u64)-1, 3019 ret = clear_record_extent_bits(&BTRFS_I(inode)->io_tree, 0, (u64)-1,
3005 EXTENT_QGROUP_RESERVED, &changeset); 3020 EXTENT_QGROUP_RESERVED, &changeset);
3006 3021
@@ -3017,5 +3032,5 @@ void btrfs_qgroup_check_reserved_leak(struct inode *inode)
3017 changeset.bytes_changed); 3032 changeset.bytes_changed);
3018 3033
3019 } 3034 }
3020 ulist_release(&changeset.range_changed); 3035 extent_changeset_release(&changeset);
3021} 3036}
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h
index d11125d6afb9..99408e93eb0d 100644
--- a/fs/btrfs/qgroup.h
+++ b/fs/btrfs/qgroup.h
@@ -242,7 +242,8 @@ int btrfs_verify_qgroup_counts(struct btrfs_fs_info *fs_info, u64 qgroupid,
242#endif 242#endif
243 243
244/* New io_tree based accurate qgroup reserve API */ 244/* New io_tree based accurate qgroup reserve API */
245int btrfs_qgroup_reserve_data(struct inode *inode, u64 start, u64 len); 245int btrfs_qgroup_reserve_data(struct inode *inode,
246 struct extent_changeset **reserved, u64 start, u64 len);
246int btrfs_qgroup_release_data(struct inode *inode, u64 start, u64 len); 247int btrfs_qgroup_release_data(struct inode *inode, u64 start, u64 len);
247int btrfs_qgroup_free_data(struct inode *inode, u64 start, u64 len); 248int btrfs_qgroup_free_data(struct inode *inode, u64 start, u64 len);
248 249
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index b291d1bebb4c..6407423151ab 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -3093,11 +3093,12 @@ int prealloc_file_extent_cluster(struct inode *inode,
3093 u64 prealloc_start = cluster->start - offset; 3093 u64 prealloc_start = cluster->start - offset;
3094 u64 prealloc_end = cluster->end - offset; 3094 u64 prealloc_end = cluster->end - offset;
3095 u64 cur_offset; 3095 u64 cur_offset;
3096 struct extent_changeset *data_reserved = NULL;
3096 3097
3097 BUG_ON(cluster->start != cluster->boundary[0]); 3098 BUG_ON(cluster->start != cluster->boundary[0]);
3098 inode_lock(inode); 3099 inode_lock(inode);
3099 3100
3100 ret = btrfs_check_data_free_space(inode, prealloc_start, 3101 ret = btrfs_check_data_free_space(inode, &data_reserved, prealloc_start,
3101 prealloc_end + 1 - prealloc_start); 3102 prealloc_end + 1 - prealloc_start);
3102 if (ret) 3103 if (ret)
3103 goto out; 3104 goto out;
@@ -3129,6 +3130,7 @@ int prealloc_file_extent_cluster(struct inode *inode,
3129 prealloc_end + 1 - cur_offset); 3130 prealloc_end + 1 - cur_offset);
3130out: 3131out:
3131 inode_unlock(inode); 3132 inode_unlock(inode);
3133 extent_changeset_free(data_reserved);
3132 return ret; 3134 return ret;
3133} 3135}
3134 3136