Blame Btrfs-progs-detect-if-the-disk-we-are-formatting-is-.patch

Josef Bacik 0124ba
diff -up btrfs-progs-0.20.rc1.20121017git91d9eec/Makefile.patch4 btrfs-progs-0.20.rc1.20121017git91d9eec/Makefile
Josef Bacik 0124ba
--- btrfs-progs-0.20.rc1.20121017git91d9eec/Makefile.patch4	2012-10-04 20:35:31.000000000 -0400
Josef Bacik 0124ba
+++ btrfs-progs-0.20.rc1.20121017git91d9eec/Makefile	2012-10-17 13:48:02.331453645 -0400
Josef Bacik 0124ba
@@ -67,7 +67,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 0124ba
diff -up btrfs-progs-0.20.rc1.20121017git91d9eec/man/mkfs.btrfs.8.in.patch4 btrfs-progs-0.20.rc1.20121017git91d9eec/man/mkfs.btrfs.8.in
Josef Bacik 0124ba
--- btrfs-progs-0.20.rc1.20121017git91d9eec/man/mkfs.btrfs.8.in.patch4	2012-10-04 20:35:31.000000000 -0400
Josef Bacik 0124ba
+++ btrfs-progs-0.20.rc1.20121017git91d9eec/man/mkfs.btrfs.8.in	2012-10-17 13:48:02.331453645 -0400
Josef Bacik 0124ba
@@ -47,7 +47,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 0124ba
diff -up btrfs-progs-0.20.rc1.20121017git91d9eec/mkfs.c.patch4 btrfs-progs-0.20.rc1.20121017git91d9eec/mkfs.c
Josef Bacik 0124ba
--- btrfs-progs-0.20.rc1.20121017git91d9eec/mkfs.c.patch4	2012-10-17 13:48:02.329453660 -0400
Josef Bacik 0124ba
+++ btrfs-progs-0.20.rc1.20121017git91d9eec/mkfs.c	2012-10-17 13:53:36.954806793 -0400
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 0124ba
@@ -234,7 +235,7 @@ static int create_one_raid_group(struct
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 0124ba
@@ -245,8 +246,12 @@ static int create_raid_groups(struct btr
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 0124ba
@@ -1215,6 +1220,49 @@ static int check_leaf_or_node_size(u32 s
Josef Bacik 0124ba
 	return 0;
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 0124ba
@@ -1241,6 +1289,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 0124ba
@@ -1360,6 +1409,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 0124ba
@@ -1445,7 +1497,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