aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorliubo <liubo2009@cn.fujitsu.com>2011-03-24 07:18:59 -0400
committerroot <Chris Mason chris.mason@oracle.com>2011-03-28 05:37:33 -0400
commit1abe9b8a138c9988ba8f7bfded6453649a31541f (patch)
tree9fe0c181e78b075b65f6b1802f0a5092e7afbc6a /fs/btrfs
parent240f62c8756df285da11469259b3900f32883168 (diff)
Btrfs: add initial tracepoint support for btrfs
Tracepoints can provide insight into why btrfs hits bugs and be greatly helpful for debugging, e.g dd-7822 [000] 2121.641088: btrfs_inode_request: root = 5(FS_TREE), gen = 4, ino = 256, blocks = 8, disk_i_size = 0, last_trans = 8, logged_trans = 0 dd-7822 [000] 2121.641100: btrfs_inode_new: root = 5(FS_TREE), gen = 8, ino = 257, blocks = 0, disk_i_size = 0, last_trans = 0, logged_trans = 0 btrfs-transacti-7804 [001] 2146.935420: btrfs_cow_block: root = 2(EXTENT_TREE), refs = 2, orig_buf = 29368320 (orig_level = 0), cow_buf = 29388800 (cow_level = 0) btrfs-transacti-7804 [001] 2146.935473: btrfs_cow_block: root = 1(ROOT_TREE), refs = 2, orig_buf = 29364224 (orig_level = 0), cow_buf = 29392896 (cow_level = 0) btrfs-transacti-7804 [001] 2146.972221: btrfs_transaction_commit: root = 1(ROOT_TREE), gen = 8 flush-btrfs-2-7821 [001] 2155.824210: btrfs_chunk_alloc: root = 3(CHUNK_TREE), offset = 1103101952, size = 1073741824, num_stripes = 1, sub_stripes = 0, type = DATA flush-btrfs-2-7821 [001] 2155.824241: btrfs_cow_block: root = 2(EXTENT_TREE), refs = 2, orig_buf = 29388800 (orig_level = 0), cow_buf = 29396992 (cow_level = 0) flush-btrfs-2-7821 [001] 2155.824255: btrfs_cow_block: root = 4(DEV_TREE), refs = 2, orig_buf = 29372416 (orig_level = 0), cow_buf = 29401088 (cow_level = 0) flush-btrfs-2-7821 [000] 2155.824329: btrfs_cow_block: root = 3(CHUNK_TREE), refs = 2, orig_buf = 20971520 (orig_level = 0), cow_buf = 20975616 (cow_level = 0) btrfs-endio-wri-7800 [001] 2155.898019: btrfs_cow_block: root = 5(FS_TREE), refs = 2, orig_buf = 29384704 (orig_level = 0), cow_buf = 29405184 (cow_level = 0) btrfs-endio-wri-7800 [001] 2155.898043: btrfs_cow_block: root = 7(CSUM_TREE), refs = 2, orig_buf = 29376512 (orig_level = 0), cow_buf = 29409280 (cow_level = 0) Here is what I have added: 1) ordere_extent: btrfs_ordered_extent_add btrfs_ordered_extent_remove btrfs_ordered_extent_start btrfs_ordered_extent_put These provide critical information to understand how ordered_extents are updated. 2) extent_map: btrfs_get_extent extent_map is used in both read and write cases, and it is useful for tracking how btrfs specific IO is running. 3) writepage: __extent_writepage btrfs_writepage_end_io_hook Pages are cirtical resourses and produce a lot of corner cases during writeback, so it is valuable to know how page is written to disk. 4) inode: btrfs_inode_new btrfs_inode_request btrfs_inode_evict These can show where and when a inode is created, when a inode is evicted. 5) sync: btrfs_sync_file btrfs_sync_fs These show sync arguments. 6) transaction: btrfs_transaction_commit In transaction based filesystem, it will be useful to know the generation and who does commit. 7) back reference and cow: btrfs_delayed_tree_ref btrfs_delayed_data_ref btrfs_delayed_ref_head btrfs_cow_block Btrfs natively supports back references, these tracepoints are helpful on understanding btrfs's COW mechanism. 8) chunk: btrfs_chunk_alloc btrfs_chunk_free Chunk is a link between physical offset and logical offset, and stands for space infomation in btrfs, and these are helpful on tracing space things. 9) reserved_extent: btrfs_reserved_extent_alloc btrfs_reserved_extent_free These can show how btrfs uses its space. Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.c3
-rw-r--r--fs/btrfs/ctree.h1
-rw-r--r--fs/btrfs/delayed-ref.c6
-rw-r--r--fs/btrfs/extent-tree.c4
-rw-r--r--fs/btrfs/extent_io.c2
-rw-r--r--fs/btrfs/file.c1
-rw-r--r--fs/btrfs/inode.c12
-rw-r--r--fs/btrfs/ordered-data.c8
-rw-r--r--fs/btrfs/super.c5
-rw-r--r--fs/btrfs/transaction.c2
-rw-r--r--fs/btrfs/volumes.c16
-rw-r--r--fs/btrfs/volumes.h11
12 files changed, 60 insertions, 11 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 8680110f0a5a..465b5d7d6b48 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -535,6 +535,9 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
535 535
536 ret = __btrfs_cow_block(trans, root, buf, parent, 536 ret = __btrfs_cow_block(trans, root, buf, parent,
537 parent_slot, cow_ret, search_start, 0); 537 parent_slot, cow_ret, search_start, 0);
538
539 trace_btrfs_cow_block(root, buf, *cow_ret);
540
538 return ret; 541 return ret;
539} 542}
540 543
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 0ee679b6c1b7..9d0f59142afa 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -28,6 +28,7 @@
28#include <linux/wait.h> 28#include <linux/wait.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/kobject.h> 30#include <linux/kobject.h>
31#include <trace/events/btrfs.h>
31#include <asm/kmap_types.h> 32#include <asm/kmap_types.h>
32#include "extent_io.h" 33#include "extent_io.h"
33#include "extent_map.h" 34#include "extent_map.h"
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
index e807b143b857..bce28f653899 100644
--- a/fs/btrfs/delayed-ref.c
+++ b/fs/btrfs/delayed-ref.c
@@ -483,6 +483,8 @@ static noinline int add_delayed_ref_head(struct btrfs_trans_handle *trans,
483 INIT_LIST_HEAD(&head_ref->cluster); 483 INIT_LIST_HEAD(&head_ref->cluster);
484 mutex_init(&head_ref->mutex); 484 mutex_init(&head_ref->mutex);
485 485
486 trace_btrfs_delayed_ref_head(ref, head_ref, action);
487
486 existing = tree_insert(&delayed_refs->root, &ref->rb_node); 488 existing = tree_insert(&delayed_refs->root, &ref->rb_node);
487 489
488 if (existing) { 490 if (existing) {
@@ -537,6 +539,8 @@ static noinline int add_delayed_tree_ref(struct btrfs_trans_handle *trans,
537 } 539 }
538 full_ref->level = level; 540 full_ref->level = level;
539 541
542 trace_btrfs_delayed_tree_ref(ref, full_ref, action);
543
540 existing = tree_insert(&delayed_refs->root, &ref->rb_node); 544 existing = tree_insert(&delayed_refs->root, &ref->rb_node);
541 545
542 if (existing) { 546 if (existing) {
@@ -591,6 +595,8 @@ static noinline int add_delayed_data_ref(struct btrfs_trans_handle *trans,
591 full_ref->objectid = owner; 595 full_ref->objectid = owner;
592 full_ref->offset = offset; 596 full_ref->offset = offset;
593 597
598 trace_btrfs_delayed_data_ref(ref, full_ref, action);
599
594 existing = tree_insert(&delayed_refs->root, &ref->rb_node); 600 existing = tree_insert(&delayed_refs->root, &ref->rb_node);
595 601
596 if (existing) { 602 if (existing) {
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index cd794c35a636..86ea471d3801 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -5412,6 +5412,8 @@ again:
5412 dump_space_info(sinfo, num_bytes, 1); 5412 dump_space_info(sinfo, num_bytes, 1);
5413 } 5413 }
5414 5414
5415 trace_btrfs_reserved_extent_alloc(root, ins->objectid, ins->offset);
5416
5415 return ret; 5417 return ret;
5416} 5418}
5417 5419
@@ -5433,6 +5435,8 @@ int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len)
5433 update_reserved_bytes(cache, len, 0, 1); 5435 update_reserved_bytes(cache, len, 0, 1);
5434 btrfs_put_block_group(cache); 5436 btrfs_put_block_group(cache);
5435 5437
5438 trace_btrfs_reserved_extent_free(root, start, len);
5439
5436 return ret; 5440 return ret;
5437} 5441}
5438 5442
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 1bbd26b4fc5c..77c65a0bea34 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2192,6 +2192,8 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
2192 else 2192 else
2193 write_flags = WRITE; 2193 write_flags = WRITE;
2194 2194
2195 trace___extent_writepage(page, inode, wbc);
2196
2195 WARN_ON(!PageLocked(page)); 2197 WARN_ON(!PageLocked(page));
2196 pg_offset = i_size & (PAGE_CACHE_SIZE - 1); 2198 pg_offset = i_size & (PAGE_CACHE_SIZE - 1);
2197 if (page->index > end_index || 2199 if (page->index > end_index ||
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index a85b044cf39e..656bc0a892b1 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1205,6 +1205,7 @@ int btrfs_sync_file(struct file *file, int datasync)
1205 int ret = 0; 1205 int ret = 0;
1206 struct btrfs_trans_handle *trans; 1206 struct btrfs_trans_handle *trans;
1207 1207
1208 trace_btrfs_sync_file(file, datasync);
1208 1209
1209 /* we wait first, since the writeback may change the inode */ 1210 /* we wait first, since the writeback may change the inode */
1210 root->log_batch++; 1211 root->log_batch++;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index e9813bd7d556..eaa271484199 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1787,6 +1787,8 @@ out:
1787static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end, 1787static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end,
1788 struct extent_state *state, int uptodate) 1788 struct extent_state *state, int uptodate)
1789{ 1789{
1790 trace_btrfs_writepage_end_io_hook(page, start, end, uptodate);
1791
1790 ClearPagePrivate2(page); 1792 ClearPagePrivate2(page);
1791 return btrfs_finish_ordered_io(page->mapping->host, start, end); 1793 return btrfs_finish_ordered_io(page->mapping->host, start, end);
1792} 1794}
@@ -3718,6 +3720,8 @@ void btrfs_evict_inode(struct inode *inode)
3718 unsigned long nr; 3720 unsigned long nr;
3719 int ret; 3721 int ret;
3720 3722
3723 trace_btrfs_inode_evict(inode);
3724
3721 truncate_inode_pages(&inode->i_data, 0); 3725 truncate_inode_pages(&inode->i_data, 0);
3722 if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 || 3726 if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 ||
3723 root == root->fs_info->tree_root)) 3727 root == root->fs_info->tree_root))
@@ -4510,6 +4514,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
4510 return ERR_PTR(-ENOMEM); 4514 return ERR_PTR(-ENOMEM);
4511 4515
4512 if (dir) { 4516 if (dir) {
4517 trace_btrfs_inode_request(dir);
4518
4513 ret = btrfs_set_inode_index(dir, index); 4519 ret = btrfs_set_inode_index(dir, index);
4514 if (ret) { 4520 if (ret) {
4515 iput(inode); 4521 iput(inode);
@@ -4584,6 +4590,9 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
4584 4590
4585 insert_inode_hash(inode); 4591 insert_inode_hash(inode);
4586 inode_tree_add(inode); 4592 inode_tree_add(inode);
4593
4594 trace_btrfs_inode_new(inode);
4595
4587 return inode; 4596 return inode;
4588fail: 4597fail:
4589 if (dir) 4598 if (dir)
@@ -5261,6 +5270,9 @@ insert:
5261 } 5270 }
5262 write_unlock(&em_tree->lock); 5271 write_unlock(&em_tree->lock);
5263out: 5272out:
5273
5274 trace_btrfs_get_extent(root, em);
5275
5264 if (path) 5276 if (path)
5265 btrfs_free_path(path); 5277 btrfs_free_path(path);
5266 if (trans) { 5278 if (trans) {
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 083a55477375..a1c940425307 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -202,6 +202,8 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
202 INIT_LIST_HEAD(&entry->list); 202 INIT_LIST_HEAD(&entry->list);
203 INIT_LIST_HEAD(&entry->root_extent_list); 203 INIT_LIST_HEAD(&entry->root_extent_list);
204 204
205 trace_btrfs_ordered_extent_add(inode, entry);
206
205 spin_lock(&tree->lock); 207 spin_lock(&tree->lock);
206 node = tree_insert(&tree->tree, file_offset, 208 node = tree_insert(&tree->tree, file_offset,
207 &entry->rb_node); 209 &entry->rb_node);
@@ -387,6 +389,8 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry)
387 struct list_head *cur; 389 struct list_head *cur;
388 struct btrfs_ordered_sum *sum; 390 struct btrfs_ordered_sum *sum;
389 391
392 trace_btrfs_ordered_extent_put(entry->inode, entry);
393
390 if (atomic_dec_and_test(&entry->refs)) { 394 if (atomic_dec_and_test(&entry->refs)) {
391 while (!list_empty(&entry->list)) { 395 while (!list_empty(&entry->list)) {
392 cur = entry->list.next; 396 cur = entry->list.next;
@@ -420,6 +424,8 @@ static int __btrfs_remove_ordered_extent(struct inode *inode,
420 spin_lock(&root->fs_info->ordered_extent_lock); 424 spin_lock(&root->fs_info->ordered_extent_lock);
421 list_del_init(&entry->root_extent_list); 425 list_del_init(&entry->root_extent_list);
422 426
427 trace_btrfs_ordered_extent_remove(inode, entry);
428
423 /* 429 /*
424 * we have no more ordered extents for this inode and 430 * we have no more ordered extents for this inode and
425 * no dirty pages. We can safely remove it from the 431 * no dirty pages. We can safely remove it from the
@@ -585,6 +591,8 @@ void btrfs_start_ordered_extent(struct inode *inode,
585 u64 start = entry->file_offset; 591 u64 start = entry->file_offset;
586 u64 end = start + entry->len - 1; 592 u64 end = start + entry->len - 1;
587 593
594 trace_btrfs_ordered_extent_start(inode, entry);
595
588 /* 596 /*
589 * pages in the range can be dirty, clean or writeback. We 597 * pages in the range can be dirty, clean or writeback. We
590 * start IO on any dirty ones so the wait doesn't stall waiting 598 * start IO on any dirty ones so the wait doesn't stall waiting
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index d39a9895d932..2edfc039f098 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -52,6 +52,9 @@
52#include "export.h" 52#include "export.h"
53#include "compression.h" 53#include "compression.h"
54 54
55#define CREATE_TRACE_POINTS
56#include <trace/events/btrfs.h>
57
55static const struct super_operations btrfs_super_ops; 58static const struct super_operations btrfs_super_ops;
56 59
57static const char *btrfs_decode_error(struct btrfs_fs_info *fs_info, int errno, 60static const char *btrfs_decode_error(struct btrfs_fs_info *fs_info, int errno,
@@ -620,6 +623,8 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
620 struct btrfs_root *root = btrfs_sb(sb); 623 struct btrfs_root *root = btrfs_sb(sb);
621 int ret; 624 int ret;
622 625
626 trace_btrfs_sync_fs(wait);
627
623 if (!wait) { 628 if (!wait) {
624 filemap_flush(root->fs_info->btree_inode->i_mapping); 629 filemap_flush(root->fs_info->btree_inode->i_mapping);
625 return 0; 630 return 0;
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 3d73c8d93bbb..5b4bc685bb0e 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1389,6 +1389,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1389 put_transaction(cur_trans); 1389 put_transaction(cur_trans);
1390 put_transaction(cur_trans); 1390 put_transaction(cur_trans);
1391 1391
1392 trace_btrfs_transaction_commit(root);
1393
1392 mutex_unlock(&root->fs_info->trans_mutex); 1394 mutex_unlock(&root->fs_info->trans_mutex);
1393 1395
1394 if (current->journal_info == trans) 1396 if (current->journal_info == trans)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index dd13eb81ee40..8ba3c9ebff93 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -33,17 +33,6 @@
33#include "volumes.h" 33#include "volumes.h"
34#include "async-thread.h" 34#include "async-thread.h"
35 35
36struct map_lookup {
37 u64 type;
38 int io_align;
39 int io_width;
40 int stripe_len;
41 int sector_size;
42 int num_stripes;
43 int sub_stripes;
44 struct btrfs_bio_stripe stripes[];
45};
46
47static int init_first_rw_device(struct btrfs_trans_handle *trans, 36static int init_first_rw_device(struct btrfs_trans_handle *trans,
48 struct btrfs_root *root, 37 struct btrfs_root *root,
49 struct btrfs_device *device); 38 struct btrfs_device *device);
@@ -1923,6 +1912,8 @@ static int btrfs_relocate_chunk(struct btrfs_root *root,
1923 1912
1924 BUG_ON(ret); 1913 BUG_ON(ret);
1925 1914
1915 trace_btrfs_chunk_free(root, map, chunk_offset, em->len);
1916
1926 if (map->type & BTRFS_BLOCK_GROUP_SYSTEM) { 1917 if (map->type & BTRFS_BLOCK_GROUP_SYSTEM) {
1927 ret = btrfs_del_sys_chunk(root, chunk_objectid, chunk_offset); 1918 ret = btrfs_del_sys_chunk(root, chunk_objectid, chunk_offset);
1928 BUG_ON(ret); 1919 BUG_ON(ret);
@@ -2650,6 +2641,8 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
2650 *num_bytes = chunk_bytes_by_type(type, calc_size, 2641 *num_bytes = chunk_bytes_by_type(type, calc_size,
2651 map->num_stripes, sub_stripes); 2642 map->num_stripes, sub_stripes);
2652 2643
2644 trace_btrfs_chunk_alloc(info->chunk_root, map, start, *num_bytes);
2645
2653 em = alloc_extent_map(GFP_NOFS); 2646 em = alloc_extent_map(GFP_NOFS);
2654 if (!em) { 2647 if (!em) {
2655 ret = -ENOMEM; 2648 ret = -ENOMEM;
@@ -2758,6 +2751,7 @@ static int __finish_chunk_alloc(struct btrfs_trans_handle *trans,
2758 item_size); 2751 item_size);
2759 BUG_ON(ret); 2752 BUG_ON(ret);
2760 } 2753 }
2754
2761 kfree(chunk); 2755 kfree(chunk);
2762 return 0; 2756 return 0;
2763} 2757}
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 7fb59d45fe8c..7b38d0668b51 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -145,6 +145,17 @@ struct btrfs_device_info {
145 u64 max_avail; 145 u64 max_avail;
146}; 146};
147 147
148struct map_lookup {
149 u64 type;
150 int io_align;
151 int io_width;
152 int stripe_len;
153 int sector_size;
154 int num_stripes;
155 int sub_stripes;
156 struct btrfs_bio_stripe stripes[];
157};
158
148/* Used to sort the devices by max_avail(descending sort) */ 159/* Used to sort the devices by max_avail(descending sort) */
149int btrfs_cmp_device_free_bytes(const void *dev_info1, const void *dev_info2); 160int btrfs_cmp_device_free_bytes(const void *dev_info1, const void *dev_info2);
150 161