Skip to content

Commit

Permalink
Btrfs: add initial tracepoint support for btrfs
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Chris Mason <[email protected]>
  • Loading branch information
liub authored and root committed Mar 28, 2011
1 parent 240f62c commit 1abe9b8
Show file tree
Hide file tree
Showing 13 changed files with 727 additions and 11 deletions.
3 changes: 3 additions & 0 deletions fs/btrfs/ctree.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,9 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,

ret = __btrfs_cow_block(trans, root, buf, parent,
parent_slot, cow_ret, search_start, 0);

trace_btrfs_cow_block(root, buf, *cow_ret);

return ret;
}

Expand Down
1 change: 1 addition & 0 deletions fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/kobject.h>
#include <trace/events/btrfs.h>
#include <asm/kmap_types.h>
#include "extent_io.h"
#include "extent_map.h"
Expand Down
6 changes: 6 additions & 0 deletions fs/btrfs/delayed-ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,8 @@ static noinline int add_delayed_ref_head(struct btrfs_trans_handle *trans,
INIT_LIST_HEAD(&head_ref->cluster);
mutex_init(&head_ref->mutex);

trace_btrfs_delayed_ref_head(ref, head_ref, action);

existing = tree_insert(&delayed_refs->root, &ref->rb_node);

if (existing) {
Expand Down Expand Up @@ -537,6 +539,8 @@ static noinline int add_delayed_tree_ref(struct btrfs_trans_handle *trans,
}
full_ref->level = level;

trace_btrfs_delayed_tree_ref(ref, full_ref, action);

existing = tree_insert(&delayed_refs->root, &ref->rb_node);

if (existing) {
Expand Down Expand Up @@ -591,6 +595,8 @@ static noinline int add_delayed_data_ref(struct btrfs_trans_handle *trans,
full_ref->objectid = owner;
full_ref->offset = offset;

trace_btrfs_delayed_data_ref(ref, full_ref, action);

existing = tree_insert(&delayed_refs->root, &ref->rb_node);

if (existing) {
Expand Down
4 changes: 4 additions & 0 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -5412,6 +5412,8 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans,
dump_space_info(sinfo, num_bytes, 1);
}

trace_btrfs_reserved_extent_alloc(root, ins->objectid, ins->offset);

return ret;
}

Expand All @@ -5433,6 +5435,8 @@ int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len)
update_reserved_bytes(cache, len, 0, 1);
btrfs_put_block_group(cache);

trace_btrfs_reserved_extent_free(root, start, len);

return ret;
}

Expand Down
2 changes: 2 additions & 0 deletions fs/btrfs/extent_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -2192,6 +2192,8 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
else
write_flags = WRITE;

trace___extent_writepage(page, inode, wbc);

WARN_ON(!PageLocked(page));
pg_offset = i_size & (PAGE_CACHE_SIZE - 1);
if (page->index > end_index ||
Expand Down
1 change: 1 addition & 0 deletions fs/btrfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,7 @@ int btrfs_sync_file(struct file *file, int datasync)
int ret = 0;
struct btrfs_trans_handle *trans;

trace_btrfs_sync_file(file, datasync);

/* we wait first, since the writeback may change the inode */
root->log_batch++;
Expand Down
12 changes: 12 additions & 0 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1787,6 +1787,8 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end,
struct extent_state *state, int uptodate)
{
trace_btrfs_writepage_end_io_hook(page, start, end, uptodate);

ClearPagePrivate2(page);
return btrfs_finish_ordered_io(page->mapping->host, start, end);
}
Expand Down Expand Up @@ -3718,6 +3720,8 @@ void btrfs_evict_inode(struct inode *inode)
unsigned long nr;
int ret;

trace_btrfs_inode_evict(inode);

truncate_inode_pages(&inode->i_data, 0);
if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 ||
root == root->fs_info->tree_root))
Expand Down Expand Up @@ -4510,6 +4514,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
return ERR_PTR(-ENOMEM);

if (dir) {
trace_btrfs_inode_request(dir);

ret = btrfs_set_inode_index(dir, index);
if (ret) {
iput(inode);
Expand Down Expand Up @@ -4584,6 +4590,9 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,

insert_inode_hash(inode);
inode_tree_add(inode);

trace_btrfs_inode_new(inode);

return inode;
fail:
if (dir)
Expand Down Expand Up @@ -5261,6 +5270,9 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
}
write_unlock(&em_tree->lock);
out:

trace_btrfs_get_extent(root, em);

if (path)
btrfs_free_path(path);
if (trans) {
Expand Down
8 changes: 8 additions & 0 deletions fs/btrfs/ordered-data.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
INIT_LIST_HEAD(&entry->list);
INIT_LIST_HEAD(&entry->root_extent_list);

trace_btrfs_ordered_extent_add(inode, entry);

spin_lock(&tree->lock);
node = tree_insert(&tree->tree, file_offset,
&entry->rb_node);
Expand Down Expand Up @@ -387,6 +389,8 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry)
struct list_head *cur;
struct btrfs_ordered_sum *sum;

trace_btrfs_ordered_extent_put(entry->inode, entry);

if (atomic_dec_and_test(&entry->refs)) {
while (!list_empty(&entry->list)) {
cur = entry->list.next;
Expand Down Expand Up @@ -420,6 +424,8 @@ static int __btrfs_remove_ordered_extent(struct inode *inode,
spin_lock(&root->fs_info->ordered_extent_lock);
list_del_init(&entry->root_extent_list);

trace_btrfs_ordered_extent_remove(inode, entry);

/*
* we have no more ordered extents for this inode and
* no dirty pages. We can safely remove it from the
Expand Down Expand Up @@ -585,6 +591,8 @@ void btrfs_start_ordered_extent(struct inode *inode,
u64 start = entry->file_offset;
u64 end = start + entry->len - 1;

trace_btrfs_ordered_extent_start(inode, entry);

/*
* pages in the range can be dirty, clean or writeback. We
* start IO on any dirty ones so the wait doesn't stall waiting
Expand Down
5 changes: 5 additions & 0 deletions fs/btrfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
#include "export.h"
#include "compression.h"

#define CREATE_TRACE_POINTS
#include <trace/events/btrfs.h>

static const struct super_operations btrfs_super_ops;

static const char *btrfs_decode_error(struct btrfs_fs_info *fs_info, int errno,
Expand Down Expand Up @@ -620,6 +623,8 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
struct btrfs_root *root = btrfs_sb(sb);
int ret;

trace_btrfs_sync_fs(wait);

if (!wait) {
filemap_flush(root->fs_info->btree_inode->i_mapping);
return 0;
Expand Down
2 changes: 2 additions & 0 deletions fs/btrfs/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -1389,6 +1389,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
put_transaction(cur_trans);
put_transaction(cur_trans);

trace_btrfs_transaction_commit(root);

mutex_unlock(&root->fs_info->trans_mutex);

if (current->journal_info == trans)
Expand Down
16 changes: 5 additions & 11 deletions fs/btrfs/volumes.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,6 @@
#include "volumes.h"
#include "async-thread.h"

struct map_lookup {
u64 type;
int io_align;
int io_width;
int stripe_len;
int sector_size;
int num_stripes;
int sub_stripes;
struct btrfs_bio_stripe stripes[];
};

static int init_first_rw_device(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct btrfs_device *device);
Expand Down Expand Up @@ -1923,6 +1912,8 @@ static int btrfs_relocate_chunk(struct btrfs_root *root,

BUG_ON(ret);

trace_btrfs_chunk_free(root, map, chunk_offset, em->len);

if (map->type & BTRFS_BLOCK_GROUP_SYSTEM) {
ret = btrfs_del_sys_chunk(root, chunk_objectid, chunk_offset);
BUG_ON(ret);
Expand Down Expand Up @@ -2650,6 +2641,8 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
*num_bytes = chunk_bytes_by_type(type, calc_size,
map->num_stripes, sub_stripes);

trace_btrfs_chunk_alloc(info->chunk_root, map, start, *num_bytes);

em = alloc_extent_map(GFP_NOFS);
if (!em) {
ret = -ENOMEM;
Expand Down Expand Up @@ -2758,6 +2751,7 @@ static int __finish_chunk_alloc(struct btrfs_trans_handle *trans,
item_size);
BUG_ON(ret);
}

kfree(chunk);
return 0;
}
Expand Down
11 changes: 11 additions & 0 deletions fs/btrfs/volumes.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,17 @@ struct btrfs_device_info {
u64 max_avail;
};

struct map_lookup {
u64 type;
int io_align;
int io_width;
int stripe_len;
int sector_size;
int num_stripes;
int sub_stripes;
struct btrfs_bio_stripe stripes[];
};

/* Used to sort the devices by max_avail(descending sort) */
int btrfs_cmp_device_free_bytes(const void *dev_info1, const void *dev_info2);

Expand Down
Loading

0 comments on commit 1abe9b8

Please sign in to comment.