diff options
author | Chris Mason <chris.mason@fusionio.com> | 2012-07-25 16:11:38 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2012-07-25 16:11:38 -0400 |
commit | b478b2baa37ac99fc04a30809c780dd5dfd43595 (patch) | |
tree | bed7af1466e5b1e0b0501eba18f77c804a864d7d /fs/btrfs/transaction.c | |
parent | 67c9684f48ea9cbc5e9b8a1feb3151800e9dcc22 (diff) | |
parent | 6f72c7e20dbaea55f04546de69586c84a3654503 (diff) |
Merge branch 'qgroup' of git://git.jan-o-sch.net/btrfs-unstable into for-linus
Conflicts:
fs/btrfs/ioctl.c
fs/btrfs/ioctl.h
fs/btrfs/transaction.c
fs/btrfs/transaction.h
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 59 |
1 files changed, 55 insertions, 4 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 328b95f67660..cc20e95ea289 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -38,7 +38,6 @@ void put_transaction(struct btrfs_transaction *transaction) | |||
38 | if (atomic_dec_and_test(&transaction->use_count)) { | 38 | if (atomic_dec_and_test(&transaction->use_count)) { |
39 | BUG_ON(!list_empty(&transaction->list)); | 39 | BUG_ON(!list_empty(&transaction->list)); |
40 | WARN_ON(transaction->delayed_refs.root.rb_node); | 40 | WARN_ON(transaction->delayed_refs.root.rb_node); |
41 | WARN_ON(!list_empty(&transaction->delayed_refs.seq_head)); | ||
42 | memset(transaction, 0, sizeof(*transaction)); | 41 | memset(transaction, 0, sizeof(*transaction)); |
43 | kmem_cache_free(btrfs_transaction_cachep, transaction); | 42 | kmem_cache_free(btrfs_transaction_cachep, transaction); |
44 | } | 43 | } |
@@ -126,7 +125,6 @@ loop: | |||
126 | cur_trans->delayed_refs.num_heads = 0; | 125 | cur_trans->delayed_refs.num_heads = 0; |
127 | cur_trans->delayed_refs.flushing = 0; | 126 | cur_trans->delayed_refs.flushing = 0; |
128 | cur_trans->delayed_refs.run_delayed_start = 0; | 127 | cur_trans->delayed_refs.run_delayed_start = 0; |
129 | cur_trans->delayed_refs.seq = 1; | ||
130 | 128 | ||
131 | /* | 129 | /* |
132 | * although the tree mod log is per file system and not per transaction, | 130 | * although the tree mod log is per file system and not per transaction, |
@@ -145,10 +143,8 @@ loop: | |||
145 | } | 143 | } |
146 | atomic_set(&fs_info->tree_mod_seq, 0); | 144 | atomic_set(&fs_info->tree_mod_seq, 0); |
147 | 145 | ||
148 | init_waitqueue_head(&cur_trans->delayed_refs.seq_wait); | ||
149 | spin_lock_init(&cur_trans->commit_lock); | 146 | spin_lock_init(&cur_trans->commit_lock); |
150 | spin_lock_init(&cur_trans->delayed_refs.lock); | 147 | spin_lock_init(&cur_trans->delayed_refs.lock); |
151 | INIT_LIST_HEAD(&cur_trans->delayed_refs.seq_head); | ||
152 | 148 | ||
153 | INIT_LIST_HEAD(&cur_trans->pending_snapshots); | 149 | INIT_LIST_HEAD(&cur_trans->pending_snapshots); |
154 | list_add_tail(&cur_trans->list, &fs_info->trans_list); | 150 | list_add_tail(&cur_trans->list, &fs_info->trans_list); |
@@ -299,6 +295,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, | |||
299 | struct btrfs_transaction *cur_trans; | 295 | struct btrfs_transaction *cur_trans; |
300 | u64 num_bytes = 0; | 296 | u64 num_bytes = 0; |
301 | int ret; | 297 | int ret; |
298 | u64 qgroup_reserved = 0; | ||
302 | 299 | ||
303 | if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) | 300 | if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) |
304 | return ERR_PTR(-EROFS); | 301 | return ERR_PTR(-EROFS); |
@@ -317,6 +314,14 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, | |||
317 | * the appropriate flushing if need be. | 314 | * the appropriate flushing if need be. |
318 | */ | 315 | */ |
319 | 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 | |||
320 | num_bytes = btrfs_calc_trans_metadata_size(root, num_items); | 325 | num_bytes = btrfs_calc_trans_metadata_size(root, num_items); |
321 | ret = btrfs_block_rsv_add(root, | 326 | ret = btrfs_block_rsv_add(root, |
322 | &root->fs_info->trans_block_rsv, | 327 | &root->fs_info->trans_block_rsv, |
@@ -349,12 +354,16 @@ again: | |||
349 | h->transaction = cur_trans; | 354 | h->transaction = cur_trans; |
350 | h->blocks_used = 0; | 355 | h->blocks_used = 0; |
351 | h->bytes_reserved = 0; | 356 | h->bytes_reserved = 0; |
357 | h->root = root; | ||
352 | h->delayed_ref_updates = 0; | 358 | h->delayed_ref_updates = 0; |
353 | h->use_count = 1; | 359 | h->use_count = 1; |
354 | h->adding_csums = 0; | 360 | h->adding_csums = 0; |
355 | h->block_rsv = NULL; | 361 | h->block_rsv = NULL; |
356 | h->orig_rsv = NULL; | 362 | h->orig_rsv = NULL; |
357 | h->aborted = 0; | 363 | h->aborted = 0; |
364 | h->qgroup_reserved = qgroup_reserved; | ||
365 | h->delayed_ref_elem.seq = 0; | ||
366 | INIT_LIST_HEAD(&h->qgroup_ref_list); | ||
358 | 367 | ||
359 | smp_mb(); | 368 | smp_mb(); |
360 | if (cur_trans->blocked && may_wait_transaction(root, type)) { | 369 | if (cur_trans->blocked && may_wait_transaction(root, type)) { |
@@ -505,6 +514,24 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
505 | return 0; | 514 | return 0; |
506 | } | 515 | } |
507 | 516 | ||
517 | /* | ||
518 | * do the qgroup accounting as early as possible | ||
519 | */ | ||
520 | err = btrfs_delayed_refs_qgroup_accounting(trans, info); | ||
521 | |||
522 | btrfs_trans_release_metadata(trans, root); | ||
523 | trans->block_rsv = NULL; | ||
524 | /* | ||
525 | * the same root has to be passed to start_transaction and | ||
526 | * end_transaction. Subvolume quota depends on this. | ||
527 | */ | ||
528 | WARN_ON(trans->root != root); | ||
529 | |||
530 | if (trans->qgroup_reserved) { | ||
531 | btrfs_qgroup_free(root, trans->qgroup_reserved); | ||
532 | trans->qgroup_reserved = 0; | ||
533 | } | ||
534 | |||
508 | while (count < 2) { | 535 | while (count < 2) { |
509 | unsigned long cur = trans->delayed_ref_updates; | 536 | unsigned long cur = trans->delayed_ref_updates; |
510 | trans->delayed_ref_updates = 0; | 537 | trans->delayed_ref_updates = 0; |
@@ -559,6 +586,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
559 | root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { | 586 | root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { |
560 | err = -EIO; | 587 | err = -EIO; |
561 | } | 588 | } |
589 | assert_qgroups_uptodate(trans); | ||
562 | 590 | ||
563 | memset(trans, 0, sizeof(*trans)); | 591 | memset(trans, 0, sizeof(*trans)); |
564 | kmem_cache_free(btrfs_trans_handle_cachep, trans); | 592 | kmem_cache_free(btrfs_trans_handle_cachep, trans); |
@@ -777,6 +805,13 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
777 | ret = btrfs_run_dev_stats(trans, root->fs_info); | 805 | ret = btrfs_run_dev_stats(trans, root->fs_info); |
778 | BUG_ON(ret); | 806 | BUG_ON(ret); |
779 | 807 | ||
808 | ret = btrfs_run_qgroups(trans, root->fs_info); | ||
809 | BUG_ON(ret); | ||
810 | |||
811 | /* run_qgroups might have added some more refs */ | ||
812 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | ||
813 | BUG_ON(ret); | ||
814 | |||
780 | while (!list_empty(&fs_info->dirty_cowonly_roots)) { | 815 | while (!list_empty(&fs_info->dirty_cowonly_roots)) { |
781 | next = fs_info->dirty_cowonly_roots.next; | 816 | next = fs_info->dirty_cowonly_roots.next; |
782 | list_del_init(next); | 817 | list_del_init(next); |
@@ -949,6 +984,14 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
949 | } | 984 | } |
950 | } | 985 | } |
951 | 986 | ||
987 | ret = btrfs_qgroup_inherit(trans, fs_info, root->root_key.objectid, | ||
988 | objectid, pending->inherit); | ||
989 | kfree(pending->inherit); | ||
990 | if (ret) { | ||
991 | pending->error = ret; | ||
992 | goto fail; | ||
993 | } | ||
994 | |||
952 | key.objectid = objectid; | 995 | key.objectid = objectid; |
953 | key.offset = (u64)-1; | 996 | key.offset = (u64)-1; |
954 | key.type = BTRFS_ROOT_ITEM_KEY; | 997 | key.type = BTRFS_ROOT_ITEM_KEY; |
@@ -1345,6 +1388,13 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1345 | goto cleanup_transaction; | 1388 | goto cleanup_transaction; |
1346 | 1389 | ||
1347 | /* | 1390 | /* |
1391 | * running the delayed items may have added new refs. account | ||
1392 | * them now so that they hinder processing of more delayed refs | ||
1393 | * as little as possible. | ||
1394 | */ | ||
1395 | btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info); | ||
1396 | |||
1397 | /* | ||
1348 | * rename don't use btrfs_join_transaction, so, once we | 1398 | * rename don't use btrfs_join_transaction, so, once we |
1349 | * set the transaction to blocked above, we aren't going | 1399 | * set the transaction to blocked above, we aren't going |
1350 | * to get any new ordered operations. We can safely run | 1400 | * to get any new ordered operations. We can safely run |
@@ -1456,6 +1506,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1456 | root->fs_info->chunk_root->node); | 1506 | root->fs_info->chunk_root->node); |
1457 | switch_commit_root(root->fs_info->chunk_root); | 1507 | switch_commit_root(root->fs_info->chunk_root); |
1458 | 1508 | ||
1509 | assert_qgroups_uptodate(trans); | ||
1459 | update_super_roots(root); | 1510 | update_super_roots(root); |
1460 | 1511 | ||
1461 | if (!root->fs_info->log_root_recovering) { | 1512 | if (!root->fs_info->log_root_recovering) { |