nbd/server: Favor [u]int64_t over off_t
Although our compile-time environment is set up so that we always support long files with 64-bit off_t, we have no guarantee whether off_t is the same type as int64_t. This requires casts when printing values, and prevents us from directly using qemu_strtoi64() (which will be done in the next patch). Let's just flip to uint64_t where possible, and stick to int64_t for detecting failure of blk_getlength(); we also keep the assertions added in the previous patch that the resulting values fit in 63 bits. The overflow check in nbd_co_receive_request() was already sane (request->from is validated to fit in 63 bits, and request->len is 32 bits, so the addition can't overflow 64 bits), but rewrite it in a form easier to recognize as a typical overflow check. Rename the variable 'description' to keep line lengths reasonable. Suggested-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Signed-off-by: Eric Blake <eblake@redhat.com> Message-Id: <20190117193658.16413-7-eblake@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
This commit is contained in:
parent
7596bbb390
commit
9d26dfcbab
@ -294,8 +294,8 @@ int nbd_errno_to_system_errno(int err);
|
|||||||
typedef struct NBDExport NBDExport;
|
typedef struct NBDExport NBDExport;
|
||||||
typedef struct NBDClient NBDClient;
|
typedef struct NBDClient NBDClient;
|
||||||
|
|
||||||
NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size,
|
NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset,
|
||||||
const char *name, const char *description,
|
uint64_t size, const char *name, const char *desc,
|
||||||
const char *bitmap, uint16_t nbdflags,
|
const char *bitmap, uint16_t nbdflags,
|
||||||
void (*close)(NBDExport *), bool writethrough,
|
void (*close)(NBDExport *), bool writethrough,
|
||||||
BlockBackend *on_eject_blk, Error **errp);
|
BlockBackend *on_eject_blk, Error **errp);
|
||||||
|
18
nbd/server.c
18
nbd/server.c
@ -77,8 +77,8 @@ struct NBDExport {
|
|||||||
BlockBackend *blk;
|
BlockBackend *blk;
|
||||||
char *name;
|
char *name;
|
||||||
char *description;
|
char *description;
|
||||||
off_t dev_offset;
|
uint64_t dev_offset;
|
||||||
off_t size;
|
uint64_t size;
|
||||||
uint16_t nbdflags;
|
uint16_t nbdflags;
|
||||||
QTAILQ_HEAD(, NBDClient) clients;
|
QTAILQ_HEAD(, NBDClient) clients;
|
||||||
QTAILQ_ENTRY(NBDExport) next;
|
QTAILQ_ENTRY(NBDExport) next;
|
||||||
@ -1455,8 +1455,8 @@ static void nbd_eject_notifier(Notifier *n, void *data)
|
|||||||
nbd_export_close(exp);
|
nbd_export_close(exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size,
|
NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset,
|
||||||
const char *name, const char *description,
|
uint64_t size, const char *name, const char *desc,
|
||||||
const char *bitmap, uint16_t nbdflags,
|
const char *bitmap, uint16_t nbdflags,
|
||||||
void (*close)(NBDExport *), bool writethrough,
|
void (*close)(NBDExport *), bool writethrough,
|
||||||
BlockBackend *on_eject_blk, Error **errp)
|
BlockBackend *on_eject_blk, Error **errp)
|
||||||
@ -1495,12 +1495,12 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size,
|
|||||||
exp->refcount = 1;
|
exp->refcount = 1;
|
||||||
QTAILQ_INIT(&exp->clients);
|
QTAILQ_INIT(&exp->clients);
|
||||||
exp->blk = blk;
|
exp->blk = blk;
|
||||||
assert(dev_offset >= 0 && dev_offset <= INT64_MAX);
|
assert(dev_offset <= INT64_MAX);
|
||||||
exp->dev_offset = dev_offset;
|
exp->dev_offset = dev_offset;
|
||||||
exp->name = g_strdup(name);
|
exp->name = g_strdup(name);
|
||||||
exp->description = g_strdup(description);
|
exp->description = g_strdup(desc);
|
||||||
exp->nbdflags = nbdflags;
|
exp->nbdflags = nbdflags;
|
||||||
assert(size >= 0 && size <= INT64_MAX - dev_offset);
|
assert(size <= INT64_MAX - dev_offset);
|
||||||
exp->size = QEMU_ALIGN_DOWN(size, BDRV_SECTOR_SIZE);
|
exp->size = QEMU_ALIGN_DOWN(size, BDRV_SECTOR_SIZE);
|
||||||
|
|
||||||
if (bitmap) {
|
if (bitmap) {
|
||||||
@ -2130,10 +2130,10 @@ static int nbd_co_receive_request(NBDRequestData *req, NBDRequest *request,
|
|||||||
return -EROFS;
|
return -EROFS;
|
||||||
}
|
}
|
||||||
if (request->from > client->exp->size ||
|
if (request->from > client->exp->size ||
|
||||||
request->from + request->len > client->exp->size) {
|
request->len > client->exp->size - request->from) {
|
||||||
error_setg(errp, "operation past EOF; From: %" PRIu64 ", Len: %" PRIu32
|
error_setg(errp, "operation past EOF; From: %" PRIu64 ", Len: %" PRIu32
|
||||||
", Size: %" PRIu64, request->from, request->len,
|
", Size: %" PRIu64, request->from, request->len,
|
||||||
(uint64_t)client->exp->size);
|
client->exp->size);
|
||||||
return (request->type == NBD_CMD_WRITE ||
|
return (request->type == NBD_CMD_WRITE ||
|
||||||
request->type == NBD_CMD_WRITE_ZEROES) ? -ENOSPC : -EINVAL;
|
request->type == NBD_CMD_WRITE_ZEROES) ? -ENOSPC : -EINVAL;
|
||||||
}
|
}
|
||||||
|
29
qemu-nbd.c
29
qemu-nbd.c
@ -176,7 +176,7 @@ static void read_partition(uint8_t *p, struct partition_record *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int find_partition(BlockBackend *blk, int partition,
|
static int find_partition(BlockBackend *blk, int partition,
|
||||||
off_t *offset, off_t *size)
|
uint64_t *offset, uint64_t *size)
|
||||||
{
|
{
|
||||||
struct partition_record mbr[4];
|
struct partition_record mbr[4];
|
||||||
uint8_t data[MBR_SIZE];
|
uint8_t data[MBR_SIZE];
|
||||||
@ -500,14 +500,14 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
BlockBackend *blk;
|
BlockBackend *blk;
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
off_t dev_offset = 0;
|
uint64_t dev_offset = 0;
|
||||||
uint16_t nbdflags = 0;
|
uint16_t nbdflags = 0;
|
||||||
bool disconnect = false;
|
bool disconnect = false;
|
||||||
const char *bindto = NULL;
|
const char *bindto = NULL;
|
||||||
const char *port = NULL;
|
const char *port = NULL;
|
||||||
char *sockpath = NULL;
|
char *sockpath = NULL;
|
||||||
char *device = NULL;
|
char *device = NULL;
|
||||||
off_t fd_size;
|
int64_t fd_size;
|
||||||
QemuOpts *sn_opts = NULL;
|
QemuOpts *sn_opts = NULL;
|
||||||
const char *sn_id_or_name = NULL;
|
const char *sn_id_or_name = NULL;
|
||||||
const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:tl:x:T:D:B:";
|
const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:tl:x:T:D:B:";
|
||||||
@ -665,10 +665,6 @@ int main(int argc, char **argv)
|
|||||||
error_report("Invalid offset `%s'", optarg);
|
error_report("Invalid offset `%s'", optarg);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (dev_offset < 0) {
|
|
||||||
error_report("Offset must be positive `%s'", optarg);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
if (strstart(optarg, SNAPSHOT_OPT_BASE, NULL)) {
|
if (strstart(optarg, SNAPSHOT_OPT_BASE, NULL)) {
|
||||||
@ -1005,15 +1001,14 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dev_offset >= fd_size) {
|
if (dev_offset >= fd_size) {
|
||||||
error_report("Offset (%lld) has to be smaller than the image size "
|
error_report("Offset (%" PRIu64 ") has to be smaller than the image "
|
||||||
"(%lld)",
|
"size (%" PRId64 ")", dev_offset, fd_size);
|
||||||
(long long int)dev_offset, (long long int)fd_size);
|
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
fd_size -= dev_offset;
|
fd_size -= dev_offset;
|
||||||
|
|
||||||
if (partition != -1) {
|
if (partition != -1) {
|
||||||
off_t limit;
|
uint64_t limit;
|
||||||
|
|
||||||
if (dev_offset) {
|
if (dev_offset) {
|
||||||
error_report("Cannot request partition and offset together");
|
error_report("Cannot request partition and offset together");
|
||||||
@ -1027,15 +1022,13 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* MBR partition limits are (32-bit << 9); this assert lets
|
* MBR partition limits are (32-bit << 9); this assert lets
|
||||||
* the compiler know that we have two positive values that
|
* the compiler know that we can't overflow 64 bits.
|
||||||
* can't overflow 64 bits.
|
|
||||||
*/
|
*/
|
||||||
assert(dev_offset >= 0 && dev_offset + limit >= dev_offset);
|
assert(dev_offset + limit >= dev_offset);
|
||||||
if (dev_offset + limit > fd_size) {
|
if (dev_offset + limit > fd_size) {
|
||||||
error_report("Discovered partition %d at offset %lld size %lld, "
|
error_report("Discovered partition %d at offset %" PRIu64
|
||||||
"but size exceeds file length %lld", partition,
|
" size %" PRIu64 ", but size exceeds file length %"
|
||||||
(long long int) dev_offset, (long long int) limit,
|
PRId64, partition, dev_offset, limit, fd_size);
|
||||||
(long long int) fd_size);
|
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
fd_size = limit;
|
fd_size = limit;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user