nbd: Clean up ioctl handling of qemu-nbd -c
The kernel ioctl() interface into NBD is limited to 'unsigned long'; we MUST pass in input with that type (and not int or size_t, as there may be platform ABIs where the wrong types promote incorrectly through var-args). Furthermore, on 32-bit platforms, the kernel is limited to a maximum export size of 2T (our BLKSIZE of 512 times a SIZE_BLOCKS constrained by 32 bit unsigned long). Signed-off-by: Eric Blake <eblake@redhat.com> Message-Id: <1463006384-7734-8-git-send-email-eblake@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
98494e3b92
commit
f57e2416aa
20
nbd/client.c
20
nbd/client.c
@ -593,9 +593,15 @@ fail:
|
||||
#ifdef __linux__
|
||||
int nbd_init(int fd, QIOChannelSocket *sioc, uint32_t flags, off_t size)
|
||||
{
|
||||
unsigned long sectors = size / BDRV_SECTOR_SIZE;
|
||||
if (size / BDRV_SECTOR_SIZE != sectors) {
|
||||
LOG("Export size %lld too large for 32-bit kernel", (long long) size);
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
TRACE("Setting NBD socket");
|
||||
|
||||
if (ioctl(fd, NBD_SET_SOCK, sioc->fd) < 0) {
|
||||
if (ioctl(fd, NBD_SET_SOCK, (unsigned long) sioc->fd) < 0) {
|
||||
int serrno = errno;
|
||||
LOG("Failed to set NBD socket");
|
||||
return -serrno;
|
||||
@ -603,21 +609,25 @@ int nbd_init(int fd, QIOChannelSocket *sioc, uint32_t flags, off_t size)
|
||||
|
||||
TRACE("Setting block size to %lu", (unsigned long)BDRV_SECTOR_SIZE);
|
||||
|
||||
if (ioctl(fd, NBD_SET_BLKSIZE, (size_t)BDRV_SECTOR_SIZE) < 0) {
|
||||
if (ioctl(fd, NBD_SET_BLKSIZE, (unsigned long)BDRV_SECTOR_SIZE) < 0) {
|
||||
int serrno = errno;
|
||||
LOG("Failed setting NBD block size");
|
||||
return -serrno;
|
||||
}
|
||||
|
||||
TRACE("Setting size to %zd block(s)", (size_t)(size / BDRV_SECTOR_SIZE));
|
||||
TRACE("Setting size to %lu block(s)", sectors);
|
||||
if (size % BDRV_SECTOR_SIZE) {
|
||||
TRACE("Ignoring trailing %d bytes of export",
|
||||
(int) (size % BDRV_SECTOR_SIZE));
|
||||
}
|
||||
|
||||
if (ioctl(fd, NBD_SET_SIZE_BLOCKS, (size_t)(size / BDRV_SECTOR_SIZE)) < 0) {
|
||||
if (ioctl(fd, NBD_SET_SIZE_BLOCKS, sectors) < 0) {
|
||||
int serrno = errno;
|
||||
LOG("Failed setting size (in blocks)");
|
||||
return -serrno;
|
||||
}
|
||||
|
||||
if (ioctl(fd, NBD_SET_FLAGS, flags) < 0) {
|
||||
if (ioctl(fd, NBD_SET_FLAGS, (unsigned long) flags) < 0) {
|
||||
if (errno == ENOTTY) {
|
||||
int read_only = (flags & NBD_FLAG_READ_ONLY) != 0;
|
||||
TRACE("Setting readonly attribute");
|
||||
|
Loading…
Reference in New Issue
Block a user