diff options
author | Ekaterina Tumanova <tumanova@linux.vnet.ibm.com> | 2015-02-16 12:47:55 +0100 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2015-03-10 14:02:21 +0100 |
commit | 8a4ed0d1b16d8932362ffecf8f6f79e6340a585f (patch) | |
tree | 876621115ba670ef557750aa2489c78abcd1e00b /block/raw-posix.c | |
parent | 892b7de832681cdfff22a6e96cb0280b59684024 (diff) |
raw-posix: Factor block size detection out of raw_probe_alignment()
Put it in new probe_logical_blocksize().
Signed-off-by: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1424087278-49393-3-git-send-email-tumanova@linux.vnet.ibm.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block/raw-posix.c')
-rw-r--r-- | block/raw-posix.c | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/block/raw-posix.c b/block/raw-posix.c index c0b46cac9e..34d403d391 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -218,39 +218,58 @@ static int raw_normalize_devicepath(const char **filename) } #endif -static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp) +/* + * Get logical block size via ioctl. On success store it in @sector_size_p. + */ +static int probe_logical_blocksize(int fd, unsigned int *sector_size_p) { - BDRVRawState *s = bs->opaque; - char *buf; unsigned int sector_size; + bool success = false; - /* For /dev/sg devices the alignment is not really used. - With buffered I/O, we don't have any restrictions. */ - if (bs->sg || !s->needs_alignment) { - bs->request_alignment = 1; - s->buf_align = 1; - return; - } + errno = ENOTSUP; /* Try a few ioctls to get the right size */ - bs->request_alignment = 0; - s->buf_align = 0; - #ifdef BLKSSZGET if (ioctl(fd, BLKSSZGET, §or_size) >= 0) { - bs->request_alignment = sector_size; + *sector_size_p = sector_size; + success = true; } #endif #ifdef DKIOCGETBLOCKSIZE if (ioctl(fd, DKIOCGETBLOCKSIZE, §or_size) >= 0) { - bs->request_alignment = sector_size; + *sector_size_p = sector_size; + success = true; } #endif #ifdef DIOCGSECTORSIZE if (ioctl(fd, DIOCGSECTORSIZE, §or_size) >= 0) { - bs->request_alignment = sector_size; + *sector_size_p = sector_size; + success = true; } #endif + + return success ? 0 : -errno; +} + +static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp) +{ + BDRVRawState *s = bs->opaque; + char *buf; + + /* For /dev/sg devices the alignment is not really used. + With buffered I/O, we don't have any restrictions. */ + if (bs->sg || !s->needs_alignment) { + bs->request_alignment = 1; + s->buf_align = 1; + return; + } + + bs->request_alignment = 0; + s->buf_align = 0; + /* Let's try to use the logical blocksize for the alignment. */ + if (probe_logical_blocksize(fd, &bs->request_alignment) < 0) { + bs->request_alignment = 0; + } #ifdef CONFIG_XFS if (s->is_xfs) { struct dioattr da; |