Commit 8c2a3ca20f6233677ac3222c6506174010eb414f

Authored by Josef Bacik
Committed by Chris Mason
1 parent 90290e1982

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>

Showing 5 changed files with 119 additions and 20 deletions Side-by-side Diff

fs/btrfs/delayed-inode.c
... ... @@ -595,8 +595,12 @@
595 595  
596 596 num_bytes = btrfs_calc_trans_metadata_size(root, 1);
597 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 602 item->bytes_reserved = num_bytes;
  603 + }
600 604  
601 605 return ret;
602 606 }
... ... @@ -610,6 +614,9 @@
610 614 return;
611 615  
612 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 620 btrfs_block_rsv_release(root, rsv,
614 621 item->bytes_reserved);
615 622 }
... ... @@ -624,7 +631,7 @@
624 631 struct btrfs_block_rsv *dst_rsv;
625 632 u64 num_bytes;
626 633 int ret;
627   - int release = false;
  634 + bool release = false;
628 635  
629 636 src_rsv = trans->block_rsv;
630 637 dst_rsv = &root->fs_info->delayed_block_rsv;
631 638  
... ... @@ -651,8 +658,13 @@
651 658 */
652 659 if (ret == -EAGAIN)
653 660 ret = -ENOSPC;
654   - if (!ret)
  661 + if (!ret) {
655 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 668 return ret;
657 669 } else if (src_rsv == &root->fs_info->delalloc_block_rsv) {
658 670 spin_lock(&BTRFS_I(inode)->lock);
659 671  
660 672  
661 673  
... ... @@ -707,11 +719,17 @@
707 719 * reservation here. I think it may be time for a documentation page on
708 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 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 731 btrfs_block_rsv_release(root, src_rsv, num_bytes);
  732 + }
715 733  
716 734 return ret;
717 735 }
... ... @@ -725,6 +743,8 @@
725 743 return;
726 744  
727 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 748 btrfs_block_rsv_release(root, rsv,
729 749 node->bytes_reserved);
730 750 node->bytes_reserved = 0;
... ... @@ -1372,13 +1392,6 @@
1372 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 1395 delayed_item->key.objectid = btrfs_ino(dir);
1383 1396 btrfs_set_key_type(&delayed_item->key, BTRFS_DIR_INDEX_KEY);
1384 1397 delayed_item->key.offset = index;
... ... @@ -1390,6 +1403,14 @@
1390 1403 dir_item->name_len = cpu_to_le16(name_len);
1391 1404 dir_item->type = type;
1392 1405 memcpy((char *)(dir_item + 1), name, name_len);
  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 +
1393 1414  
1394 1415 mutex_lock(&delayed_node->mutex);
1395 1416 ret = __btrfs_add_delayed_insertion_item(delayed_node, delayed_item);
fs/btrfs/extent-tree.c
... ... @@ -3310,6 +3310,8 @@
3310 3310 return -ENOSPC;
3311 3311 }
3312 3312 data_sinfo->bytes_may_use += bytes;
  3313 + trace_btrfs_space_reservation(root->fs_info, "space_info",
  3314 + (u64)data_sinfo, bytes, 1);
3313 3315 spin_unlock(&data_sinfo->lock);
3314 3316  
3315 3317 return 0;
... ... @@ -3329,6 +3331,8 @@
3329 3331 data_sinfo = BTRFS_I(inode)->space_info;
3330 3332 spin_lock(&data_sinfo->lock);
3331 3333 data_sinfo->bytes_may_use -= bytes;
  3334 + trace_btrfs_space_reservation(root->fs_info, "space_info",
  3335 + (u64)data_sinfo, bytes, 0);
3332 3336 spin_unlock(&data_sinfo->lock);
3333 3337 }
3334 3338  
... ... @@ -3686,6 +3690,10 @@
3686 3690 if (used <= space_info->total_bytes) {
3687 3691 if (used + orig_bytes <= space_info->total_bytes) {
3688 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 3697 ret = 0;
3690 3698 } else {
3691 3699 /*
... ... @@ -3753,6 +3761,10 @@
3753 3761  
3754 3762 if (used + num_bytes < space_info->total_bytes + avail) {
3755 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 3768 ret = 0;
3757 3769 } else {
3758 3770 wait_ordered = true;
... ... @@ -3859,7 +3871,8 @@
3859 3871 spin_unlock(&block_rsv->lock);
3860 3872 }
3861 3873  
3862   -static void block_rsv_release_bytes(struct btrfs_block_rsv *block_rsv,
  3874 +static void block_rsv_release_bytes(struct btrfs_fs_info *fs_info,
  3875 + struct btrfs_block_rsv *block_rsv,
3863 3876 struct btrfs_block_rsv *dest, u64 num_bytes)
3864 3877 {
3865 3878 struct btrfs_space_info *space_info = block_rsv->space_info;
... ... @@ -3895,6 +3908,9 @@
3895 3908 if (num_bytes) {
3896 3909 spin_lock(&space_info->lock);
3897 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 3914 space_info->reservation_progress++;
3899 3915 spin_unlock(&space_info->lock);
3900 3916 }
... ... @@ -4051,7 +4067,8 @@
4051 4067 if (global_rsv->full || global_rsv == block_rsv ||
4052 4068 block_rsv->space_info != global_rsv->space_info)
4053 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 /*
4058 4075  
... ... @@ -4110,11 +4127,15 @@
4110 4127 num_bytes = sinfo->total_bytes - num_bytes;
4111 4128 block_rsv->reserved += num_bytes;
4112 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 4134 if (block_rsv->reserved >= block_rsv->size) {
4116 4135 num_bytes = block_rsv->reserved - block_rsv->size;
4117 4136 sinfo->bytes_may_use -= num_bytes;
  4137 + trace_btrfs_space_reservation(fs_info, "space_info",
  4138 + (u64)sinfo, num_bytes, 0);
4118 4139 sinfo->reservation_progress++;
4119 4140 block_rsv->reserved = block_rsv->size;
4120 4141 block_rsv->full = 1;
... ... @@ -4149,7 +4170,8 @@
4149 4170  
4150 4171 static 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 4175 WARN_ON(fs_info->delalloc_block_rsv.size > 0);
4154 4176 WARN_ON(fs_info->delalloc_block_rsv.reserved > 0);
4155 4177 WARN_ON(fs_info->trans_block_rsv.size > 0);
... ... @@ -4166,6 +4188,8 @@
4166 4188 if (!trans->bytes_reserved)
4167 4189 return;
4168 4190  
  4191 + trace_btrfs_space_reservation(root->fs_info, "transaction", (u64)trans,
  4192 + trans->bytes_reserved, 0);
4169 4193 btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved);
4170 4194 trans->bytes_reserved = 0;
4171 4195 }
... ... @@ -4183,6 +4207,8 @@
4183 4207 * when we are truly done with the orphan item.
4184 4208 */
4185 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 4212 return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes);
4187 4213 }
4188 4214  
... ... @@ -4190,6 +4216,8 @@
4190 4216 {
4191 4217 struct btrfs_root *root = BTRFS_I(inode)->root;
4192 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 4221 btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes);
4194 4222 }
4195 4223  
4196 4224  
... ... @@ -4370,8 +4398,13 @@
4370 4398 if (dropped)
4371 4399 to_free += btrfs_calc_trans_metadata_size(root, dropped);
4372 4400  
4373   - if (to_free)
  4401 + if (to_free) {
4374 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 4408 return ret;
4376 4409 }
4377 4410  
... ... @@ -4383,6 +4416,9 @@
4383 4416 BTRFS_I(inode)->reserved_extents += nr_extents;
4384 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 4422 block_rsv_add_bytes(block_rsv, to_reserve, 1);
4387 4423  
4388 4424 return 0;
... ... @@ -4412,6 +4448,8 @@
4412 4448 if (dropped > 0)
4413 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 4453 btrfs_block_rsv_release(root, &root->fs_info->delalloc_block_rsv,
4416 4454 to_free);
4417 4455 }
... ... @@ -4666,7 +4704,10 @@
4666 4704 cache->reserved += num_bytes;
4667 4705 space_info->bytes_reserved += num_bytes;
4668 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 4711 space_info->bytes_may_use -= num_bytes;
4671 4712 }
4672 4713 }
4673 4714  
... ... @@ -6126,10 +6167,11 @@
6126 6167 return ERR_PTR(-ENOSPC);
6127 6168 }
6128 6169  
6129   -static void unuse_block_rsv(struct btrfs_block_rsv *block_rsv, u32 blocksize)
  6170 +static void unuse_block_rsv(struct btrfs_fs_info *fs_info,
  6171 + struct btrfs_block_rsv *block_rsv, u32 blocksize)
6130 6172 {
6131 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 @@
6159 6201 ret = btrfs_reserve_extent(trans, root, blocksize, blocksize,
6160 6202 empty_size, hint, (u64)-1, &ins, 0);
6161 6203 if (ret) {
6162   - unuse_block_rsv(block_rsv, blocksize);
  6204 + unuse_block_rsv(root->fs_info, block_rsv, blocksize);
6163 6205 return ERR_PTR(ret);
6164 6206 }
6165 6207  
fs/btrfs/inode-map.c
... ... @@ -438,6 +438,8 @@
438 438 trans->bytes_reserved);
439 439 if (ret)
440 440 goto out;
  441 + trace_btrfs_space_reservation(root->fs_info, "ino_cache", (u64)trans,
  442 + trans->bytes_reserved, 1);
441 443 again:
442 444 inode = lookup_free_ino_inode(root, path);
443 445 if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) {
... ... @@ -498,6 +500,8 @@
498 500 out_put:
499 501 iput(inode);
500 502 out_release:
  503 + trace_btrfs_space_reservation(root->fs_info, "ino_cache", (u64)trans,
  504 + trans->bytes_reserved, 0);
501 505 btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved);
502 506 out:
503 507 trans->block_rsv = rsv;
fs/btrfs/transaction.c
... ... @@ -326,6 +326,8 @@
326 326 }
327 327  
328 328 if (num_bytes) {
  329 + trace_btrfs_space_reservation(root->fs_info, "transaction",
  330 + (u64)h, num_bytes, 1);
329 331 h->block_rsv = &root->fs_info->trans_block_rsv;
330 332 h->bytes_reserved = num_bytes;
331 333 }
include/trace/events/btrfs.h
... ... @@ -55,6 +55,8 @@
55 55 { BTRFS_BLOCK_GROUP_DUP, "DUP"}, \
56 56 { BTRFS_BLOCK_GROUP_RAID10, "RAID10"}
57 57  
  58 +#define BTRFS_UUID_SIZE 16
  59 +
58 60 TRACE_EVENT(btrfs_transaction_commit,
59 61  
60 62 TP_PROTO(struct btrfs_root *root),
... ... @@ -630,6 +632,34 @@
630 632 __entry->buf_level,
631 633 (unsigned long long)__entry->cow_start,
632 634 __entry->cow_level)
  635 +);
  636 +
  637 +TRACE_EVENT(btrfs_space_reservation,
  638 +
  639 + TP_PROTO(struct btrfs_fs_info *fs_info, char *type, u64 val,
  640 + u64 bytes, int reserve),
  641 +
  642 + TP_ARGS(fs_info, type, val, bytes, reserve),
  643 +
  644 + TP_STRUCT__entry(
  645 + __array( u8, fsid, BTRFS_UUID_SIZE )
  646 + __string( type, type )
  647 + __field( u64, val )
  648 + __field( u64, bytes )
  649 + __field( int, reserve )
  650 + ),
  651 +
  652 + TP_fast_assign(
  653 + memcpy(__entry->fsid, fs_info->fsid, BTRFS_UUID_SIZE);
  654 + __assign_str(type, type);
  655 + __entry->val = val;
  656 + __entry->bytes = bytes;
  657 + __entry->reserve = reserve;
  658 + ),
  659 +
  660 + TP_printk("%pU: %s: %Lu %s %Lu", __entry->fsid, __get_str(type),
  661 + __entry->val, __entry->reserve ? "reserve" : "release",
  662 + __entry->bytes)
633 663 );
634 664  
635 665 DECLARE_EVENT_CLASS(btrfs__reserved_extent,