Early mmap for basic multipart support

parent f59c6eb0
......@@ -14,6 +14,7 @@ vmod_get_h_LDADD = -ldl
TESTS = \
vtc/plain.vtc \
vtc/plain_cors.vtc \
vtc/multipart.vtc \
vtc/name_hash.vtc \
vtc/expires.vtc \
vtc/done.vtc \
......
......@@ -1097,11 +1097,19 @@ struct tus_suck_fd {
struct tus_suck_common sc;
};
struct tus_suck_mmap {
unsigned magic;
#define TUS_SUCK_MMAP_MAGIC 0x11ffbafa
void *ptr;
struct tus_suck_common sc;
};
typedef int suck_truncate_f(void *, off_t);
struct tus_suck {
union {
struct tus_suck_fd sfd;
struct tus_suck_fd sfd;
struct tus_suck_mmap sm;
} priv;
objiterate_f *func;
suck_truncate_f *trunc;
......@@ -1158,7 +1166,7 @@ tus_suck_fd_truncate_f(void *priv, off_t length)
CAST_OBJ_NOTNULL(sfd, priv, TUS_SUCK_FD_MAGIC);
return (ftruncate(sfd->fd, length));
return (ftruncate(sfd->fd, header_size + length));
}
static inline struct tus_suck_common *
......@@ -1179,6 +1187,73 @@ tus_suck_fd_init(struct tus_suck *suck, struct tus_file_core *fcore)
* suck to mmapped
*/
static int v_matchproto_(objiterate_f)
tus_suck_mmap_f(void *priv, unsigned flush, const void *ptr, ssize_t len)
{
struct tus_suck_mmap *sm;
struct tus_suck_common *sc;
void *wptr;
CAST_OBJ_NOTNULL(sm, priv, TUS_SUCK_MMAP_MAGIC);
sc = &sm->sc;
(void) flush;
if (len == 0)
return (0);
assert(len > 0);
if (*sc->upload_offset + len > sc->max) {
errno = EFBIG;
return (-1);
}
wptr = (char *)sm->ptr + *sc->upload_offset;
memcpy(wptr, ptr, len);
/* XXX write ordering with fdisk flush ?
*
* maybe we can just truncate all trailing NULs
* when reading?
*/
return (tus_suck_finish(sc, len, ptr, len));
}
static int
tus_suck_mmap_truncate_f(void *priv, off_t length)
{
struct tus_suck_mmap *sm;
struct tus_suck_common *sc;
void *wptr;
CAST_OBJ_NOTNULL(sm, priv, TUS_SUCK_MMAP_MAGIC);
sc = &sm->sc;
assert(length <= sc->max);
if (length >= *sc->upload_offset)
return (0);
wptr = (char *)sm->ptr + length;
memset(wptr, 0, *sc->upload_offset - length);
}
static inline struct tus_suck_common *
tus_suck_mmap_init(struct tus_suck *suck, struct tus_file_core *fcore)
{
struct tus_suck_mmap *sm = &suck->priv.sm;
tus_file_mmap(fcore);
sm->magic = TUS_SUCK_MMAP_MAGIC;
sm->ptr = fcore->ptr;
AN(sm->ptr);
suck->func = tus_suck_mmap_f;
suck->trunc = tus_suck_mmap_truncate_f;
return (&sm->sc);
}
/* ------------------------------------------------------------
* top level sucking
*/
......@@ -1192,9 +1267,17 @@ tus_suck_trunc(struct tus_suck *suck, off_t length)
}
static inline struct tus_suck_common *
tus_suck_init(struct tus_suck *suck, struct tus_file_core *fcore)
tus_suck_init(struct tus_suck *suck, struct tus_file_core *fcore,
struct tus_file_disk *fdisk)
{
return (tus_suck_fd_init(suck, fcore));
VCL_BYTES bm;
bm = tus_server_multipart(fcore->server);
if (bm > 0 && fdisk->upload_offset >= bm)
return (tus_suck_mmap_init(suck, fcore));
else
return (tus_suck_fd_init(suck, fcore));
}
unsigned
......@@ -1215,10 +1298,10 @@ tus_body_to_file(VRT_CTX, struct tus_file_core *fcore)
memset(&suck, 0, sizeof suck);
sc = tus_suck_init(&suck, fcore);
sc = tus_suck_init(&suck, fcore, fdisk);
AN(sc);
offset_saved = fcore->disk->upload_offset;
offset_saved = fdisk->upload_offset;
sc->ctx = ctx;
sc->max = tus_server_max(fcore->server);
......@@ -1238,8 +1321,8 @@ tus_body_to_file(VRT_CTX, struct tus_file_core *fcore)
suck.func, &suck.priv);
if (written < 0 && errno == EFBIG) {
tus_suck_trunc(&suck, sc->max);
fdisk->upload_offset = fdisk->upload_length = sc->max;
tus_suck_trunc(&suck, header_size + sc->max);
return (413);
}
......@@ -1253,8 +1336,8 @@ tus_body_to_file(VRT_CTX, struct tus_file_core *fcore)
if (tus_chksum_equal(ctx, sc->chksum))
return (204);
tus_suck_trunc(&suck, offset_saved);
fcore->disk->upload_offset = offset_saved;
tus_suck_trunc(&suck, header_size + offset_saved);
return (460);
}
......
......@@ -44,6 +44,7 @@ VCL_DURATION tus_server_expires(const struct VPFX(tus_server) *);
void tus_server_lock(struct VPFX(tus_server) *);
void tus_server_unlock(struct VPFX(tus_server) *);
VCL_BYTES tus_server_max(const struct VPFX(tus_server) *s);
VCL_BYTES tus_server_multipart(const struct VPFX(tus_server) *s);
struct vmod_blobdigest_digest * tus_server_digest(
const struct VPFX(tus_server) *s);
struct tus_exp *tus_server_exp(const struct VPFX(tus_server) *);
......@@ -103,6 +103,14 @@ tus_server_max(const struct VPFX(tus_server) *s)
return (s->max);
}
VCL_BYTES
tus_server_multipart(const struct VPFX(tus_server) *s)
{
CHECK_OBJ_NOTNULL(s, VMOD_TUS_SERVER_MAGIC);
return (s->multipart);
}
struct vmod_blobdigest_digest *
tus_server_digest(const struct VPFX(tus_server) *s)
{
......
This diff is collapsed.
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