Commit 9d26dfcb authored by Eric Blake's avatar Eric Blake
Browse files

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: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: default avatarEric Blake <eblake@redhat.com>
Message-Id: <20190117193658.16413-7-eblake@redhat.com>
Reviewed-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
parent 7596bbb3
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -294,8 +294,8 @@ int nbd_errno_to_system_errno(int err);
typedef struct NBDExport NBDExport;
typedef struct NBDClient NBDClient;

NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size,
                          const char *name, const char *description,
NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset,
                          uint64_t size, const char *name, const char *desc,
                          const char *bitmap, uint16_t nbdflags,
                          void (*close)(NBDExport *), bool writethrough,
                          BlockBackend *on_eject_blk, Error **errp);
+9 −9
Original line number Diff line number Diff line
@@ -77,8 +77,8 @@ struct NBDExport {
    BlockBackend *blk;
    char *name;
    char *description;
    off_t dev_offset;
    off_t size;
    uint64_t dev_offset;
    uint64_t size;
    uint16_t nbdflags;
    QTAILQ_HEAD(, NBDClient) clients;
    QTAILQ_ENTRY(NBDExport) next;
@@ -1455,8 +1455,8 @@ static void nbd_eject_notifier(Notifier *n, void *data)
    nbd_export_close(exp);
}

NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size,
                          const char *name, const char *description,
NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset,
                          uint64_t size, const char *name, const char *desc,
                          const char *bitmap, uint16_t nbdflags,
                          void (*close)(NBDExport *), bool writethrough,
                          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;
    QTAILQ_INIT(&exp->clients);
    exp->blk = blk;
    assert(dev_offset >= 0 && dev_offset <= INT64_MAX);
    assert(dev_offset <= INT64_MAX);
    exp->dev_offset = dev_offset;
    exp->name = g_strdup(name);
    exp->description = g_strdup(description);
    exp->description = g_strdup(desc);
    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);

    if (bitmap) {
@@ -2130,10 +2130,10 @@ static int nbd_co_receive_request(NBDRequestData *req, NBDRequest *request,
        return -EROFS;
    }
    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
                   ", Size: %" PRIu64, request->from, request->len,
                   (uint64_t)client->exp->size);
                   client->exp->size);
        return (request->type == NBD_CMD_WRITE ||
                request->type == NBD_CMD_WRITE_ZEROES) ? -ENOSPC : -EINVAL;
    }
+11 −18
Original line number Diff line number Diff line
@@ -176,7 +176,7 @@ static void read_partition(uint8_t *p, struct partition_record *r)
}

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];
    uint8_t data[MBR_SIZE];
@@ -500,14 +500,14 @@ int main(int argc, char **argv)
{
    BlockBackend *blk;
    BlockDriverState *bs;
    off_t dev_offset = 0;
    uint64_t dev_offset = 0;
    uint16_t nbdflags = 0;
    bool disconnect = false;
    const char *bindto = NULL;
    const char *port = NULL;
    char *sockpath = NULL;
    char *device = NULL;
    off_t fd_size;
    int64_t fd_size;
    QemuOpts *sn_opts = NULL;
    const char *sn_id_or_name = NULL;
    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);
                exit(EXIT_FAILURE);
            }
            if (dev_offset < 0) {
                error_report("Offset must be positive `%s'", optarg);
                exit(EXIT_FAILURE);
            }
            break;
        case 'l':
            if (strstart(optarg, SNAPSHOT_OPT_BASE, NULL)) {
@@ -1005,15 +1001,14 @@ int main(int argc, char **argv)
    }

    if (dev_offset >= fd_size) {
        error_report("Offset (%lld) has to be smaller than the image size "
                     "(%lld)",
                     (long long int)dev_offset, (long long int)fd_size);
        error_report("Offset (%" PRIu64 ") has to be smaller than the image "
                     "size (%" PRId64 ")", dev_offset, fd_size);
        exit(EXIT_FAILURE);
    }
    fd_size -= dev_offset;

    if (partition != -1) {
        off_t limit;
        uint64_t limit;

        if (dev_offset) {
            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
         * the compiler know that we have two positive values that
         * can't overflow 64 bits.
         * the compiler know that we 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) {
            error_report("Discovered partition %d at offset %lld size %lld, "
                         "but size exceeds file length %lld", partition,
                         (long long int) dev_offset, (long long int) limit,
                         (long long int) fd_size);
            error_report("Discovered partition %d at offset %" PRIu64
                         " size %" PRIu64 ", but size exceeds file length %"
                         PRId64, partition, dev_offset, limit, fd_size);
            exit(EXIT_FAILURE);
        }
        fd_size = limit;