diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2013-07-17 12:39:14 +0200 |
---|---|---|
committer | Kent Overstreet <kmo@daterainc.com> | 2013-07-17 13:13:31 -0700 |
commit | 7721b11a6095b10127621bf78a3b3462bb67e696 (patch) | |
tree | 6197491f6e77b2174b7da4b549e614dfe459d816 | |
parent | 557c79518c0fc9a319f2df1473b38973d445a272 (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.c | 31 |
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; } |