forked from luck/tmp_suning_uos_patched
1abe9b8a13
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>
227 lines
6.3 KiB
C
227 lines
6.3 KiB
C
/*
|
|
* Copyright (C) 2007 Oracle. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public
|
|
* License v2 as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public
|
|
* License along with this program; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 021110-1307, USA.
|
|
*/
|
|
|
|
#ifndef __BTRFS_VOLUMES_
|
|
#define __BTRFS_VOLUMES_
|
|
|
|
#include <linux/bio.h>
|
|
#include <linux/sort.h>
|
|
#include "async-thread.h"
|
|
|
|
#define BTRFS_STRIPE_LEN (64 * 1024)
|
|
|
|
struct buffer_head;
|
|
struct btrfs_pending_bios {
|
|
struct bio *head;
|
|
struct bio *tail;
|
|
};
|
|
|
|
struct btrfs_device {
|
|
struct list_head dev_list;
|
|
struct list_head dev_alloc_list;
|
|
struct btrfs_fs_devices *fs_devices;
|
|
struct btrfs_root *dev_root;
|
|
|
|
/* regular prio bios */
|
|
struct btrfs_pending_bios pending_bios;
|
|
/* WRITE_SYNC bios */
|
|
struct btrfs_pending_bios pending_sync_bios;
|
|
|
|
int running_pending;
|
|
u64 generation;
|
|
|
|
int writeable;
|
|
int in_fs_metadata;
|
|
int missing;
|
|
|
|
spinlock_t io_lock;
|
|
|
|
struct block_device *bdev;
|
|
|
|
/* the mode sent to blkdev_get */
|
|
fmode_t mode;
|
|
|
|
char *name;
|
|
|
|
/* the internal btrfs device id */
|
|
u64 devid;
|
|
|
|
/* size of the device */
|
|
u64 total_bytes;
|
|
|
|
/* size of the disk */
|
|
u64 disk_total_bytes;
|
|
|
|
/* bytes used */
|
|
u64 bytes_used;
|
|
|
|
/* optimal io alignment for this device */
|
|
u32 io_align;
|
|
|
|
/* optimal io width for this device */
|
|
u32 io_width;
|
|
|
|
/* minimal io size for this device */
|
|
u32 sector_size;
|
|
|
|
/* type and info about this device */
|
|
u64 type;
|
|
|
|
/* physical drive uuid (or lvm uuid) */
|
|
u8 uuid[BTRFS_UUID_SIZE];
|
|
|
|
struct btrfs_work work;
|
|
};
|
|
|
|
struct btrfs_fs_devices {
|
|
u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */
|
|
|
|
/* the device with this id has the most recent copy of the super */
|
|
u64 latest_devid;
|
|
u64 latest_trans;
|
|
u64 num_devices;
|
|
u64 open_devices;
|
|
u64 rw_devices;
|
|
u64 missing_devices;
|
|
u64 total_rw_bytes;
|
|
struct block_device *latest_bdev;
|
|
|
|
/* all of the devices in the FS, protected by a mutex
|
|
* so we can safely walk it to write out the supers without
|
|
* worrying about add/remove by the multi-device code
|
|
*/
|
|
struct mutex device_list_mutex;
|
|
struct list_head devices;
|
|
|
|
/* devices not currently being allocated */
|
|
struct list_head alloc_list;
|
|
struct list_head list;
|
|
|
|
struct btrfs_fs_devices *seed;
|
|
int seeding;
|
|
|
|
int opened;
|
|
|
|
/* set when we find or add a device that doesn't have the
|
|
* nonrot flag set
|
|
*/
|
|
int rotating;
|
|
};
|
|
|
|
struct btrfs_bio_stripe {
|
|
struct btrfs_device *dev;
|
|
u64 physical;
|
|
};
|
|
|
|
struct btrfs_multi_bio {
|
|
atomic_t stripes_pending;
|
|
bio_end_io_t *end_io;
|
|
struct bio *orig_bio;
|
|
void *private;
|
|
atomic_t error;
|
|
int max_errors;
|
|
int num_stripes;
|
|
struct btrfs_bio_stripe stripes[];
|
|
};
|
|
|
|
struct btrfs_device_info {
|
|
struct btrfs_device *dev;
|
|
u64 dev_offset;
|
|
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);
|
|
|
|
/*
|
|
* sort the devices by max_avail, in which max free extent size of each device
|
|
* is stored.(Descending Sort)
|
|
*/
|
|
static inline void btrfs_descending_sort_devices(
|
|
struct btrfs_device_info *devices,
|
|
size_t nr_devices)
|
|
{
|
|
sort(devices, nr_devices, sizeof(struct btrfs_device_info),
|
|
btrfs_cmp_device_free_bytes, NULL);
|
|
}
|
|
|
|
int btrfs_account_dev_extents_size(struct btrfs_device *device, u64 start,
|
|
u64 end, u64 *length);
|
|
|
|
#define btrfs_multi_bio_size(n) (sizeof(struct btrfs_multi_bio) + \
|
|
(sizeof(struct btrfs_bio_stripe) * (n)))
|
|
|
|
int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans,
|
|
struct btrfs_device *device,
|
|
u64 chunk_tree, u64 chunk_objectid,
|
|
u64 chunk_offset, u64 start, u64 num_bytes);
|
|
int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
|
|
u64 logical, u64 *length,
|
|
struct btrfs_multi_bio **multi_ret, int mirror_num);
|
|
int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
|
|
u64 chunk_start, u64 physical, u64 devid,
|
|
u64 **logical, int *naddrs, int *stripe_len);
|
|
int btrfs_read_sys_array(struct btrfs_root *root);
|
|
int btrfs_read_chunk_tree(struct btrfs_root *root);
|
|
int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
|
|
struct btrfs_root *extent_root, u64 type);
|
|
void btrfs_mapping_init(struct btrfs_mapping_tree *tree);
|
|
void btrfs_mapping_tree_free(struct btrfs_mapping_tree *tree);
|
|
int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
|
|
int mirror_num, int async_submit);
|
|
int btrfs_read_super_device(struct btrfs_root *root, struct extent_buffer *buf);
|
|
int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
|
|
fmode_t flags, void *holder);
|
|
int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder,
|
|
struct btrfs_fs_devices **fs_devices_ret);
|
|
int btrfs_close_devices(struct btrfs_fs_devices *fs_devices);
|
|
int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices);
|
|
int btrfs_add_device(struct btrfs_trans_handle *trans,
|
|
struct btrfs_root *root,
|
|
struct btrfs_device *device);
|
|
int btrfs_rm_device(struct btrfs_root *root, char *device_path);
|
|
int btrfs_cleanup_fs_uuids(void);
|
|
int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len);
|
|
int btrfs_unplug_page(struct btrfs_mapping_tree *map_tree,
|
|
u64 logical, struct page *page);
|
|
int btrfs_grow_device(struct btrfs_trans_handle *trans,
|
|
struct btrfs_device *device, u64 new_size);
|
|
struct btrfs_device *btrfs_find_device(struct btrfs_root *root, u64 devid,
|
|
u8 *uuid, u8 *fsid);
|
|
int btrfs_shrink_device(struct btrfs_device *device, u64 new_size);
|
|
int btrfs_init_new_device(struct btrfs_root *root, char *path);
|
|
int btrfs_balance(struct btrfs_root *dev_root);
|
|
void btrfs_unlock_volumes(void);
|
|
void btrfs_lock_volumes(void);
|
|
int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset);
|
|
int find_free_dev_extent(struct btrfs_trans_handle *trans,
|
|
struct btrfs_device *device, u64 num_bytes,
|
|
u64 *start, u64 *max_avail);
|
|
#endif
|