aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2012-01-10 10:31:31 -0500
committerChris Mason <chris.mason@oracle.com>2012-01-16 15:29:43 -0500
commit8c2a3ca20f6233677ac3222c6506174010eb414f (patch)
tree88d1105c665d355b363929557ed0c5489795e348 /fs
parent90290e19820e3323ce6b9c2888eeb68bf29c278b (diff)
Btrfs: space leak tracepoints
This in addition to a script in my btrfs-tracing tree will help track down space leaks when we're getting space left over in block groups on umount. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/delayed-inode.c45
-rw-r--r--fs/btrfs/extent-tree.c58
-rw-r--r--fs/btrfs/inode-map.c4
-rw-r--r--fs/btrfs/transaction.c2
4 files changed, 89 insertions, 20 deletions
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
index 9c1eccc2c503..fe4cd0f1cef1 100644
--- a/fs/btrfs/delayed-inode.c
+++ b/fs/btrfs/delayed-inode.c
@@ -595,8 +595,12 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans,
595 595
596 num_bytes = btrfs_calc_trans_metadata_size(root, 1); 596 num_bytes = btrfs_calc_trans_metadata_size(root, 1);
597 ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); 597 ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes);
598 if (!ret) 598 if (!ret) {
599 trace_btrfs_space_reservation(root->fs_info, "delayed_item",
600 item->key.objectid,
601 num_bytes, 1);
599 item->bytes_reserved = num_bytes; 602 item->bytes_reserved = num_bytes;
603 }
600 604
601 return ret; 605 return ret;
602} 606}
@@ -610,6 +614,9 @@ static void btrfs_delayed_item_release_metadata(struct btrfs_root *root,
610 return; 614 return;
611 615
612 rsv = &root->fs_info->delayed_block_rsv; 616 rsv = &root->fs_info->delayed_block_rsv;
617 trace_btrfs_space_reservation(root->fs_info, "delayed_item",
618 item->key.objectid, item->bytes_reserved,
619 0);
613 btrfs_block_rsv_release(root, rsv, 620 btrfs_block_rsv_release(root, rsv,
614 item->bytes_reserved); 621 item->bytes_reserved);
615} 622}
@@ -624,7 +631,7 @@ static int btrfs_delayed_inode_reserve_metadata(
624 struct btrfs_block_rsv *dst_rsv; 631 struct btrfs_block_rsv *dst_rsv;
625 u64 num_bytes; 632 u64 num_bytes;
626 int ret; 633 int ret;
627 int release = false; 634 bool release = false;
628 635
629 src_rsv = trans->block_rsv; 636 src_rsv = trans->block_rsv;
630 dst_rsv = &root->fs_info->delayed_block_rsv; 637 dst_rsv = &root->fs_info->delayed_block_rsv;
@@ -651,8 +658,13 @@ static int btrfs_delayed_inode_reserve_metadata(
651 */ 658 */
652 if (ret == -EAGAIN) 659 if (ret == -EAGAIN)
653 ret = -ENOSPC; 660 ret = -ENOSPC;
654 if (!ret) 661 if (!ret) {
655 node->bytes_reserved = num_bytes; 662 node->bytes_reserved = num_bytes;
663 trace_btrfs_space_reservation(root->fs_info,
664 "delayed_inode",
665 btrfs_ino(inode),
666 num_bytes, 1);
667 }
656 return ret; 668 return ret;
657 } else if (src_rsv == &root->fs_info->delalloc_block_rsv) { 669 } else if (src_rsv == &root->fs_info->delalloc_block_rsv) {
658 spin_lock(&BTRFS_I(inode)->lock); 670 spin_lock(&BTRFS_I(inode)->lock);
@@ -707,11 +719,17 @@ out:
707 * reservation here. I think it may be time for a documentation page on 719 * reservation here. I think it may be time for a documentation page on
708 * how block rsvs. work. 720 * how block rsvs. work.
709 */ 721 */
710 if (!ret) 722 if (!ret) {
723 trace_btrfs_space_reservation(root->fs_info, "delayed_inode",
724 btrfs_ino(inode), num_bytes, 1);
711 node->bytes_reserved = num_bytes; 725 node->bytes_reserved = num_bytes;
726 }
712 727
713 if (release) 728 if (release) {
729 trace_btrfs_space_reservation(root->fs_info, "delalloc",
730 btrfs_ino(inode), num_bytes, 0);
714 btrfs_block_rsv_release(root, src_rsv, num_bytes); 731 btrfs_block_rsv_release(root, src_rsv, num_bytes);
732 }
715 733
716 return ret; 734 return ret;
717} 735}
@@ -725,6 +743,8 @@ static void btrfs_delayed_inode_release_metadata(struct btrfs_root *root,
725 return; 743 return;
726 744
727 rsv = &root->fs_info->delayed_block_rsv; 745 rsv = &root->fs_info->delayed_block_rsv;
746 trace_btrfs_space_reservation(root->fs_info, "delayed_inode",
747 node->inode_id, node->bytes_reserved, 0);
728 btrfs_block_rsv_release(root, rsv, 748 btrfs_block_rsv_release(root, rsv,
729 node->bytes_reserved); 749 node->bytes_reserved);
730 node->bytes_reserved = 0; 750 node->bytes_reserved = 0;
@@ -1372,13 +1392,6 @@ int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans,
1372 goto release_node; 1392 goto release_node;
1373 } 1393 }
1374 1394
1375 ret = btrfs_delayed_item_reserve_metadata(trans, root, delayed_item);
1376 /*
1377 * we have reserved enough space when we start a new transaction,
1378 * so reserving metadata failure is impossible
1379 */
1380 BUG_ON(ret);
1381
1382 delayed_item->key.objectid = btrfs_ino(dir); 1395 delayed_item->key.objectid = btrfs_ino(dir);
1383 btrfs_set_key_type(&delayed_item->key, BTRFS_DIR_INDEX_KEY); 1396 btrfs_set_key_type(&delayed_item->key, BTRFS_DIR_INDEX_KEY);
1384 delayed_item->key.offset = index; 1397 delayed_item->key.offset = index;
@@ -1391,6 +1404,14 @@ int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans,
1391 dir_item->type = type; 1404 dir_item->type = type;
1392 memcpy((char *)(dir_item + 1), name, name_len); 1405 memcpy((char *)(dir_item + 1), name, name_len);
1393 1406
1407 ret = btrfs_delayed_item_reserve_metadata(trans, root, delayed_item);
1408 /*
1409 * we have reserved enough space when we start a new transaction,
1410 * so reserving metadata failure is impossible
1411 */
1412 BUG_ON(ret);
1413
1414
1394 mutex_lock(&delayed_node->mutex); 1415 mutex_lock(&delayed_node->mutex);
1395 ret = __btrfs_add_delayed_insertion_item(delayed_node, delayed_item); 1416 ret = __btrfs_add_delayed_insertion_item(delayed_node, delayed_item);
1396 if (unlikely(ret)) { 1417 if (unlikely(ret)) {
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index ad1a20bc834d..556f9aa25bb7 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3310,6 +3310,8 @@ commit_trans:
3310 return -ENOSPC; 3310 return -ENOSPC;
3311 } 3311 }
3312 data_sinfo->bytes_may_use += bytes; 3312 data_sinfo->bytes_may_use += bytes;
3313 trace_btrfs_space_reservation(root->fs_info, "space_info",
3314 (u64)data_sinfo, bytes, 1);
3313 spin_unlock(&data_sinfo->lock); 3315 spin_unlock(&data_sinfo->lock);
3314 3316
3315 return 0; 3317 return 0;
@@ -3329,6 +3331,8 @@ void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes)
3329 data_sinfo = BTRFS_I(inode)->space_info; 3331 data_sinfo = BTRFS_I(inode)->space_info;
3330 spin_lock(&data_sinfo->lock); 3332 spin_lock(&data_sinfo->lock);
3331 data_sinfo->bytes_may_use -= bytes; 3333 data_sinfo->bytes_may_use -= bytes;
3334 trace_btrfs_space_reservation(root->fs_info, "space_info",
3335 (u64)data_sinfo, bytes, 0);
3332 spin_unlock(&data_sinfo->lock); 3336 spin_unlock(&data_sinfo->lock);
3333} 3337}
3334 3338
@@ -3686,6 +3690,10 @@ again:
3686 if (used <= space_info->total_bytes) { 3690 if (used <= space_info->total_bytes) {
3687 if (used + orig_bytes <= space_info->total_bytes) { 3691 if (used + orig_bytes <= space_info->total_bytes) {
3688 space_info->bytes_may_use += orig_bytes; 3692 space_info->bytes_may_use += orig_bytes;
3693 trace_btrfs_space_reservation(root->fs_info,
3694 "space_info",
3695 (u64)space_info,
3696 orig_bytes, 1);
3689 ret = 0; 3697 ret = 0;
3690 } else { 3698 } else {
3691 /* 3699 /*
@@ -3753,6 +3761,10 @@ again:
3753 3761
3754 if (used + num_bytes < space_info->total_bytes + avail) { 3762 if (used + num_bytes < space_info->total_bytes + avail) {
3755 space_info->bytes_may_use += orig_bytes; 3763 space_info->bytes_may_use += orig_bytes;
3764 trace_btrfs_space_reservation(root->fs_info,
3765 "space_info",
3766 (u64)space_info,
3767 orig_bytes, 1);
3756 ret = 0; 3768 ret = 0;
3757 } else { 3769 } else {
3758 wait_ordered = true; 3770 wait_ordered = true;
@@ -3859,7 +3871,8 @@ static void block_rsv_add_bytes(struct btrfs_block_rsv *block_rsv,
3859 spin_unlock(&block_rsv->lock); 3871 spin_unlock(&block_rsv->lock);
3860} 3872}
3861 3873
3862static void block_rsv_release_bytes(struct btrfs_block_rsv *block_rsv, 3874static void block_rsv_release_bytes(struct btrfs_fs_info *fs_info,
3875 struct btrfs_block_rsv *block_rsv,
3863 struct btrfs_block_rsv *dest, u64 num_bytes) 3876 struct btrfs_block_rsv *dest, u64 num_bytes)
3864{ 3877{
3865 struct btrfs_space_info *space_info = block_rsv->space_info; 3878 struct btrfs_space_info *space_info = block_rsv->space_info;
@@ -3895,6 +3908,9 @@ static void block_rsv_release_bytes(struct btrfs_block_rsv *block_rsv,
3895 if (num_bytes) { 3908 if (num_bytes) {
3896 spin_lock(&space_info->lock); 3909 spin_lock(&space_info->lock);
3897 space_info->bytes_may_use -= num_bytes; 3910 space_info->bytes_may_use -= num_bytes;
3911 trace_btrfs_space_reservation(fs_info, "space_info",
3912 (u64)space_info,
3913 num_bytes, 0);
3898 space_info->reservation_progress++; 3914 space_info->reservation_progress++;
3899 spin_unlock(&space_info->lock); 3915 spin_unlock(&space_info->lock);
3900 } 3916 }
@@ -4051,7 +4067,8 @@ void btrfs_block_rsv_release(struct btrfs_root *root,
4051 if (global_rsv->full || global_rsv == block_rsv || 4067 if (global_rsv->full || global_rsv == block_rsv ||
4052 block_rsv->space_info != global_rsv->space_info) 4068 block_rsv->space_info != global_rsv->space_info)
4053 global_rsv = NULL; 4069 global_rsv = NULL;
4054 block_rsv_release_bytes(block_rsv, global_rsv, num_bytes); 4070 block_rsv_release_bytes(root->fs_info, block_rsv, global_rsv,
4071 num_bytes);
4055} 4072}
4056 4073
4057/* 4074/*
@@ -4110,11 +4127,15 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info)
4110 num_bytes = sinfo->total_bytes - num_bytes; 4127 num_bytes = sinfo->total_bytes - num_bytes;
4111 block_rsv->reserved += num_bytes; 4128 block_rsv->reserved += num_bytes;
4112 sinfo->bytes_may_use += num_bytes; 4129 sinfo->bytes_may_use += num_bytes;
4130 trace_btrfs_space_reservation(fs_info, "space_info",
4131 (u64)sinfo, num_bytes, 1);
4113 } 4132 }
4114 4133
4115 if (block_rsv->reserved >= block_rsv->size) { 4134 if (block_rsv->reserved >= block_rsv->size) {
4116 num_bytes = block_rsv->reserved - block_rsv->size; 4135 num_bytes = block_rsv->reserved - block_rsv->size;
4117 sinfo->bytes_may_use -= num_bytes; 4136 sinfo->bytes_may_use -= num_bytes;
4137 trace_btrfs_space_reservation(fs_info, "space_info",
4138 (u64)sinfo, num_bytes, 0);
4118 sinfo->reservation_progress++; 4139 sinfo->reservation_progress++;
4119 block_rsv->reserved = block_rsv->size; 4140 block_rsv->reserved = block_rsv->size;
4120 block_rsv->full = 1; 4141 block_rsv->full = 1;
@@ -4149,7 +4170,8 @@ static void init_global_block_rsv(struct btrfs_fs_info *fs_info)
4149 4170
4150static void release_global_block_rsv(struct btrfs_fs_info *fs_info) 4171static void release_global_block_rsv(struct btrfs_fs_info *fs_info)
4151{ 4172{
4152 block_rsv_release_bytes(&fs_info->global_block_rsv, NULL, (u64)-1); 4173 block_rsv_release_bytes(fs_info, &fs_info->global_block_rsv, NULL,
4174 (u64)-1);
4153 WARN_ON(fs_info->delalloc_block_rsv.size > 0); 4175 WARN_ON(fs_info->delalloc_block_rsv.size > 0);
4154 WARN_ON(fs_info->delalloc_block_rsv.reserved > 0); 4176 WARN_ON(fs_info->delalloc_block_rsv.reserved > 0);
4155 WARN_ON(fs_info->trans_block_rsv.size > 0); 4177 WARN_ON(fs_info->trans_block_rsv.size > 0);
@@ -4166,6 +4188,8 @@ void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans,
4166 if (!trans->bytes_reserved) 4188 if (!trans->bytes_reserved)
4167 return; 4189 return;
4168 4190
4191 trace_btrfs_space_reservation(root->fs_info, "transaction", (u64)trans,
4192 trans->bytes_reserved, 0);
4169 btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved); 4193 btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved);
4170 trans->bytes_reserved = 0; 4194 trans->bytes_reserved = 0;
4171} 4195}
@@ -4183,6 +4207,8 @@ int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans,
4183 * when we are truly done with the orphan item. 4207 * when we are truly done with the orphan item.
4184 */ 4208 */
4185 u64 num_bytes = btrfs_calc_trans_metadata_size(root, 1); 4209 u64 num_bytes = btrfs_calc_trans_metadata_size(root, 1);
4210 trace_btrfs_space_reservation(root->fs_info, "orphan",
4211 btrfs_ino(inode), num_bytes, 1);
4186 return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes); 4212 return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes);
4187} 4213}
4188 4214
@@ -4190,6 +4216,8 @@ void btrfs_orphan_release_metadata(struct inode *inode)
4190{ 4216{
4191 struct btrfs_root *root = BTRFS_I(inode)->root; 4217 struct btrfs_root *root = BTRFS_I(inode)->root;
4192 u64 num_bytes = btrfs_calc_trans_metadata_size(root, 1); 4218 u64 num_bytes = btrfs_calc_trans_metadata_size(root, 1);
4219 trace_btrfs_space_reservation(root->fs_info, "orphan",
4220 btrfs_ino(inode), num_bytes, 0);
4193 btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes); 4221 btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes);
4194} 4222}
4195 4223
@@ -4370,8 +4398,13 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
4370 if (dropped) 4398 if (dropped)
4371 to_free += btrfs_calc_trans_metadata_size(root, dropped); 4399 to_free += btrfs_calc_trans_metadata_size(root, dropped);
4372 4400
4373 if (to_free) 4401 if (to_free) {
4374 btrfs_block_rsv_release(root, block_rsv, to_free); 4402 btrfs_block_rsv_release(root, block_rsv, to_free);
4403 trace_btrfs_space_reservation(root->fs_info,
4404 "delalloc",
4405 btrfs_ino(inode),
4406 to_free, 0);
4407 }
4375 return ret; 4408 return ret;
4376 } 4409 }
4377 4410
@@ -4383,6 +4416,9 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
4383 BTRFS_I(inode)->reserved_extents += nr_extents; 4416 BTRFS_I(inode)->reserved_extents += nr_extents;
4384 spin_unlock(&BTRFS_I(inode)->lock); 4417 spin_unlock(&BTRFS_I(inode)->lock);
4385 4418
4419 if (to_reserve)
4420 trace_btrfs_space_reservation(root->fs_info,"delalloc",
4421 btrfs_ino(inode), to_reserve, 1);
4386 block_rsv_add_bytes(block_rsv, to_reserve, 1); 4422 block_rsv_add_bytes(block_rsv, to_reserve, 1);
4387 4423
4388 return 0; 4424 return 0;
@@ -4412,6 +4448,8 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)
4412 if (dropped > 0) 4448 if (dropped > 0)
4413 to_free += btrfs_calc_trans_metadata_size(root, dropped); 4449 to_free += btrfs_calc_trans_metadata_size(root, dropped);
4414 4450
4451 trace_btrfs_space_reservation(root->fs_info, "delalloc",
4452 btrfs_ino(inode), to_free, 0);
4415 btrfs_block_rsv_release(root, &root->fs_info->delalloc_block_rsv, 4453 btrfs_block_rsv_release(root, &root->fs_info->delalloc_block_rsv,
4416 to_free); 4454 to_free);
4417} 4455}
@@ -4666,7 +4704,10 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
4666 cache->reserved += num_bytes; 4704 cache->reserved += num_bytes;
4667 space_info->bytes_reserved += num_bytes; 4705 space_info->bytes_reserved += num_bytes;
4668 if (reserve == RESERVE_ALLOC) { 4706 if (reserve == RESERVE_ALLOC) {
4669 BUG_ON(space_info->bytes_may_use < num_bytes); 4707 trace_btrfs_space_reservation(cache->fs_info,
4708 "space_info",
4709 (u64)space_info,
4710 num_bytes, 0);
4670 space_info->bytes_may_use -= num_bytes; 4711 space_info->bytes_may_use -= num_bytes;
4671 } 4712 }
4672 } 4713 }
@@ -6126,10 +6167,11 @@ use_block_rsv(struct btrfs_trans_handle *trans,
6126 return ERR_PTR(-ENOSPC); 6167 return ERR_PTR(-ENOSPC);
6127} 6168}
6128 6169
6129static void unuse_block_rsv(struct btrfs_block_rsv *block_rsv, u32 blocksize) 6170static void unuse_block_rsv(struct btrfs_fs_info *fs_info,
6171 struct btrfs_block_rsv *block_rsv, u32 blocksize)
6130{ 6172{
6131 block_rsv_add_bytes(block_rsv, blocksize, 0); 6173 block_rsv_add_bytes(block_rsv, blocksize, 0);
6132 block_rsv_release_bytes(block_rsv, NULL, 0); 6174 block_rsv_release_bytes(fs_info, block_rsv, NULL, 0);
6133} 6175}
6134 6176
6135/* 6177/*
@@ -6159,7 +6201,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
6159 ret = btrfs_reserve_extent(trans, root, blocksize, blocksize, 6201 ret = btrfs_reserve_extent(trans, root, blocksize, blocksize,
6160 empty_size, hint, (u64)-1, &ins, 0); 6202 empty_size, hint, (u64)-1, &ins, 0);
6161 if (ret) { 6203 if (ret) {
6162 unuse_block_rsv(block_rsv, blocksize); 6204 unuse_block_rsv(root->fs_info, block_rsv, blocksize);
6163 return ERR_PTR(ret); 6205 return ERR_PTR(ret);
6164 } 6206 }
6165 6207
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
index f8962a957d65..213ffa86ce1b 100644
--- a/fs/btrfs/inode-map.c
+++ b/fs/btrfs/inode-map.c
@@ -438,6 +438,8 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
438 trans->bytes_reserved); 438 trans->bytes_reserved);
439 if (ret) 439 if (ret)
440 goto out; 440 goto out;
441 trace_btrfs_space_reservation(root->fs_info, "ino_cache", (u64)trans,
442 trans->bytes_reserved, 1);
441again: 443again:
442 inode = lookup_free_ino_inode(root, path); 444 inode = lookup_free_ino_inode(root, path);
443 if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) { 445 if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) {
@@ -498,6 +500,8 @@ again:
498out_put: 500out_put:
499 iput(inode); 501 iput(inode);
500out_release: 502out_release:
503 trace_btrfs_space_reservation(root->fs_info, "ino_cache", (u64)trans,
504 trans->bytes_reserved, 0);
501 btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved); 505 btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved);
502out: 506out:
503 trans->block_rsv = rsv; 507 trans->block_rsv = rsv;
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index d5f987b49d70..287a6728b1ad 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -326,6 +326,8 @@ again:
326 } 326 }
327 327
328 if (num_bytes) { 328 if (num_bytes) {
329 trace_btrfs_space_reservation(root->fs_info, "transaction",
330 (u64)h, num_bytes, 1);
329 h->block_rsv = &root->fs_info->trans_block_rsv; 331 h->block_rsv = &root->fs_info->trans_block_rsv;
330 h->bytes_reserved = num_bytes; 332 h->bytes_reserved = num_bytes;
331 } 333 }