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