Jan Schmidt
2011-Feb-01 13:54 UTC
[PATCH 0/7] Btrfs: Progs modifications to introduce speed profiles and dedicated log devices
This patch set for progs accompanies the (largish) kernel patch submitted by Arne Jansen three days ago (Subject: [PATCH] Btrfs: introducing speed profiles and dedicated log devices). It provides a first implementation of (yet static) speed profiles: "mkfs.btrfs" and "btrfs device add" now both support device classes. Thus, it is posible to dedicate a device to the log tree (e.g. a fast ssd), or decide another should hold metadata only. Fully configurable speed profiles can be the next step. Jan Schmidt (7): moved parse_size() to utils.c pulled current kernel version of ioctl.h check open_ctree() right after it returned speed classes (needed for profiles) for device add. subsequent patch needed to fix mkfs speed classes (needed for profiles) for mkfs debug-tree output: device speed added; type output switched to hex made btrfs-vol compile. looks unused, so no speed class support here for now. btrfs-vol.c | 3 +- btrfs.c | 2 +- btrfs_cmds.c | 93 ++++++++++++++++++++-------------- ctree.h | 20 +++++++ extent-tree.c | 11 +++-- ioctl-test.c | 1 + ioctl.h | 57 +++++++++++++++++--- mkfs.c | 158 +++++++++++++++++++++++++++++++++++---------------------- print-tree.c | 7 ++- utils.c | 55 ++++++++++++++++++-- utils.h | 13 ++++- volumes.c | 13 ++++- volumes.h | 6 ++- 13 files changed, 311 insertions(+), 128 deletions(-) -- 1.7.2.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net> --- btrfs_cmds.c | 26 -------------------------- mkfs.c | 26 -------------------------- utils.c | 26 ++++++++++++++++++++++++++ utils.h | 1 + 4 files changed, 27 insertions(+), 52 deletions(-) diff --git a/btrfs_cmds.c b/btrfs_cmds.c index 8031c58..d707a7d 100644 --- a/btrfs_cmds.c +++ b/btrfs_cmds.c @@ -116,32 +116,6 @@ static int open_file_or_dir(const char *fname) return fd; } -static u64 parse_size(char *s) -{ - int len = strlen(s); - char c; - u64 mult = 1; - - if (!isdigit(s[len - 1])) { - c = tolower(s[len - 1]); - switch (c) { - case ''g'': - mult *= 1024; - case ''m'': - mult *= 1024; - case ''k'': - mult *= 1024; - case ''b'': - break; - default: - fprintf(stderr, "Unknown size descriptor %c\n", c); - exit(1); - } - s[len - 1] = ''\0''; - } - return atoll(s) * mult; -} - int do_defrag(int ac, char **av) { int fd; diff --git a/mkfs.c b/mkfs.c index 2e99b95..d1dd4a3 100644 --- a/mkfs.c +++ b/mkfs.c @@ -43,32 +43,6 @@ #include "utils.h" #include "version.h" -static u64 parse_size(char *s) -{ - int len = strlen(s); - char c; - u64 mult = 1; - - if (!isdigit(s[len - 1])) { - c = tolower(s[len - 1]); - switch (c) { - case ''g'': - mult *= 1024; - case ''m'': - mult *= 1024; - case ''k'': - mult *= 1024; - case ''b'': - break; - default: - fprintf(stderr, "Unknown size descriptor %c\n", c); - exit(1); - } - s[len - 1] = ''\0''; - } - return atol(s) * mult; -} - static int make_root_dir(struct btrfs_root *root) { struct btrfs_trans_handle *trans; diff --git a/utils.c b/utils.c index 815b967..5fb82dc 100644 --- a/utils.c +++ b/utils.c @@ -35,6 +35,7 @@ #include <linux/major.h> #include <linux/kdev_t.h> #include <limits.h> +#include <ctype.h> #include "kerncompat.h" #include "radix-tree.h" #include "ctree.h" @@ -1003,3 +1004,28 @@ char *pretty_sizes(u64 size) return pretty; } +u64 parse_size(char *s) +{ + int len = strlen(s); + char c; + u64 mult = 1; + + if (!isdigit(s[len - 1])) { + c = tolower(s[len - 1]); + switch (c) { + case ''g'': + mult *= 1024; + case ''m'': + mult *= 1024; + case ''k'': + mult *= 1024; + case ''b'': + break; + default: + fprintf(stderr, "Unknown size descriptor %c\n", c); + exit(1); + } + s[len - 1] = ''\0''; + } + return atoll(s) * mult; +} diff --git a/utils.h b/utils.h index 9dce5b0..dc1b41d 100644 --- a/utils.h +++ b/utils.h @@ -40,4 +40,5 @@ int check_mounted(const char *devicename); int btrfs_device_already_in_root(struct btrfs_root *root, int fd, int super_offset); char *pretty_sizes(u64 size); +u64 parse_size(char *s); #endif -- 1.7.2.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net> --- ioctl.h | 53 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 44 insertions(+), 9 deletions(-) diff --git a/ioctl.h b/ioctl.h index 776d7a9..b66cc29 100644 --- a/ioctl.h +++ b/ioctl.h @@ -23,13 +23,33 @@ #define BTRFS_IOCTL_MAGIC 0x94 #define BTRFS_VOL_NAME_MAX 255 -#define BTRFS_PATH_NAME_MAX 4087 +/* this should be 4k */ +#define BTRFS_PATH_NAME_MAX 4087 struct btrfs_ioctl_vol_args { __s64 fd; char name[BTRFS_PATH_NAME_MAX + 1]; }; +#define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0) +#define BTRFS_SUBVOL_RDONLY (1ULL << 1) + +#define BTRFS_SUBVOL_NAME_MAX 4039 +struct btrfs_ioctl_vol_args_v2 { + __s64 fd; + __u64 transid; + __u64 flags; + __u64 unused[4]; + char name[BTRFS_SUBVOL_NAME_MAX + 1]; +}; + +#define BTRFS_INO_LOOKUP_PATH_MAX 4080 +struct btrfs_ioctl_ino_lookup_args { + __u64 treeid; + __u64 objectid; + char name[BTRFS_INO_LOOKUP_PATH_MAX]; +}; + struct btrfs_ioctl_search_key { /* which root are we searching. 0 is the tree of tree roots */ __u64 tree_id; @@ -85,11 +105,10 @@ struct btrfs_ioctl_search_args { char buf[BTRFS_SEARCH_ARGS_BUFSIZE]; }; -#define BTRFS_INO_LOOKUP_PATH_MAX 4080 -struct btrfs_ioctl_ino_lookup_args { - __u64 treeid; - __u64 objectid; - char name[BTRFS_INO_LOOKUP_PATH_MAX]; +struct btrfs_ioctl_clone_range_args { + __s64 src_fd; + __u64 src_offset, src_length; + __u64 dest_offset; }; /* flags for the defrag range ioctl */ @@ -116,8 +135,15 @@ struct btrfs_ioctl_defrag_range_args { */ __u32 extent_thresh; + /* + * which compression method to use if turning on compression + * for this defrag operation. If unspecified, zlib will + * be used + */ + __u32 compress_type; + /* spare for later */ - __u32 unused[5]; + __u32 unused[4]; }; struct btrfs_ioctl_space_info { @@ -155,11 +181,14 @@ struct btrfs_ioctl_space_args { struct btrfs_ioctl_vol_args) #define BTRFS_IOC_BALANCE _IOW(BTRFS_IOCTL_MAGIC, 12, \ struct btrfs_ioctl_vol_args) -/* 13 is for CLONE_RANGE */ + +#define BTRFS_IOC_CLONE_RANGE _IOW(BTRFS_IOCTL_MAGIC, 13, \ + struct btrfs_ioctl_clone_range_args) + #define BTRFS_IOC_SUBVOL_CREATE _IOW(BTRFS_IOCTL_MAGIC, 14, \ struct btrfs_ioctl_vol_args) #define BTRFS_IOC_SNAP_DESTROY _IOW(BTRFS_IOCTL_MAGIC, 15, \ - struct btrfs_ioctl_vol_args) + struct btrfs_ioctl_vol_args) #define BTRFS_IOC_DEFRAG_RANGE _IOW(BTRFS_IOCTL_MAGIC, 16, \ struct btrfs_ioctl_defrag_range_args) #define BTRFS_IOC_TREE_SEARCH _IOWR(BTRFS_IOCTL_MAGIC, 17, \ @@ -169,4 +198,10 @@ struct btrfs_ioctl_space_args { #define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64) #define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \ struct btrfs_ioctl_space_args) +#define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64) +#define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64) +#define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \ + struct btrfs_ioctl_vol_args_v2) +#define BTRFS_IOC_SUBVOL_GETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 25, __u64) +#define BTRFS_IOC_SUBVOL_SETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 26, __u64) #endif -- 1.7.2.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net> --- mkfs.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) diff --git a/mkfs.c b/mkfs.c index d1dd4a3..0a80d1c 100644 --- a/mkfs.c +++ b/mkfs.c @@ -430,7 +430,13 @@ int main(int ac, char **av) fprintf(stderr, "error during mkfs %d\n", ret); exit(1); } + root = open_ctree(file, 0, O_RDWR); + if (!root) { + fprintf(stderr, "ctree init failed\n"); + return -1; + } + root->fs_info->alloc_start = alloc_start; ret = make_root_dir(root); @@ -445,10 +451,6 @@ int main(int ac, char **av) goto raid_groups; btrfs_register_one_device(file); - if (!root) { - fprintf(stderr, "ctree init failed\n"); - return -1; - } zero_end = 1; while(ac-- > 0) { -- 1.7.2.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Jan Schmidt
2011-Feb-01 13:54 UTC
[PATCH 4/7] speed classes (needed for profiles) for device add. subsequent patch needed to fix mkfs
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net> --- btrfs.c | 2 +- btrfs_cmds.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++---------- ctree.h | 20 +++++++++++++++++ ioctl-test.c | 1 + ioctl.h | 8 +++++- utils.c | 22 ++++++++++++++++-- utils.h | 8 ++++++- 7 files changed, 109 insertions(+), 19 deletions(-) diff --git a/btrfs.c b/btrfs.c index 46314cf..b66202c 100644 --- a/btrfs.c +++ b/btrfs.c @@ -101,7 +101,7 @@ static struct Command commands[] = { "filesystem." }, { do_add_volume, -2, - "device add", "<dev> [<dev>..] <path>\n" + "device add", "[-c <class>] <dev> [[-c <class>] <dev> ...] <path>\n" "Add a device to a filesystem." }, { do_remove_volume, -2, diff --git a/btrfs_cmds.c b/btrfs_cmds.c index d707a7d..639debd 100644 --- a/btrfs_cmds.c +++ b/btrfs_cmds.c @@ -666,7 +666,10 @@ int do_add_volume(int nargs, char **args) char *mntpnt = args[nargs-1]; int i, fdmnt, ret=0; - + int devcnt = 0; + int alloc_dev = 0; + int class = BTRFS_DEVCLASS_ALL; + struct btrfs_class_dev *devs = NULL; fdmnt = open_file_or_dir(mntpnt); if (fdmnt < 0) { @@ -674,46 +677,86 @@ int do_add_volume(int nargs, char **args) return 12; } - for(i=1 ; i < (nargs-1) ; i++ ){ - struct btrfs_ioctl_vol_args ioctl_args; + optind = 1; + while(1) { + int c = getopt(nargs, args, "-c:"); + if (c < 0) + break; + switch(c) { + case 1: + if (devcnt >= alloc_dev) { + alloc_dev += 10; + devs = realloc(devs, + alloc_dev*sizeof(*devs)); + } + devs[devcnt].file = args[optind-1]; + devs[devcnt].class = class; + devcnt++; + break; + case ''c'': + class = parse_class(optarg); + if (class == -1) { + fprintf(stderr, "Unknown class %s\n", optarg); + return 1; + } + break; + default: + fprintf(stderr, "Invalid arguments for add\n"); + return 1; + } + } + if (!devcnt) { + fprintf(stderr, "Invalid arguments for add\n"); + return 1; + } + for(i=0 ; i < devcnt ; i++ ){ + struct btrfs_ioctl_vol_args_v2 ioctl_args; int devfd, res; u64 dev_block_count = 0; struct stat st; - devfd = open(args[i], O_RDWR); + devfd = open(devs[i].file, O_RDWR); if (!devfd) { - fprintf(stderr, "ERROR: Unable to open device ''%s''\n", args[i]); + fprintf(stderr, "ERROR: Unable to open device ''%s''\n", + devs[i].file); close(devfd); ret++; continue; } ret = fstat(devfd, &st); if (ret) { - fprintf(stderr, "ERROR: Unable to stat ''%s''\n", args[i]); + fprintf(stderr, "ERROR: Unable to stat ''%s''\n", + devs[i].file); close(devfd); ret++; continue; } if (!S_ISBLK(st.st_mode)) { - fprintf(stderr, "ERROR: ''%s'' is not a block device\n", args[i]); + fprintf(stderr, "ERROR: ''%s'' is not a block device\n", + devs[i].file); close(devfd); ret++; continue; } - res = btrfs_prepare_device(devfd, args[i], 1, &dev_block_count); + res = btrfs_prepare_device(devfd, devs[i].file, 1, + &dev_block_count, devs[i].class); if (res) { - fprintf(stderr, "ERROR: Unable to init ''%s''\n", args[i]); + fprintf(stderr, "ERROR: Unable to init ''%s''\n", + devs[i].file); close(devfd); ret++; continue; } close(devfd); - strcpy(ioctl_args.name, args[i]); - res = ioctl(fdmnt, BTRFS_IOC_ADD_DEV, &ioctl_args); + memset(&ioctl_args, 0, sizeof(ioctl_args)); + ioctl_args.seek_speed = devs[i].class; + strcpy(ioctl_args.name, devs[i].file); + res = ioctl(fdmnt, BTRFS_IOC_ADD_DEV_V2, &ioctl_args); if(res<0){ - fprintf(stderr, "ERROR: error adding the device ''%s''\n", args[i]); + fprintf(stderr, "ERROR: error adding the device ''%s''\n", + devs[i].file); ret++; } diff --git a/ctree.h b/ctree.h index b79e238..192e8e8 100644 --- a/ctree.h +++ b/ctree.h @@ -130,6 +130,24 @@ static int btrfs_csum_sizes[] = { 4, 0 }; #define BTRFS_FT_MAX 9 /* + * default device classes (seek_speed indices) + * system chunks are considered metadata for this classification + */ + +#define BTRFS_DEVCLASS_LOG 75 /* dedicated to log data */ +#define BTRFS_DEVCLASS_META 45 /* metadata or log data */ +#define BTRFS_DEVCLASS_DATA 35 /* dedicated to user data */ +#define BTRFS_DEVCLASS_ALL 30 /* data, metadata or log data */ + +#define BTRFS_DEVCLASS_ALLOW_LOG(x) ((x) == BTRFS_DEVCLASS_LOG || \ + (x) == BTRFS_DEVCLASS_META || \ + (x) == BTRFS_DEVCLASS_ALL) +#define BTRFS_DEVCLASS_ALLOW_META(x) ((x) == BTRFS_DEVCLASS_META || \ + (x) == BTRFS_DEVCLASS_ALL) +#define BTRFS_DEVCLASS_ALLOW_DATA(x) ((x) == BTRFS_DEVCLASS_DATA || \ + (x) == BTRFS_DEVCLASS_ALL) + +/* * the key defines the order in the tree, and so it also defines (optimal) * block layout. objectid corresonds to the inode number. The flags * tells us things about the object, and is a kind of stream selector. @@ -755,6 +773,8 @@ struct btrfs_root { /* leaf allocations are done in leafsize units */ u32 stripesize; + int seek_speed; + int ref_cows; int track_dirty; diff --git a/ioctl-test.c b/ioctl-test.c index 7cf3bc2..c47469a 100644 --- a/ioctl-test.c +++ b/ioctl-test.c @@ -22,6 +22,7 @@ unsigned long ioctls[] = { BTRFS_IOC_INO_LOOKUP, BTRFS_IOC_DEFAULT_SUBVOL, BTRFS_IOC_SPACE_INFO, + BTRFS_IOC_ADD_DEV_V2, 0 }; int main(int ac, char **av) diff --git a/ioctl.h b/ioctl.h index b66cc29..2f38725 100644 --- a/ioctl.h +++ b/ioctl.h @@ -39,8 +39,10 @@ struct btrfs_ioctl_vol_args_v2 { __s64 fd; __u64 transid; __u64 flags; - __u64 unused[4]; - char name[BTRFS_SUBVOL_NAME_MAX + 1]; + __u8 seek_speed; + __u8 unused_u8[3]; + __u64 unused_u64[3]; + char name[BTRFS_PATH_NAME_MAX + 1]; }; #define BTRFS_INO_LOOKUP_PATH_MAX 4080 @@ -204,4 +206,6 @@ struct btrfs_ioctl_space_args { struct btrfs_ioctl_vol_args_v2) #define BTRFS_IOC_SUBVOL_GETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 25, __u64) #define BTRFS_IOC_SUBVOL_SETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 26, __u64) +#define BTRFS_IOC_ADD_DEV_V2 _IOW(BTRFS_IOCTL_MAGIC, 27, \ + struct btrfs_ioctl_vol_args_v2) #endif diff --git a/utils.c b/utils.c index 5fb82dc..f1477f3 100644 --- a/utils.c +++ b/utils.c @@ -522,12 +522,14 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, return 0; } -int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret) +int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret, + int class) { u64 block_count; u64 bytenr; struct stat st; int i, ret; + int mb_min = class == BTRFS_DEVCLASS_LOG ? 32 : 256; ret = fstat(fd, &st); if (ret < 0) { @@ -542,9 +544,9 @@ int btrfs_prepare_device(int fd, char *file, int zero_end, u64 *block_count_ret) } zero_end = 1; - if (block_count < 256 * 1024 * 1024) { + if (block_count < mb_min * 1024 * 1024) { fprintf(stderr, "device %s is too small " - "(must be at least 256 MB)\n", file); + "(must be at least %d MB)\n", file, mb_min); exit(1); } ret = zero_dev_start(fd); @@ -1029,3 +1031,17 @@ u64 parse_size(char *s) } return atoll(s) * mult; } + +int parse_class(const char *s) +{ + if (strcmp(s, "data") == 0) { + return BTRFS_DEVCLASS_DATA; + } else if (strcmp(s, "meta") == 0) { + return BTRFS_DEVCLASS_META; + } else if (strcmp(s, "all") == 0) { + return BTRFS_DEVCLASS_ALL; + } else if (strcmp(s, "log") == 0) { + return BTRFS_DEVCLASS_LOG; + } + return -1; +} diff --git a/utils.h b/utils.h index dc1b41d..981ffdb 100644 --- a/utils.h +++ b/utils.h @@ -27,7 +27,7 @@ int make_btrfs(int fd, const char *device, const char *label, int btrfs_make_root_dir(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 objectid); int btrfs_prepare_device(int fd, char *file, int zero_end, - u64 *block_count_ret); + u64 *block_count_ret, int class); int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, struct btrfs_root *root, int fd, char *path, u64 block_count, u32 io_width, u32 io_align, @@ -41,4 +41,10 @@ int btrfs_device_already_in_root(struct btrfs_root *root, int fd, int super_offset); char *pretty_sizes(u64 size); u64 parse_size(char *s); +int parse_class(const char *s); +struct btrfs_class_dev { + char *file; + int class; +}; + #endif -- 1.7.2.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Jan Schmidt
2011-Feb-01 13:54 UTC
[PATCH 5/7] speed classes (needed for profiles) for mkfs
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net> --- extent-tree.c | 11 +++-- mkfs.c | 122 ++++++++++++++++++++++++++++++++++++++++++-------------- utils.c | 7 ++- utils.h | 4 +- volumes.c | 13 +++++- volumes.h | 6 ++- 6 files changed, 121 insertions(+), 42 deletions(-) diff --git a/extent-tree.c b/extent-tree.c index b2f9bb2..b580b0c 100644 --- a/extent-tree.c +++ b/extent-tree.c @@ -1788,7 +1788,7 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags) static int do_chunk_alloc(struct btrfs_trans_handle *trans, struct btrfs_root *extent_root, u64 alloc_bytes, - u64 flags) + u64 flags, int seek_speed) { struct btrfs_space_info *space_info; u64 thresh; @@ -1812,7 +1812,8 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, thresh) return 0; - ret = btrfs_alloc_chunk(trans, extent_root, &start, &num_bytes, flags); + ret = btrfs_alloc_chunk(trans, extent_root, &start, &num_bytes, flags, + seek_speed); if (ret == -ENOSPC) { space_info->full = 1; return 0; @@ -2513,11 +2514,13 @@ static int btrfs_reserve_extent(struct btrfs_trans_handle *trans, if (!(data & BTRFS_BLOCK_GROUP_METADATA)) { ret = do_chunk_alloc(trans, root->fs_info->extent_root, num_bytes, - BTRFS_BLOCK_GROUP_METADATA); + BTRFS_BLOCK_GROUP_METADATA, + root->seek_speed); BUG_ON(ret); } ret = do_chunk_alloc(trans, root->fs_info->extent_root, - num_bytes + 2 * 1024 * 1024, data); + num_bytes + 2 * 1024 * 1024, data, + root->seek_speed); BUG_ON(ret); } diff --git a/mkfs.c b/mkfs.c index 0a80d1c..231448b 100644 --- a/mkfs.c +++ b/mkfs.c @@ -64,7 +64,8 @@ static int make_root_dir(struct btrfs_root *root) ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root, &chunk_start, &chunk_size, - BTRFS_BLOCK_GROUP_METADATA); + BTRFS_BLOCK_GROUP_METADATA, + root->seek_speed); BUG_ON(ret); ret = btrfs_make_block_group(trans, root, 0, BTRFS_BLOCK_GROUP_METADATA, @@ -77,16 +78,6 @@ static int make_root_dir(struct btrfs_root *root) trans = btrfs_start_transaction(root, 1); BUG_ON(!trans); - ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root, - &chunk_start, &chunk_size, - BTRFS_BLOCK_GROUP_DATA); - BUG_ON(ret); - ret = btrfs_make_block_group(trans, root, 0, - BTRFS_BLOCK_GROUP_DATA, - BTRFS_FIRST_CHUNK_TREE_OBJECTID, - chunk_start, chunk_size); - BUG_ON(ret); - ret = btrfs_make_root_dir(trans, root->fs_info->tree_root, BTRFS_ROOT_TREE_DIR_OBJECTID); if (ret) @@ -156,19 +147,19 @@ static int recow_roots(struct btrfs_trans_handle *trans, } static int create_one_raid_group(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 type) + struct btrfs_root *root, u64 type, int seek_speed) { u64 chunk_start; u64 chunk_size; int ret; ret = btrfs_alloc_chunk(trans, root->fs_info->extent_root, - &chunk_start, &chunk_size, type); - BUG_ON(ret); + &chunk_start, &chunk_size, type, seek_speed); + if (ret) + return ret; ret = btrfs_make_block_group(trans, root->fs_info->extent_root, 0, type, BTRFS_FIRST_CHUNK_TREE_OBJECTID, chunk_start, chunk_size); - BUG_ON(ret); return ret; } @@ -191,12 +182,14 @@ static int create_raid_groups(struct btrfs_trans_handle *trans, if (allowed & metadata_profile) { ret = create_one_raid_group(trans, root, BTRFS_BLOCK_GROUP_SYSTEM | - (allowed & metadata_profile)); + (allowed & metadata_profile), + root->seek_speed); BUG_ON(ret); ret = create_one_raid_group(trans, root, BTRFS_BLOCK_GROUP_METADATA | - (allowed & metadata_profile)); + (allowed & metadata_profile), + root->seek_speed); BUG_ON(ret); ret = recow_roots(trans, root); @@ -205,7 +198,8 @@ static int create_raid_groups(struct btrfs_trans_handle *trans, if (num_devices > 1 && (allowed & data_profile)) { ret = create_one_raid_group(trans, root, BTRFS_BLOCK_GROUP_DATA | - (allowed & data_profile)); + (allowed & data_profile), + root->seek_speed); BUG_ON(ret); } return 0; @@ -244,6 +238,8 @@ static void print_usage(void) fprintf(stderr, "options:\n"); fprintf(stderr, "\t -A --alloc-start the offset to start the FS\n"); fprintf(stderr, "\t -b --byte-count total number of bytes in the FS\n"); + fprintf(stderr, "\t -c --class {data|meta|log|all} valid until overridden by\n"); + fprintf(stderr, "\t next -c, default: all\n"); fprintf(stderr, "\t -d --data data profile, raid0, raid1, raid10 or single\n"); fprintf(stderr, "\t -l --leafsize size of btree leaves\n"); fprintf(stderr, "\t -L --label set a label\n"); @@ -305,10 +301,16 @@ static struct option long_options[] = { { "nodesize", 1, NULL, ''n'' }, { "sectorsize", 1, NULL, ''s'' }, { "data", 1, NULL, ''d'' }, + { "class", 1, NULL, ''c'' }, { "version", 0, NULL, ''V'' }, { 0, 0, 0, 0} }; +static const char opts_allowed_in_devlist[256] = { + [1] = 1, + [''c''] = 1, +}; + int main(int ac, char **av) { char *file; @@ -326,23 +328,61 @@ int main(int ac, char **av) u32 sectorsize = 4096; u32 nodesize = leafsize; u32 stripesize = 4096; + int class = BTRFS_DEVCLASS_ALL; int zero_end = 1; int option_index = 0; int fd; int first_fd; int ret; int i; + int devcnt = 0; + int devind = 0; + int alloc_dev = 0; + int first_dev = -1; + int data_devs = 0; + int meta_devs = 0; + struct btrfs_class_dev *devs = NULL; while(1) { int c; - c = getopt_long(ac, av, "A:b:l:n:s:m:d:L:V", long_options, + c = getopt_long(ac, av, "-A:b:c:l:n:s:m:d:L:V", long_options, &option_index); if (c < 0) break; + if (devcnt && !opts_allowed_in_devlist[c]) { + print_usage(); + } switch(c) { + case 1: + if (devcnt >= alloc_dev) { + alloc_dev += 10; + devs = realloc(devs, + alloc_dev*sizeof(*devs)); + } + devs[devcnt].file = av[optind-1]; + devs[devcnt].class = class; + if (BTRFS_DEVCLASS_ALLOW_DATA(class)) + data_devs++; + if (BTRFS_DEVCLASS_ALLOW_META(class)) + meta_devs++; + + if ((first_dev < 0 || + devs[first_dev].class!=BTRFS_DEVCLASS_META) + && BTRFS_DEVCLASS_ALLOW_META(class)) + first_dev = devcnt; + devcnt++; + break; case ''A'': alloc_start = parse_size(optarg); break; + case ''c'': + class = parse_class(optarg); + if (class == -1) { + fprintf(stderr, "Unknown class %s\n", + optarg); + print_usage(); + } + break; case ''d'': data_profile = parse_profile(optarg); break; @@ -388,14 +428,30 @@ int main(int ac, char **av) fprintf(stderr, "Illegal nodesize %u\n", nodesize); exit(1); } - ac = ac - optind; - if (ac == 0) + if (devcnt == 0) print_usage(); + if (meta_devs == 0 || data_devs == 0) { + fprintf(stderr, "Illegal setup. You will need space for data " + "and space for metadata.\n\n"); + print_usage(); + } printf("\nWARNING! - %s IS EXPERIMENTAL\n", BTRFS_BUILD_VERSION); printf("WARNING! - see http://btrfs.wiki.kernel.org before using\n\n"); - file = av[optind++]; + if (first_dev > 0) { + /* + * bootstrap chunks (meta/system) will be created on the first + * device during make_btrfs(). to create them on the preferred + * metadata device bring that to the front of the list. + */ + struct btrfs_class_dev tmp; + tmp = devs[0]; + devs[0] = devs[first_dev]; + devs[first_dev] = tmp; + } + + file = devs[0].file; ret = check_mounted(file); if (ret < 0) { fprintf(stderr, "error checking %s mount status\n", file); @@ -405,7 +461,6 @@ int main(int ac, char **av) fprintf(stderr, "%s is mounted\n", file); exit(1); } - ac--; fd = open(file, O_RDWR); if (fd < 0) { fprintf(stderr, "unable to open %s\n", file); @@ -413,7 +468,8 @@ int main(int ac, char **av) } first_fd = fd; first_file = file; - ret = btrfs_prepare_device(fd, file, zero_end, &dev_block_count); + ret = btrfs_prepare_device(fd, file, zero_end, &dev_block_count, + devs[0].class); if (block_count == 0) block_count = dev_block_count; @@ -423,9 +479,11 @@ int main(int ac, char **av) leafsize * i; } + printf("creating fs on %s, id 1\n", file); + ret = make_btrfs(fd, file, label, blocks, block_count, nodesize, leafsize, - sectorsize, stripesize); + sectorsize, stripesize, devs[0].class); if (ret) { fprintf(stderr, "error during mkfs %d\n", ret); exit(1); @@ -438,6 +496,7 @@ int main(int ac, char **av) } root->fs_info->alloc_start = alloc_start; + root->seek_speed = devs[0].class; ret = make_root_dir(root); if (ret) { @@ -447,14 +506,14 @@ int main(int ac, char **av) trans = btrfs_start_transaction(root, 1); - if (ac == 0) + if (devcnt == 1) goto raid_groups; btrfs_register_one_device(file); zero_end = 1; - while(ac-- > 0) { - file = av[optind++]; + while(++devind < devcnt) { + file = devs[devind].file; ret = check_mounted(file); if (ret < 0) { fprintf(stderr, "error checking %s mount status\n", @@ -478,13 +537,14 @@ int main(int ac, char **av) close(fd); continue; } - ret = btrfs_prepare_device(fd, file, zero_end, - &dev_block_count); + ret = btrfs_prepare_device(fd, file, zero_end, &dev_block_count, + devs[devind].class); BUG_ON(ret); ret = btrfs_add_to_fsid(trans, root, fd, file, dev_block_count, - sectorsize, sectorsize, sectorsize); + sectorsize, sectorsize, sectorsize, + devs[devind].class); BUG_ON(ret); btrfs_register_one_device(file); } diff --git a/utils.c b/utils.c index f1477f3..7134f03 100644 --- a/utils.c +++ b/utils.c @@ -62,7 +62,7 @@ static u64 reference_root_table[] = { int make_btrfs(int fd, const char *device, const char *label, u64 blocks[7], u64 num_bytes, u32 nodesize, - u32 leafsize, u32 sectorsize, u32 stripesize) + u32 leafsize, u32 sectorsize, u32 stripesize, int seek_speed) { struct btrfs_super_block super; struct extent_buffer *buf; @@ -269,6 +269,7 @@ int make_btrfs(int fd, const char *device, const char *label, btrfs_set_device_io_width(buf, dev_item, sectorsize); btrfs_set_device_sector_size(buf, dev_item, sectorsize); btrfs_set_device_type(buf, dev_item, 0); + btrfs_set_device_seek_speed(buf, dev_item, seek_speed); write_extent_buffer(buf, super.dev_item.uuid, (unsigned long)btrfs_device_uuid(dev_item), @@ -451,7 +452,7 @@ static int zero_dev_end(int fd, u64 dev_size) int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, struct btrfs_root *root, int fd, char *path, u64 block_count, u32 io_width, u32 io_align, - u32 sectorsize) + u32 sectorsize, int seek_speed) { struct btrfs_super_block *disk_super; struct btrfs_super_block *super = &root->fs_info->super_copy; @@ -487,6 +488,7 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, device->total_bytes = block_count; device->bytes_used = 0; device->total_ios = 0; + device->seek_speed = seek_speed; device->dev_root = root->fs_info->dev_root; ret = btrfs_add_device(trans, root, device); @@ -511,6 +513,7 @@ int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, btrfs_set_stack_device_sector_size(dev_item, device->sector_size); btrfs_set_stack_device_total_bytes(dev_item, device->total_bytes); btrfs_set_stack_device_bytes_used(dev_item, device->bytes_used); + btrfs_set_stack_device_seek_speed(dev_item, device->seek_speed); memcpy(&dev_item->uuid, device->uuid, BTRFS_UUID_SIZE); ret = pwrite(fd, buf, sectorsize, BTRFS_SUPER_INFO_OFFSET); diff --git a/utils.h b/utils.h index 981ffdb..6542f39 100644 --- a/utils.h +++ b/utils.h @@ -23,7 +23,7 @@ int make_btrfs(int fd, const char *device, const char *label, u64 blocks[6], u64 num_bytes, u32 nodesize, - u32 leafsize, u32 sectorsize, u32 stripesize); + u32 leafsize, u32 sectorsize, u32 stripesize, int seek_speed); int btrfs_make_root_dir(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 objectid); int btrfs_prepare_device(int fd, char *file, int zero_end, @@ -31,7 +31,7 @@ int btrfs_prepare_device(int fd, char *file, int zero_end, int btrfs_add_to_fsid(struct btrfs_trans_handle *trans, struct btrfs_root *root, int fd, char *path, u64 block_count, u32 io_width, u32 io_align, - u32 sectorsize); + u32 sectorsize, int seek_speed); int btrfs_scan_for_fsid(struct btrfs_fs_devices *fs_devices, u64 total_devs, int run_ioctls); void btrfs_register_one_device(char *fname); diff --git a/volumes.c b/volumes.c index 7671855..8507a84 100644 --- a/volumes.c +++ b/volumes.c @@ -29,6 +29,7 @@ #include "transaction.h" #include "print-tree.h" #include "volumes.h" +#include "utils.h" struct stripe { struct btrfs_device *dev; @@ -522,7 +523,7 @@ int btrfs_add_device(struct btrfs_trans_handle *trans, btrfs_set_device_total_bytes(leaf, dev_item, device->total_bytes); btrfs_set_device_bytes_used(leaf, dev_item, device->bytes_used); btrfs_set_device_group(leaf, dev_item, 0); - btrfs_set_device_seek_speed(leaf, dev_item, 0); + btrfs_set_device_seek_speed(leaf, dev_item, device->seek_speed); btrfs_set_device_bandwidth(leaf, dev_item, 0); btrfs_set_device_start_offset(leaf, dev_item, 0); @@ -577,6 +578,8 @@ int btrfs_update_device(struct btrfs_trans_handle *trans, btrfs_set_device_sector_size(leaf, dev_item, device->sector_size); btrfs_set_device_total_bytes(leaf, dev_item, device->total_bytes); btrfs_set_device_bytes_used(leaf, dev_item, device->bytes_used); + btrfs_set_device_seek_speed(leaf, dev_item, device->seek_speed); + btrfs_set_device_bandwidth(leaf, dev_item, 0); btrfs_mark_buffer_dirty(leaf); out: @@ -630,7 +633,7 @@ static u64 chunk_bytes_by_type(u64 type, u64 calc_size, int num_stripes, int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, struct btrfs_root *extent_root, u64 *start, - u64 *num_bytes, u64 type) + u64 *num_bytes, u64 type, int seek_speed) { u64 dev_offset; struct btrfs_fs_info *info = extent_root->fs_info; @@ -659,6 +662,8 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, int stripe_len = 64 * 1024; struct btrfs_key key; + BUG_ON(seek_speed <= 1); + if (list_empty(dev_list)) { return -ENOSPC; } @@ -735,6 +740,8 @@ again: device = list_entry(cur, struct btrfs_device, dev_list); avail = device->total_bytes - device->bytes_used; cur = cur->next; + if (device->seek_speed != seek_speed) + goto next; if (avail >= min_free) { list_move_tail(&device->dev_list, &private_devs); index++; @@ -742,6 +749,7 @@ again: index++; } else if (avail > max_avail) max_avail = avail; +next: if (cur == dev_list) break; } @@ -1233,6 +1241,7 @@ static int fill_device_from_item(struct extent_buffer *leaf, device->io_align = btrfs_device_io_align(leaf, dev_item); device->io_width = btrfs_device_io_width(leaf, dev_item); device->sector_size = btrfs_device_sector_size(leaf, dev_item); + device->seek_speed = btrfs_device_seek_speed(leaf, dev_item); ptr = (unsigned long)btrfs_device_uuid(dev_item); read_extent_buffer(leaf, device->uuid, ptr, BTRFS_UUID_SIZE); diff --git a/volumes.h b/volumes.h index bb78751..2ba9a24 100644 --- a/volumes.h +++ b/volumes.h @@ -57,6 +57,10 @@ struct btrfs_device { /* type and info about this device */ u64 type; + /* the speed is used to determine if the device should be a preferred + * log device */ + u8 seek_speed; + /* physical drive uuid (or lvm uuid) */ u8 uuid[BTRFS_UUID_SIZE]; }; @@ -106,7 +110,7 @@ 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 *start, - u64 *num_bytes, u64 type); + u64 *num_bytes, u64 type, int seek_speed); int btrfs_read_super_device(struct btrfs_root *root, struct extent_buffer *buf); int btrfs_add_device(struct btrfs_trans_handle *trans, struct btrfs_root *root, -- 1.7.2.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Jan Schmidt
2011-Feb-01 13:54 UTC
[PATCH 6/7] debug-tree output: device speed added; type output switched to hex
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net> --- print-tree.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/print-tree.c b/print-tree.c index ac575d5..79a2f21 100644 --- a/print-tree.c +++ b/print-tree.c @@ -83,7 +83,7 @@ static void print_chunk(struct extent_buffer *eb, struct btrfs_chunk *chunk) { int num_stripes = btrfs_chunk_num_stripes(eb, chunk); int i; - printf("\t\tchunk length %llu owner %llu type %llu num_stripes %d\n", + printf("\t\tchunk length %llu owner %llu type 0x%llx num_stripes %d\n", (unsigned long long)btrfs_chunk_length(eb, chunk), (unsigned long long)btrfs_chunk_owner(eb, chunk), (unsigned long long)btrfs_chunk_type(eb, chunk), @@ -98,10 +98,11 @@ static void print_dev_item(struct extent_buffer *eb, struct btrfs_dev_item *dev_item) { printf("\t\tdev item devid %llu " - "total_bytes %llu bytes used %Lu\n", + "total_bytes %llu bytes used %Lu speed %u\n", (unsigned long long)btrfs_device_id(eb, dev_item), (unsigned long long)btrfs_device_total_bytes(eb, dev_item), - (unsigned long long)btrfs_device_bytes_used(eb, dev_item)); + (unsigned long long)btrfs_device_bytes_used(eb, dev_item), + btrfs_device_seek_speed(eb, dev_item)); } static void print_uuids(struct extent_buffer *eb) -- 1.7.2.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Jan Schmidt
2011-Feb-01 13:54 UTC
[PATCH 7/7] made btrfs-vol compile. looks unused, so no speed class support here for now.
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net> --- btrfs-vol.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/btrfs-vol.c b/btrfs-vol.c index 4ed799d..138c69c 100644 --- a/btrfs-vol.c +++ b/btrfs-vol.c @@ -143,7 +143,8 @@ int main(int ac, char **av) exit(1); } if (cmd == BTRFS_IOC_ADD_DEV) { - ret = btrfs_prepare_device(devfd, device, 1, &dev_block_count); + ret = btrfs_prepare_device(devfd, device, 1, &dev_block_count, + BTRFS_DEVCLASS_ALL); if (ret) { fprintf(stderr, "Unable to init %s\n", device); exit(1); -- 1.7.2.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html