From cd3ea086ec3db709c6682d85f8a97b96646cbb4f Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Sat, 9 Dec 2017 09:41:34 -0500 Subject: Buffering: Remove statically-sized path buffer from handle struct Paths are stored after the structure at their actual length plus any aligment padding. In principle, any type of auxilliary data could go there. Change-Id: Ic5487dc4089781b5cc52414d1691ba6d9dc1893c --- apps/buffering.c | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/apps/buffering.c b/apps/buffering.c index 79262a2f13..72b3890ef0 100644 --- a/apps/buffering.c +++ b/apps/buffering.c @@ -82,13 +82,13 @@ enum handle_flags struct memory_handle { struct lld_node hnode; /* Handle list node (first!) */ - struct lld_node mrunode;/* MRU list node */ - int id; /* A unique ID for the handle (after list!) */ + struct lld_node mrunode;/* MRU list node (second!) */ + size_t size; /* Size of this structure + its auxilliary data */ + int id; /* A unique ID for the handle */ enum data_type type; /* Type of data buffered with this handle */ uint8_t flags; /* Handle property flags */ int8_t pinned; /* Count of pinnings */ int8_t signaled; /* Stop any attempt at waiting to get the data */ - char path[MAX_PATH]; /* Path if data originated in a file */ int fd; /* File descriptor to path (-1 if closed) */ size_t data; /* Start index of the handle's data buffer */ size_t ridx; /* Read pointer, relative to the main buffer */ @@ -97,8 +97,12 @@ struct memory_handle { off_t start; /* Offset at which we started reading the file */ off_t pos; /* Read position in file */ off_t volatile end; /* Offset at which we stopped reading the file */ + char path[]; /* Path if data originated in a file */ }; +/* Minimum allowed handle movement */ +#define MIN_MOVE_DELTA sizeof(struct memory_handle) + struct buf_message_data { int handle_id; @@ -344,7 +348,8 @@ static void adjust_handle_node(struct lld_head *list, NULL if there memory_handle itself cannot be allocated or if the data_size cannot be allocated and alloc_all is set. */ static struct memory_handle * -add_handle(unsigned int flags, size_t data_size, size_t *data_out) +add_handle(unsigned int flags, size_t data_size, const char *path, + size_t *data_out) { /* Gives each handle a unique id */ if (num_handles >= BUF_MAX_HANDLES) @@ -376,14 +381,17 @@ add_handle(unsigned int flags, size_t data_size, size_t *data_out) } /* Align to align size up */ + size_t pathsize = path ? strlen(path) + 1 : 0; size_t adjust = ALIGN_UP(widx, alignof(struct memory_handle)) - widx; size_t index = ringbuf_add(widx, adjust); - size_t len = data_size + sizeof(struct memory_handle); + size_t handlesize = ALIGN_UP(sizeof(struct memory_handle) + pathsize, + alignof(struct memory_handle)); + size_t len = handlesize + data_size; /* First, will the handle wrap? */ /* If the handle would wrap, move to the beginning of the buffer, * or if the data must not but would wrap, move it to the beginning */ - if (index + sizeof(struct memory_handle) > buffer_len || + if (index + handlesize > buffer_len || (!(flags & H_CANWRAP) && index + len > buffer_len)) { index = 0; } @@ -405,13 +413,17 @@ add_handle(unsigned int flags, size_t data_size, size_t *data_out) /* There is enough space for the required data, initialize the struct */ struct memory_handle *h = ringbuf_ptr(index); + h->size = handlesize; h->id = next_handle_id(); h->flags = flags; h->pinned = 0; /* Can be moved */ h->signaled = 0; /* Data can be waited for */ + /* Save the provided path */ + memcpy(h->path, path, pathsize); + /* Return the start of the data area */ - *data_out = ringbuf_add(index, sizeof (struct memory_handle)); + *data_out = ringbuf_add(index, handlesize); return h; } @@ -457,13 +469,13 @@ static bool move_handle(struct memory_handle **h, size_t *delta, if (h == NULL || (src = *h) == NULL) return false; - size_t size_to_move = sizeof(struct memory_handle) + data_size; + size_t size_to_move = src->size + data_size; /* Align to align size down */ size_t final_delta = *delta; final_delta = ALIGN_DOWN(final_delta, alignof(struct memory_handle)); - if (final_delta < sizeof(struct memory_handle)) { - /* It's not legal to move less than the size of the struct */ + if (final_delta < MIN_MOVE_DELTA) { + /* It's not legal to move less than MIN_MOVE_DELTA */ return false; } @@ -490,8 +502,8 @@ static bool move_handle(struct memory_handle **h, size_t *delta, if (correction) { /* Align correction to align size up */ correction = ALIGN_UP(correction, alignof(struct memory_handle)); - if (final_delta < correction + sizeof(struct memory_handle)) { - /* Delta cannot end up less than the size of the struct */ + if (final_delta < correction + MIN_MOVE_DELTA) { + /* Delta cannot end up less than MIN_MOVE_DELTA */ return false; } newpos -= correction; @@ -918,13 +930,12 @@ int bufopen(const char *file, size_t offset, enum data_type type, /* ID3 case: allocate space, init the handle and return. */ mutex_lock(&llist_mutex); - h = add_handle(H_ALLOCALL, sizeof(struct mp3entry), &data); + h = add_handle(H_ALLOCALL, sizeof(struct mp3entry), file, &data); if (h) { handle_id = h->id; h->type = type; - strlcpy(h->path, file, MAX_PATH); h->fd = -1; h->data = data; h->ridx = data; @@ -983,7 +994,7 @@ int bufopen(const char *file, size_t offset, enum data_type type, mutex_lock(&llist_mutex); - h = add_handle(hflags, padded_size, &data); + h = add_handle(hflags, padded_size, file, &data); if (!h) { DEBUGF("%s(): failed to add handle\n", __func__); mutex_unlock(&llist_mutex); @@ -994,7 +1005,6 @@ int bufopen(const char *file, size_t offset, enum data_type type, handle_id = h->id; h->type = type; - strlcpy(h->path, file, MAX_PATH); h->fd = -1; #ifdef STORAGE_WANTS_ALIGN @@ -1080,7 +1090,7 @@ int bufalloc(const void *src, size_t size, enum data_type type) mutex_lock(&llist_mutex); size_t data; - struct memory_handle *h = add_handle(H_ALLOCALL, size, &data); + struct memory_handle *h = add_handle(H_ALLOCALL, size, NULL, &data); if (h) { handle_id = h->id; @@ -1095,7 +1105,6 @@ int bufalloc(const void *src, size_t size, enum data_type type) } h->type = type; - h->path[0] = '\0'; h->fd = -1; h->data = data; h->ridx = data; -- cgit