Compare commits
3 Commits
add-read-f
...
change-mma
Author | SHA1 | Date | |
---|---|---|---|
![]() |
29306a716e | ||
![]() |
0ba90b39a3 | ||
![]() |
7f98f6ef9e |
7
Makefile
7
Makefile
@@ -4,7 +4,7 @@ VPATH=src:tests/unit
|
||||
DESTDIR?=/
|
||||
PREFIX?=/usr/local/bin
|
||||
INSTALLDIR=$(DESTDIR)/$(PREFIX)
|
||||
|
||||
|
||||
ifdef DEBUG
|
||||
CFLAGS_EXTRA=-g -DDEBUG
|
||||
LDFLAGS_EXTRA=-g
|
||||
@@ -12,6 +12,11 @@ else
|
||||
CFLAGS_EXTRA=-O2
|
||||
endif
|
||||
|
||||
NO_MSYNC=1
|
||||
ifdef NO_MSYNC
|
||||
CFLAGS_EXTRA += -DNO_MSYNC
|
||||
endif
|
||||
|
||||
CFLAGS_EXTRA += -fPIC --std=gnu99
|
||||
LDFLAGS_EXTRA += -Wl,--relax,--gc-sections -L$(LIB) -Wl,-rpath-link,$(LIB)
|
||||
|
||||
|
@@ -73,7 +73,6 @@ int build_allocation_map(struct bitset * allocation_map, int fd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int open_and_mmap(const char* filename, int* out_fd, uint64_t *out_size, void **out_map)
|
||||
{
|
||||
/*
|
||||
@@ -101,7 +100,7 @@ int open_and_mmap(const char* filename, int* out_fd, uint64_t *out_size, void **
|
||||
*out_size = size;
|
||||
}
|
||||
|
||||
if (out_map) {
|
||||
if (0) {
|
||||
*out_map = mmap64(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
|
||||
*out_fd, 0);
|
||||
if (((long) *out_map) == -1) {
|
||||
@@ -349,3 +348,36 @@ ssize_t iobuf_write( int fd, struct iobuf *iobuf )
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
struct iommap *iommap_alloc(int fd, off64_t from, uint64_t len) {
|
||||
|
||||
off66_t mmap_from = from & ~((off64_t) getpagesize() - 1);
|
||||
uint64_t mmap_len = len + (from - mmap_from);
|
||||
void *mmap_buf = NULL;
|
||||
|
||||
// TODO: Check the error code from mmap64
|
||||
if(mmap_len)
|
||||
mmap_buf = mmap64(NULL, mmap_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mmap_from);
|
||||
|
||||
struct iommap *im = xmalloc(sizeof(struct iommap ));
|
||||
|
||||
im->mmap_buf = mmap_buf;
|
||||
im->mmap_len = mmap_len;
|
||||
im->buf = (char *) mmap_buf + from - mmap_from;
|
||||
debug("mmapped file from %ld:%d", mmap_from, mmap_len);
|
||||
return im;
|
||||
}
|
||||
|
||||
void iommap_sync(struct iommap *im) {
|
||||
if (im->mmap_len)
|
||||
msync(im->mmap_buf, im->mmap_len, MS_SYNC | MS_INVALIDATE);
|
||||
return;
|
||||
}
|
||||
|
||||
void iommap_free(struct iommap *im) {
|
||||
if (im->mmap_len)
|
||||
munmap(im->mmap_buf, im->mmap_len);
|
||||
|
||||
free(im);
|
||||
}
|
||||
|
||||
|
@@ -11,7 +11,20 @@ struct iobuf {
|
||||
ssize_t iobuf_read( int fd, struct iobuf* iobuf, size_t default_size );
|
||||
ssize_t iobuf_write( int fd, struct iobuf* iobuf );
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
struct iommap {
|
||||
char *buf;
|
||||
char *mmap_buf;
|
||||
uint64_t mmap_len;
|
||||
};
|
||||
|
||||
struct iommap *iommap_alloc(int fd, off64_t from, uint64_t len);
|
||||
void iommap_sync(struct iommap *im);
|
||||
void iommap_free(struct iommap *im);
|
||||
|
||||
#include "serve.h"
|
||||
|
||||
struct bitset; /* don't need whole of bitset.h here */
|
||||
|
||||
/** Scan the file opened in ''fd'', set bits in ''allocation_map'' that
|
||||
|
@@ -118,6 +118,7 @@ void write_not_zeroes(struct client* client, uint64_t from, uint64_t len)
|
||||
*/
|
||||
|
||||
uint64_t run = bitset_run_count(map, from, len);
|
||||
struct iommap *iommap = iommap_alloc(client->fileno, from, len);
|
||||
|
||||
debug("write_not_zeroes: from=%ld, len=%d, run=%d", from, len, run);
|
||||
|
||||
@@ -155,7 +156,7 @@ void write_not_zeroes(struct client* client, uint64_t from, uint64_t len)
|
||||
if (bitset_is_set_at(map, from)) {
|
||||
debug("writing the lot: from=%ld, run=%d", from, run);
|
||||
/* already allocated, just write it all */
|
||||
DO_READ(client->mapped + from, run);
|
||||
DO_READ(iommap->buf, run);
|
||||
/* We know from our earlier call to bitset_run_count that the
|
||||
* bitset is all-1s at this point, but we need to dirty it for the
|
||||
* sake of the event stream - the actual bytes have changed, and we
|
||||
@@ -186,7 +187,7 @@ void write_not_zeroes(struct client* client, uint64_t from, uint64_t len)
|
||||
(0 == memcmp( zerobuffer, zerobuffer+1, blockrun-1 ));
|
||||
|
||||
if ( !all_zeros ) {
|
||||
memcpy(client->mapped+from, zerobuffer, blockrun);
|
||||
memcpy(iommap->buf, zerobuffer, blockrun);
|
||||
bitset_set_range(map, from, blockrun);
|
||||
/* at this point we could choose to
|
||||
* short-cut the rest of the write for
|
||||
@@ -205,6 +206,8 @@ void write_not_zeroes(struct client* client, uint64_t from, uint64_t len)
|
||||
from += blockrun;
|
||||
}
|
||||
}
|
||||
iommap_sync(iommap);
|
||||
iommap_free(iommap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,22 +452,28 @@ void client_reply_to_read( struct client* client, struct nbd_request request )
|
||||
void client_reply_to_write( struct client* client, struct nbd_request request )
|
||||
{
|
||||
debug("request write from=%"PRIu64", len=%"PRIu32", handle=0x%08X", request.from, request.len, request.handle);
|
||||
if (client->serve->allocation_map_built) {
|
||||
// TODO: Just write directly for now. Not (yet) convinced my changes later on work.
|
||||
// if (client->serve->allocation_map_built) {
|
||||
if (0) {
|
||||
write_not_zeroes( client, request.from, request.len );
|
||||
}
|
||||
else {
|
||||
debug("No allocation map, writing directly.");
|
||||
/* If we get cut off partway through reading this data:
|
||||
* */
|
||||
struct iommap *iommap = iommap_alloc(client->fileno, request.from, request.len);
|
||||
|
||||
ERROR_IF_NEGATIVE(
|
||||
readloop( client->socket,
|
||||
client->mapped + request.from,
|
||||
iommap->buf,
|
||||
request.len),
|
||||
"reading write data failed from=%ld, len=%d",
|
||||
request.from,
|
||||
request.len
|
||||
);
|
||||
|
||||
iommap_sync(iommap);
|
||||
iommap_free(iommap);
|
||||
/* the allocation_map is shared between client threads, and may be
|
||||
* being built. We need to reflect the write in it, as it may be in
|
||||
* a position the builder has already gone over.
|
||||
@@ -472,19 +481,6 @@ void client_reply_to_write( struct client* client, struct nbd_request request )
|
||||
bitset_set_range(client->serve->allocation_map, 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,
|
||||
len_rounded,
|
||||
MS_SYNC | MS_INVALIDATE),
|
||||
"msync failed %ld %ld", request.from, request.len
|
||||
);
|
||||
}
|
||||
client_write_reply( client, &request, 0);
|
||||
}
|
||||
|
||||
@@ -650,9 +646,6 @@ void client_cleanup(struct client* client,
|
||||
debug("Closed client socket fd %d", client->socket);
|
||||
client->socket = -1;
|
||||
}
|
||||
if (client->mapped) {
|
||||
munmap(client->mapped, client->serve->size);
|
||||
}
|
||||
if (client->fileno) {
|
||||
FATAL_IF_NEGATIVE( close(client->fileno),
|
||||
"Error closing file %d",
|
||||
@@ -668,25 +661,20 @@ void client_cleanup(struct client* client,
|
||||
void* client_serve(void* client_uncast)
|
||||
{
|
||||
struct client* client = (struct client*) client_uncast;
|
||||
void** a = NULL;
|
||||
|
||||
error_set_handler((cleanup_handler*) client_cleanup, client);
|
||||
|
||||
info("client: mmaping file");
|
||||
FATAL_IF_NEGATIVE(
|
||||
open_and_mmap(
|
||||
client->serve->filename,
|
||||
&client->fileno,
|
||||
NULL,
|
||||
(void**) &client->mapped
|
||||
a
|
||||
),
|
||||
"Couldn't open/mmap file %s: %s", client->serve->filename, strerror( errno )
|
||||
);
|
||||
|
||||
FATAL_IF_NEGATIVE(
|
||||
madvise( client->mapped, client->serve->size, MADV_RANDOM ),
|
||||
SHOW_ERRNO( "Failed to madvise() %s", client->serve->filename )
|
||||
);
|
||||
|
||||
debug( "Opened client file fd %d", client->fileno);
|
||||
debug("client: sending hello");
|
||||
client_send_hello(client);
|
||||
|
@@ -29,7 +29,6 @@ struct client {
|
||||
int socket;
|
||||
|
||||
int fileno;
|
||||
char* mapped;
|
||||
|
||||
struct self_pipe * stop_signal;
|
||||
|
||||
|
Reference in New Issue
Block a user