|
Josef Bacik |
b5e03c |
From f507119002c6bb972df09a47edfa8998c0fc8172 Mon Sep 17 00:00:00 2001
|
|
Josef Bacik |
b5e03c |
From: Josef Bacik <jbacik@fusionio.com>
|
|
Josef Bacik |
b5e03c |
Date: Fri, 20 Jul 2012 11:09:43 -0400
|
|
Josef Bacik |
b5e03c |
Subject: [PATCH 2/3] Btrfs-progs: detect if the disk we are formatting is a
|
|
Josef Bacik |
b5e03c |
ssd
|
|
Josef Bacik |
b5e03c |
|
|
Josef Bacik |
b5e03c |
SSD's do not gain anything by having metadata DUP turned on. The underlying
|
|
Josef Bacik |
b5e03c |
file system that is a part of all SSD's could easily map duplicate metadat
|
|
Josef Bacik |
b5e03c |
blocks into the same erase block which effectively eliminates the benefit of
|
|
Josef Bacik |
b5e03c |
duplicating the metadata on disk. So detect if we are formatting a single
|
|
Josef Bacik |
b5e03c |
SSD drive and if we are do not use DUP. Thanks,
|
|
Josef Bacik |
b5e03c |
|
|
Josef Bacik |
b5e03c |
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
|
|
Josef Bacik |
b5e03c |
---
|
|
Josef Bacik |
b5e03c |
Makefile | 2 +-
|
|
Josef Bacik |
b5e03c |
man/mkfs.btrfs.8.in | 5 +++-
|
|
Josef Bacik |
b5e03c |
mkfs.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++--
|
|
Josef Bacik |
b5e03c |
3 files changed, 60 insertions(+), 5 deletions(-)
|
|
Josef Bacik |
b5e03c |
|
|
Josef Bacik |
b5e03c |
diff --git a/Makefile b/Makefile
|
|
Josef Bacik |
b5e03c |
index c0aaa3d..1afef49 100644
|
|
Josef Bacik |
b5e03c |
--- a/Makefile
|
|
Josef Bacik |
b5e03c |
+++ b/Makefile
|
|
Josef Bacik |
b5e03c |
@@ -66,7 +66,7 @@ btrfsck: $(objects) btrfsck.o
|
|
Josef Bacik |
b5e03c |
$(CC) $(CFLAGS) -o btrfsck btrfsck.o $(objects) $(LDFLAGS) $(LIBS)
|
|
Josef Bacik |
b5e03c |
|
|
Josef Bacik |
b5e03c |
mkfs.btrfs: $(objects) mkfs.o
|
|
Josef Bacik |
b5e03c |
- $(CC) $(CFLAGS) -o mkfs.btrfs $(objects) mkfs.o $(LDFLAGS) $(LIBS)
|
|
Josef Bacik |
b5e03c |
+ $(CC) $(CFLAGS) -o mkfs.btrfs $(objects) mkfs.o $(LDFLAGS) $(LIBS) -lblkid
|
|
Josef Bacik |
b5e03c |
|
|
Josef Bacik |
b5e03c |
btrfs-debug-tree: $(objects) debug-tree.o
|
|
Josef Bacik |
b5e03c |
$(CC) $(CFLAGS) -o btrfs-debug-tree $(objects) debug-tree.o $(LDFLAGS) $(LIBS)
|
|
Josef Bacik |
b5e03c |
diff --git a/man/mkfs.btrfs.8.in b/man/mkfs.btrfs.8.in
|
|
Josef Bacik |
b5e03c |
index fc2e1d2..dfa7996 100644
|
|
Josef Bacik |
b5e03c |
--- a/man/mkfs.btrfs.8.in
|
|
Josef Bacik |
b5e03c |
+++ b/man/mkfs.btrfs.8.in
|
|
Josef Bacik |
b5e03c |
@@ -46,7 +46,10 @@ Specify a label for the filesystem.
|
|
Josef Bacik |
b5e03c |
.TP
|
|
Josef Bacik |
b5e03c |
\fB\-m\fR, \fB\-\-metadata \fIprofile\fR
|
|
Josef Bacik |
b5e03c |
Specify how metadata must be spanned across the devices specified. Valid
|
|
Josef Bacik |
b5e03c |
-values are raid0, raid1, raid10 or single.
|
|
Josef Bacik |
b5e03c |
+values are raid0, raid1, raid10, single or dup. Single device will have dup
|
|
Josef Bacik |
b5e03c |
+set by default except in the case of SSDs which will default to single. This is
|
|
Josef Bacik |
b5e03c |
+because SSDs can remap blocks internally so duplicate blocks could end up in the
|
|
Josef Bacik |
b5e03c |
+same erase block which negates the benefits of doing metadata duplication.
|
|
Josef Bacik |
b5e03c |
.TP
|
|
Josef Bacik |
b5e03c |
\fB\-M\fR, \fB\-\-mixed\fR
|
|
Josef Bacik |
b5e03c |
Mix data and metadata chunks together for more efficient space
|
|
Josef Bacik |
b5e03c |
diff --git a/mkfs.c b/mkfs.c
|
|
Josef Bacik |
b5e03c |
index dff5eb8..8816db8 100644
|
|
Josef Bacik |
b5e03c |
--- a/mkfs.c
|
|
Josef Bacik |
b5e03c |
+++ b/mkfs.c
|
|
Josef Bacik |
b5e03c |
@@ -37,6 +37,7 @@
|
|
Josef Bacik |
b5e03c |
#include <linux/fs.h>
|
|
Josef Bacik |
b5e03c |
#include <ctype.h>
|
|
Josef Bacik |
b5e03c |
#include <attr/xattr.h>
|
|
Josef Bacik |
b5e03c |
+#include <blkid/blkid.h>
|
|
Josef Bacik |
b5e03c |
#include "kerncompat.h"
|
|
Josef Bacik |
b5e03c |
#include "ctree.h"
|
|
Josef Bacik |
b5e03c |
#include "disk-io.h"
|
|
Josef Bacik |
b5e03c |
@@ -234,7 +235,7 @@ static int create_one_raid_group(struct btrfs_trans_handle *trans,
|
|
Josef Bacik |
b5e03c |
static int create_raid_groups(struct btrfs_trans_handle *trans,
|
|
Josef Bacik |
b5e03c |
struct btrfs_root *root, u64 data_profile,
|
|
Josef Bacik |
b5e03c |
int data_profile_opt, u64 metadata_profile,
|
|
Josef Bacik |
b5e03c |
- int metadata_profile_opt, int mixed)
|
|
Josef Bacik |
b5e03c |
+ int metadata_profile_opt, int mixed, int ssd)
|
|
Josef Bacik |
b5e03c |
{
|
|
Josef Bacik |
b5e03c |
u64 num_devices = btrfs_super_num_devices(&root->fs_info->super_copy);
|
|
Josef Bacik |
b5e03c |
u64 allowed;
|
|
Josef Bacik |
b5e03c |
@@ -245,8 +246,12 @@ static int create_raid_groups(struct btrfs_trans_handle *trans,
|
|
Josef Bacik |
b5e03c |
* For mixed groups defaults are single/single.
|
|
Josef Bacik |
b5e03c |
*/
|
|
Josef Bacik |
b5e03c |
if (!metadata_profile_opt && !mixed) {
|
|
Josef Bacik |
b5e03c |
+ if (num_devices == 1 && ssd)
|
|
Josef Bacik |
b5e03c |
+ printf("Detected a SSD, turning off metadata "
|
|
Josef Bacik |
b5e03c |
+ "duplication. Mkfs with -m dup if you want to "
|
|
Josef Bacik |
b5e03c |
+ "force metadata duplication.\n");
|
|
Josef Bacik |
b5e03c |
metadata_profile = (num_devices > 1) ?
|
|
Josef Bacik |
b5e03c |
- BTRFS_BLOCK_GROUP_RAID1 : BTRFS_BLOCK_GROUP_DUP;
|
|
Josef Bacik |
b5e03c |
+ BTRFS_BLOCK_GROUP_RAID1 : (ssd) ? 0: BTRFS_BLOCK_GROUP_DUP;
|
|
Josef Bacik |
b5e03c |
}
|
|
Josef Bacik |
b5e03c |
if (!data_profile_opt && !mixed) {
|
|
Josef Bacik |
b5e03c |
data_profile = (num_devices > 1) ?
|
|
Josef Bacik |
b5e03c |
@@ -1201,6 +1206,49 @@ static int zero_output_file(int out_fd, u64 size, u32 sectorsize)
|
|
Josef Bacik |
b5e03c |
return ret;
|
|
Josef Bacik |
b5e03c |
}
|
|
Josef Bacik |
b5e03c |
|
|
Josef Bacik |
b5e03c |
+static int is_ssd(const char *file)
|
|
Josef Bacik |
b5e03c |
+{
|
|
Josef Bacik |
b5e03c |
+ char *devname;
|
|
Josef Bacik |
b5e03c |
+ blkid_probe probe;
|
|
Josef Bacik |
b5e03c |
+ char *dev;
|
|
Josef Bacik |
b5e03c |
+ char path[PATH_MAX];
|
|
Josef Bacik |
b5e03c |
+ dev_t disk;
|
|
Josef Bacik |
b5e03c |
+ int fd;
|
|
Josef Bacik |
b5e03c |
+ char rotational;
|
|
Josef Bacik |
b5e03c |
+
|
|
Josef Bacik |
b5e03c |
+ probe = blkid_new_probe_from_filename(file);
|
|
Josef Bacik |
b5e03c |
+ if (!probe)
|
|
Josef Bacik |
b5e03c |
+ return 0;
|
|
Josef Bacik |
b5e03c |
+
|
|
Josef Bacik |
b5e03c |
+ /*
|
|
Josef Bacik |
b5e03c |
+ * We want to use blkid_devno_to_wholedisk() but it's broken for some
|
|
Josef Bacik |
b5e03c |
+ * reason on F17 at least so we'll do this trickery
|
|
Josef Bacik |
b5e03c |
+ */
|
|
Josef Bacik |
b5e03c |
+ disk = blkid_probe_get_wholedisk_devno(probe);
|
|
Josef Bacik |
b5e03c |
+ devname = blkid_devno_to_devname(disk);
|
|
Josef Bacik |
b5e03c |
+
|
|
Josef Bacik |
b5e03c |
+ dev = strrchr(devname, '/');
|
|
Josef Bacik |
b5e03c |
+ dev++;
|
|
Josef Bacik |
b5e03c |
+
|
|
Josef Bacik |
b5e03c |
+ snprintf(path, PATH_MAX, "/sys/block/%s/queue/rotational", dev);
|
|
Josef Bacik |
b5e03c |
+
|
|
Josef Bacik |
b5e03c |
+ free(devname);
|
|
Josef Bacik |
b5e03c |
+ blkid_free_probe(probe);
|
|
Josef Bacik |
b5e03c |
+
|
|
Josef Bacik |
b5e03c |
+ fd = open(path, O_RDONLY);
|
|
Josef Bacik |
b5e03c |
+ if (fd < 0) {
|
|
Josef Bacik |
b5e03c |
+ return 0;
|
|
Josef Bacik |
b5e03c |
+ }
|
|
Josef Bacik |
b5e03c |
+
|
|
Josef Bacik |
b5e03c |
+ if (read(fd, &rotational, sizeof(char)) < sizeof(char)) {
|
|
Josef Bacik |
b5e03c |
+ close(fd);
|
|
Josef Bacik |
b5e03c |
+ return 0;
|
|
Josef Bacik |
b5e03c |
+ }
|
|
Josef Bacik |
b5e03c |
+ close(fd);
|
|
Josef Bacik |
b5e03c |
+
|
|
Josef Bacik |
b5e03c |
+ return !atoi((const char *)&rotational);
|
|
Josef Bacik |
b5e03c |
+}
|
|
Josef Bacik |
b5e03c |
+
|
|
Josef Bacik |
b5e03c |
int main(int ac, char **av)
|
|
Josef Bacik |
b5e03c |
{
|
|
Josef Bacik |
b5e03c |
char *file;
|
|
Josef Bacik |
b5e03c |
@@ -1227,6 +1275,7 @@ int main(int ac, char **av)
|
|
Josef Bacik |
b5e03c |
int data_profile_opt = 0;
|
|
Josef Bacik |
b5e03c |
int metadata_profile_opt = 0;
|
|
Josef Bacik |
b5e03c |
int nodiscard = 0;
|
|
Josef Bacik |
b5e03c |
+ int ssd = 0;
|
|
Josef Bacik |
b5e03c |
|
|
Josef Bacik |
b5e03c |
char *source_dir = NULL;
|
|
Josef Bacik |
b5e03c |
int source_dir_set = 0;
|
|
Josef Bacik |
b5e03c |
@@ -1352,6 +1401,9 @@ int main(int ac, char **av)
|
|
Josef Bacik |
b5e03c |
exit(1);
|
|
Josef Bacik |
b5e03c |
}
|
|
Josef Bacik |
b5e03c |
}
|
|
Josef Bacik |
b5e03c |
+
|
|
Josef Bacik |
b5e03c |
+ ssd = is_ssd(file);
|
|
Josef Bacik |
b5e03c |
+
|
|
Josef Bacik |
b5e03c |
if (mixed) {
|
|
Josef Bacik |
b5e03c |
if (metadata_profile != data_profile) {
|
|
Josef Bacik |
b5e03c |
fprintf(stderr, "With mixed block groups data and metadata "
|
|
Josef Bacik |
b5e03c |
@@ -1438,7 +1490,7 @@ raid_groups:
|
|
Josef Bacik |
b5e03c |
if (!source_dir_set) {
|
|
Josef Bacik |
b5e03c |
ret = create_raid_groups(trans, root, data_profile,
|
|
Josef Bacik |
b5e03c |
data_profile_opt, metadata_profile,
|
|
Josef Bacik |
b5e03c |
- metadata_profile_opt, mixed);
|
|
Josef Bacik |
b5e03c |
+ metadata_profile_opt, mixed, ssd);
|
|
Josef Bacik |
b5e03c |
BUG_ON(ret);
|
|
Josef Bacik |
b5e03c |
}
|
|
Josef Bacik |
b5e03c |
|
|
Josef Bacik |
b5e03c |
--
|
|
Josef Bacik |
b5e03c |
1.7.7.6
|
|
Josef Bacik |
b5e03c |
|