diff --git a/src/client.c b/src/client.c index 1189a42..6917a93 100644 --- a/src/client.c +++ b/src/client.c @@ -387,26 +387,28 @@ void client_reply_to_write( struct client* client, struct nbd_request request ) write_not_zeroes( client, request.from, request.len ); } else { - FATAL_IF_NEGATIVE( - readloop( - client->socket, - client->mapped + request.from, - request.len), - "read failed from=%ld, len=%d", - request.from, - request.len ); + debug("No allocation map, writing directly."); + /* If we get cut off partway through reading this data + * */ + ERROR_IF_NEGATIVE( + readloop( client->socket, + client->mapped + request.from, + request.len), + "reading write data failed from=%ld, len=%d", + request.from, + request.len + ); server_dirty(client->serve, request.from, request.len); } - + if (1) /* not sure whether this is necessary... */ { /* multiple of 4K page size */ uint64_t from_rounded = request.from & (!0xfff); uint64_t len_rounded = request.len + (request.from - from_rounded); - + FATAL_IF_NEGATIVE( - msync( - client->mapped + from_rounded, + msync( client->mapped + from_rounded, len_rounded, MS_SYNC), "msync failed %ld %ld", request.from, request.len diff --git a/src/ioutil.c b/src/ioutil.c index 8c7df08..336bbba 100644 --- a/src/ioutil.c +++ b/src/ioutil.c @@ -15,7 +15,7 @@ struct bitset_mapping* build_allocation_map(int fd, uint64_t size, int resolutio { unsigned int i; struct bitset_mapping* allocation_map = bitset_alloc(size, resolution); - struct fiemap *fiemap_count, *fiemap; + struct fiemap *fiemap_count = NULL, *fiemap = NULL; fiemap_count = (struct fiemap*) xmalloc(sizeof(struct fiemap)); @@ -27,17 +27,18 @@ struct bitset_mapping* build_allocation_map(int fd, uint64_t size, int resolutio /* Find out how many extents there are */ if (ioctl(fd, FS_IOC_FIEMAP, fiemap_count) < 0) { - return NULL; + debug( "Couldn't get fiemap_count, returning no allocation_map" ); + goto no_map; } /* Resize fiemap to allow us to read in the extents */ fiemap = (struct fiemap*)xmalloc( - sizeof(struct fiemap) + ( - sizeof(struct fiemap_extent) * - fiemap_count->fm_mapped_extents - ) - ); - + sizeof(struct fiemap) + ( + sizeof(struct fiemap_extent) * + fiemap_count->fm_mapped_extents + ) + ); + /* realloc makes valgrind complain a lot */ memcpy(fiemap, fiemap_count, sizeof(struct fiemap)); free( fiemap_count ); @@ -45,7 +46,10 @@ struct bitset_mapping* build_allocation_map(int fd, uint64_t size, int resolutio fiemap->fm_extent_count = fiemap->fm_mapped_extents; fiemap->fm_mapped_extents = 0; - if (ioctl(fd, FS_IOC_FIEMAP, fiemap) < 0) { return NULL; } + if (ioctl(fd, FS_IOC_FIEMAP, fiemap) < 0) { + debug( "Couldn't get fiemap, returning no allocation_map" ); + goto no_map; + } for (i=0;ifm_mapped_extents;i++) { bitset_set_range( @@ -54,7 +58,7 @@ struct bitset_mapping* build_allocation_map(int fd, uint64_t size, int resolutio fiemap->fm_extents[i].fe_length ); } - + /* This is pointlessly verbose for real discs, it's here as a * reference for pulling data out of the allocation map */ if ( 0 ) { @@ -72,13 +76,22 @@ struct bitset_mapping* build_allocation_map(int fd, uint64_t size, int resolutio ); } } - - + + free(fiemap); - + + debug("Successfully built allocation map"); return allocation_map; + +no_map: + fprintf(stderr, "Freeing"); + free( allocation_map ); + if ( NULL != fiemap ) { free( fiemap ); } + if ( NULL != fiemap_count ) { free( fiemap_count ); } + return NULL; } + int open_and_mmap(const char* filename, int* out_fd, off64_t *out_size, void **out_map) { off64_t size;