support for writable mmap

parent 94294317
......@@ -418,8 +418,10 @@ tus_mmap_header(int fd)
MAP_SHARED | MAP_NORESERVE, fd, 0));
}
static char * empty = "";
void
tus_file_mmap(struct tus_file_core *fcore)
tus_file_complete(struct tus_file_core *fcore)
{
struct tus_file_disk *fdisk;
......@@ -427,15 +429,56 @@ tus_file_mmap(struct tus_file_core *fcore)
fdisk = fcore->disk;
CHECK_TUS_FILE_DISK(fdisk);
assert(fdisk->upload_length == fdisk->upload_offset);
assert(fdisk->upload_offset == fdisk->upload_length);
if (fdisk->upload_offset > 0) {
tus_file_mmap(fcore);
return;
}
AZ(fdisk->upload_length);
AZ(fdisk->upload_offset);
AZ(fcore->ptr);
AZ(fcore->len);
assert(fcore->ptr_type == TFCP_INVALID);
fcore->ptr_type = TFCP_EMPTY;
fcore->ptr = empty;
}
void
tus_file_mmap(struct tus_file_core *fcore)
{
struct tus_file_disk *fdisk;
int prot = PROT_READ;
CHECK_OBJ_NOTNULL(fcore, VMOD_TUS_FILE_CORE_MAGIC);
fdisk = fcore->disk;
CHECK_TUS_FILE_DISK(fdisk);
if (fcore->ptr != NULL) {
assert(fcore->ptr_type >= TFCP_MMAP_RO);
return;
}
AZ(fcore->ptr);
AZ(fcore->len);
assert(fcore->ptr_type == TFCP_INVALID);
fcore->ptr = mmap(NULL, fdisk->upload_length, PROT_READ,
assert(fdisk->upload_offset > 0);
assert(fdisk->upload_length > 0);
assert(fdisk->upload_offset <= fdisk->upload_length);
if (fdisk->upload_offset < fdisk->upload_length) {
prot |= PROT_WRITE;
// XXX error handling
AZ(fallocate(fcore->fd, 0, 0,
header_size + fdisk->upload_length));
}
fcore->ptr = mmap(NULL, fdisk->upload_length, prot,
MAP_SHARED | MAP_NORESERVE, fcore->fd, header_size);
AN(fcore->ptr);
fcore->ptr_type = TFCP_MMAP_RO;
fcore->ptr_type = (prot & PROT_WRITE) ?
TFCP_MMAP_RW : TFCP_MMAP_RO;
tus_file_close(fcore);
fcore->len = fdisk->upload_length;
}
......@@ -476,12 +519,19 @@ tus_file_fini(struct tus_file_core *fcore)
if (fdisk->type == TUS_FINAL) {
tus_file_final_fini(fcore);
} else if (fcore->ptr != NULL) {
} else if (fcore->ptr != NULL && fcore->ptr_type >= TFCP_MMAP_RO) {
fcore->ptr_type = TFCP_INVALID;
(void) munmap(fcore->ptr, fcore->len);
fcore->ptr = NULL;
fcore->len = 0;
} else if (fcore->ptr != NULL && fcore->ptr_type == TFCP_EMPTY) {
fcore->ptr_type = TFCP_INVALID;
fcore->ptr = NULL;
fcore->len = 0;
}
assert(fcore->ptr_type == TFCP_INVALID);
AZ(fcore->ptr);
AZ(fcore->len);
fcore->disk = NULL;
tus_file_disk_del(&fdisk, &fcore->fd, fcore->filename,
......
......@@ -172,6 +172,7 @@ struct tus_file_core *tus_file_new(VRT_CTX, struct VPFX(tus_server) *,
unsigned *, const char **);
struct tus_file_core *tus_file_lookup(struct VPFX(tus_server) *, const char *);
unsigned tus_body_to_file(VRT_CTX, struct tus_file_core *);
void tus_file_complete(struct tus_file_core *);
void tus_file_mmap(struct tus_file_core *);
#ifdef BAD_IDEA
......
......@@ -504,7 +504,7 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv,
return (0);
}
if (fdisk->upload_offset == fdisk->upload_length) {
tus_file_mmap(r->fcore);
tus_file_complete(r->fcore);
AZ(pthread_cond_signal(&r->fcore->cond));
if (type == TUS_PARTIAL)
return (0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment