Enable writing after the 2G boundary
This patch fixes a bug in readwrite.c which truncated the 'from' field in nbd requests. It was casting them down from an off64_t to an int.
This commit is contained in:
10
src/client.c
10
src/client.c
@@ -136,7 +136,6 @@ void write_not_zeroes(struct client* client, uint64_t from, int len)
|
||||
*/
|
||||
if (zerobuffer[0] != 0 ||
|
||||
memcmp(zerobuffer, zerobuffer + 1, blockrun - 1)) {
|
||||
debug("non-zero, writing from=%ld, blockrun=%d", from, blockrun);
|
||||
memcpy(client->mapped+from, zerobuffer, blockrun);
|
||||
bitset_set_range(map, from, blockrun);
|
||||
server_dirty(client->serve, from, blockrun);
|
||||
@@ -147,9 +146,7 @@ void write_not_zeroes(struct client* client, uint64_t from, int len)
|
||||
* sparseness as possible.
|
||||
*/
|
||||
}
|
||||
else {
|
||||
debug("all zero, skip write");
|
||||
}
|
||||
|
||||
len -= blockrun;
|
||||
run -= blockrun;
|
||||
from += blockrun;
|
||||
@@ -164,6 +161,7 @@ int fd_read_request( int fd, struct nbd_request_raw *out_request)
|
||||
return readloop(fd, out_request, sizeof(struct nbd_request_raw));
|
||||
}
|
||||
|
||||
|
||||
/* Returns 1 if *request was filled with a valid request which we should
|
||||
* try to honour. 0 otherwise. */
|
||||
int client_read_request( struct client * client , struct nbd_request *out_request, int * disconnected )
|
||||
@@ -318,7 +316,7 @@ int client_request_needs_reply( struct client * client,
|
||||
"after an entrust message.");
|
||||
/* check it's not out of range */
|
||||
if ( request.from+request.len > client->serve->size) {
|
||||
debug("request read %ld+%d out of range",
|
||||
debug("request read %llx+%ld out of range",
|
||||
request.from,
|
||||
request.len
|
||||
);
|
||||
@@ -495,7 +493,7 @@ void* client_serve(void* client_uncast)
|
||||
NULL,
|
||||
(void**) &client->mapped
|
||||
),
|
||||
"Couldn't open/mmap file %s", client->serve->filename
|
||||
"Couldn't open/mmap file %s: %s", client->serve->filename, strerror( errno )
|
||||
);
|
||||
debug("client: sending hello");
|
||||
client_send_hello(client);
|
||||
|
28
src/ioutil.c
28
src/ioutil.c
@@ -55,18 +55,22 @@ struct bitset_mapping* build_allocation_map(int fd, uint64_t size, int resolutio
|
||||
);
|
||||
}
|
||||
|
||||
for (i=0; i<(size/resolution); i++) {
|
||||
debug("map[%d] = %d%d%d%d%d%d%d%d",
|
||||
i,
|
||||
(allocation_map->bits[i] & 1) == 1,
|
||||
(allocation_map->bits[i] & 2) == 2,
|
||||
(allocation_map->bits[i] & 4) == 4,
|
||||
(allocation_map->bits[i] & 8) == 8,
|
||||
(allocation_map->bits[i] & 16) == 16,
|
||||
(allocation_map->bits[i] & 32) == 32,
|
||||
(allocation_map->bits[i] & 64) == 64,
|
||||
(allocation_map->bits[i] & 128) == 128
|
||||
);
|
||||
/* This is pointlessly verbose for real discs, it's here as a
|
||||
* reference for pulling data out of the allocation map */
|
||||
if ( 0 ) {
|
||||
for (i=0; i<(size/resolution); i++) {
|
||||
debug("map[%d] = %d%d%d%d%d%d%d%d",
|
||||
i,
|
||||
(allocation_map->bits[i] & 1) == 1,
|
||||
(allocation_map->bits[i] & 2) == 2,
|
||||
(allocation_map->bits[i] & 4) == 4,
|
||||
(allocation_map->bits[i] & 8) == 8,
|
||||
(allocation_map->bits[i] & 16) == 16,
|
||||
(allocation_map->bits[i] & 32) == 32,
|
||||
(allocation_map->bits[i] & 64) == 64,
|
||||
(allocation_map->bits[i] & 128) == 128
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -56,7 +56,7 @@ fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fill_request(struct nbd_request *request, int type, int from, int len)
|
||||
void fill_request(struct nbd_request *request, int type, off64_t from, int len)
|
||||
{
|
||||
request->magic = htobe32(REQUEST_MAGIC);
|
||||
request->type = htobe32(type);
|
||||
|
Reference in New Issue
Block a user