aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/extent-tree.c12
-rw-r--r--fs/btrfs/transaction.c16
-rw-r--r--fs/btrfs/transaction.h1
3 files changed, 29 insertions, 0 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index c08337a83ace..2ce16f97730a 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4565,6 +4565,13 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
4565 csum_bytes = BTRFS_I(inode)->csum_bytes; 4565 csum_bytes = BTRFS_I(inode)->csum_bytes;
4566 spin_unlock(&BTRFS_I(inode)->lock); 4566 spin_unlock(&BTRFS_I(inode)->lock);
4567 4567
4568 if (root->fs_info->quota_enabled) {
4569 ret = btrfs_qgroup_reserve(root, num_bytes +
4570 nr_extents * root->leafsize);
4571 if (ret)
4572 return ret;
4573 }
4574
4568 ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush); 4575 ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush);
4569 if (ret) { 4576 if (ret) {
4570 u64 to_free = 0; 4577 u64 to_free = 0;
@@ -4643,6 +4650,11 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)
4643 4650
4644 trace_btrfs_space_reservation(root->fs_info, "delalloc", 4651 trace_btrfs_space_reservation(root->fs_info, "delalloc",
4645 btrfs_ino(inode), to_free, 0); 4652 btrfs_ino(inode), to_free, 0);
4653 if (root->fs_info->quota_enabled) {
4654 btrfs_qgroup_free(root, num_bytes +
4655 dropped * root->leafsize);
4656 }
4657
4646 btrfs_block_rsv_release(root, &root->fs_info->delalloc_block_rsv, 4658 btrfs_block_rsv_release(root, &root->fs_info->delalloc_block_rsv,
4647 to_free); 4659 to_free);
4648} 4660}
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 21c768cb443f..f1e29fbd5317 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -295,6 +295,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
295 struct btrfs_transaction *cur_trans; 295 struct btrfs_transaction *cur_trans;
296 u64 num_bytes = 0; 296 u64 num_bytes = 0;
297 int ret; 297 int ret;
298 u64 qgroup_reserved = 0;
298 299
299 if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) 300 if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)
300 return ERR_PTR(-EROFS); 301 return ERR_PTR(-EROFS);
@@ -313,6 +314,14 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
313 * the appropriate flushing if need be. 314 * the appropriate flushing if need be.
314 */ 315 */
315 if (num_items > 0 && root != root->fs_info->chunk_root) { 316 if (num_items > 0 && root != root->fs_info->chunk_root) {
317 if (root->fs_info->quota_enabled &&
318 is_fstree(root->root_key.objectid)) {
319 qgroup_reserved = num_items * root->leafsize;
320 ret = btrfs_qgroup_reserve(root, qgroup_reserved);
321 if (ret)
322 return ERR_PTR(ret);
323 }
324
316 num_bytes = btrfs_calc_trans_metadata_size(root, num_items); 325 num_bytes = btrfs_calc_trans_metadata_size(root, num_items);
317 ret = btrfs_block_rsv_add(root, 326 ret = btrfs_block_rsv_add(root,
318 &root->fs_info->trans_block_rsv, 327 &root->fs_info->trans_block_rsv,
@@ -351,6 +360,7 @@ again:
351 h->block_rsv = NULL; 360 h->block_rsv = NULL;
352 h->orig_rsv = NULL; 361 h->orig_rsv = NULL;
353 h->aborted = 0; 362 h->aborted = 0;
363 h->qgroup_reserved = qgroup_reserved;
354 h->delayed_ref_elem.seq = 0; 364 h->delayed_ref_elem.seq = 0;
355 INIT_LIST_HEAD(&h->qgroup_ref_list); 365 INIT_LIST_HEAD(&h->qgroup_ref_list);
356 366
@@ -524,6 +534,12 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
524 * end_transaction. Subvolume quota depends on this. 534 * end_transaction. Subvolume quota depends on this.
525 */ 535 */
526 WARN_ON(trans->root != root); 536 WARN_ON(trans->root != root);
537
538 if (trans->qgroup_reserved) {
539 btrfs_qgroup_free(root, trans->qgroup_reserved);
540 trans->qgroup_reserved = 0;
541 }
542
527 while (count < 2) { 543 while (count < 2) {
528 unsigned long cur = trans->delayed_ref_updates; 544 unsigned long cur = trans->delayed_ref_updates;
529 trans->delayed_ref_updates = 0; 545 trans->delayed_ref_updates = 0;
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
index 16ba00842c38..2759e0572c5c 100644
--- a/fs/btrfs/transaction.h
+++ b/fs/btrfs/transaction.h
@@ -50,6 +50,7 @@ struct btrfs_transaction {
50struct btrfs_trans_handle { 50struct btrfs_trans_handle {
51 u64 transid; 51 u64 transid;
52 u64 bytes_reserved; 52 u64 bytes_reserved;
53 u64 qgroup_reserved;
53 unsigned long use_count; 54 unsigned long use_count;
54 unsigned long blocks_reserved; 55 unsigned long blocks_reserved;
55 unsigned long blocks_used; 56 unsigned long blocks_used;