aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
authorArne Jansen <sensille@gmx.net>2011-09-14 09:44:05 -0400
committerJan Schmidt <list.btrfs@jan-o-sch.net>2012-07-12 04:54:39 -0400
commitc556723794b3487a79de1ecd6354975b1389f5ff (patch)
tree99b363645203df002ab421bbd7be3b56dbd1e6ef /fs/btrfs/transaction.c
parent546adb0d817c34dc2be3a7cb5bba8771f837a562 (diff)
Btrfs: hooks to reserve qgroup space
Like block reserves, reserve a small piece of space on each transaction start and for delalloc. These are the hooks that can actually return EDQUOT to the user. The amount of space reserved is tracked in the transaction handle. Signed-off-by: Arne Jansen <sensille@gmx.net>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c16
1 files changed, 16 insertions, 0 deletions
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;