summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2013-07-17 12:39:14 +0200
committerKent Overstreet <kmo@daterainc.com>2013-07-17 13:13:31 -0700
commit7721b11a6095b10127621bf78a3b3462bb67e696 (patch)
tree6197491f6e77b2174b7da4b549e614dfe459d816
parent557c79518c0fc9a319f2df1473b38973d445a272 (diff)
fix make-bcache to use logical_block_size, not stat.st_blocksize
As discussed on irc yesterday. Cheers, Lars From 791a4b7b2c25e21ffeb4184da5e61f18cde86246 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg <lars@linbit.com> Date: Wed, 17 Jul 2013 11:49:12 +0200 Subject: [PATCH] make-bcache: fix guessing of "block_size" to use BLKSSZGET Using stat.st_blocksize is wrong: that is the linux buffer cache granularity, it is tunable, and defaults to 4k. This caused bcache to default to create devices with logical_block_size = 4k, potentially breaking otherwise healthy disk or file system images unnecessarily. e.g. some xfs image previously created with 512 byte "sector size" would, once bcache'd, refuse to mount with mount: function not implemented device supports 4096 byte sectors (not 512) We want the logical_block_size here.
-rw-r--r--make-bcache.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/make-bcache.c b/make-bcache.c
index 6ffe89e..9c038a8 100644
--- a/make-bcache.c
+++ b/make-bcache.c
@@ -269,6 +269,37 @@ static unsigned get_blocksize(const char *path)
exit(EXIT_FAILURE);
}
+ if (S_ISBLK(statbuf.st_mode)) {
+ /* check IO limits:
+ * BLKALIGNOFF: alignment_offset
+ * BLKPBSZGET: physical_block_size
+ * BLKSSZGET: logical_block_size
+ * BLKIOMIN: minimum_io_size
+ * BLKIOOPT: optimal_io_size
+ *
+ * It may be tempting to use physical_block_size,
+ * or even minimum_io_size.
+ * But to be as transparent as possible,
+ * we want to use logical_block_size.
+ */
+ unsigned int logical_block_size;
+ int fd = open(path, O_RDONLY);
+
+ if (fd < 0) {
+ fprintf(stderr, "open(%s) failed: %m\n", path);
+ exit(EXIT_FAILURE);
+ }
+ if (ioctl(fd, BLKSSZGET, &logical_block_size)) {
+ fprintf(stderr, "ioctl(%s, BLKSSZGET) failed: %m\n", path);
+ exit(EXIT_FAILURE);
+ }
+ close(fd);
+ return logical_block_size / 512;
+
+ }
+ /* else: not a block device.
+ * Why would we even want to write a bcache super block there? */
+
return statbuf.st_blksize / 512;
}