Commit c76f4952bbf47116255bc00780ceae3bc8a657c0
Committed by
Anthony Liguori
1 parent
5f650495
Allow adjustment of http block device's readahead size, via a new
":readahead=###:" suffix. Signed-off-by: Nolan Leake <nolan <at> sigbus.net> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing
1 changed file
with
47 additions
and
3 deletions
block/curl.c
@@ -71,6 +71,7 @@ typedef struct BDRVCURLState { | @@ -71,6 +71,7 @@ typedef struct BDRVCURLState { | ||
71 | size_t len; | 71 | size_t len; |
72 | CURLState states[CURL_NUM_STATES]; | 72 | CURLState states[CURL_NUM_STATES]; |
73 | char *url; | 73 | char *url; |
74 | + size_t readahead_size; | ||
74 | } BDRVCURLState; | 75 | } BDRVCURLState; |
75 | 76 | ||
76 | static void curl_clean_state(CURLState *s); | 77 | static void curl_clean_state(CURLState *s); |
@@ -299,15 +300,57 @@ static int curl_open(BlockDriverState *bs, const char *filename, int flags) | @@ -299,15 +300,57 @@ static int curl_open(BlockDriverState *bs, const char *filename, int flags) | ||
299 | BDRVCURLState *s = bs->opaque; | 300 | BDRVCURLState *s = bs->opaque; |
300 | CURLState *state = NULL; | 301 | CURLState *state = NULL; |
301 | double d; | 302 | double d; |
303 | + | ||
304 | + #define RA_OPTSTR ":readahead=" | ||
305 | + char *file; | ||
306 | + char *ra; | ||
307 | + const char *ra_val; | ||
308 | + int parse_state = 0; | ||
309 | + | ||
302 | static int inited = 0; | 310 | static int inited = 0; |
303 | 311 | ||
312 | + file = strdup(filename); | ||
313 | + s->readahead_size = READ_AHEAD_SIZE; | ||
314 | + | ||
315 | + /* Parse a trailing ":readahead=#:" param, if present. */ | ||
316 | + ra = file + strlen(file) - 1; | ||
317 | + while (ra >= file) { | ||
318 | + if (parse_state == 0) { | ||
319 | + if (*ra == ':') | ||
320 | + parse_state++; | ||
321 | + else | ||
322 | + break; | ||
323 | + } else if (parse_state == 1) { | ||
324 | + if (*ra > '9' || *ra < '0') { | ||
325 | + char *opt_start = ra - strlen(RA_OPTSTR) + 1; | ||
326 | + if (opt_start > file && | ||
327 | + strncmp(opt_start, RA_OPTSTR, strlen(RA_OPTSTR)) == 0) { | ||
328 | + ra_val = ra + 1; | ||
329 | + ra -= strlen(RA_OPTSTR) - 1; | ||
330 | + *ra = '\0'; | ||
331 | + s->readahead_size = atoi(ra_val); | ||
332 | + break; | ||
333 | + } else { | ||
334 | + break; | ||
335 | + } | ||
336 | + } | ||
337 | + } | ||
338 | + ra--; | ||
339 | + } | ||
340 | + | ||
341 | + if ((s->readahead_size & 0x1ff) != 0) { | ||
342 | + fprintf(stderr, "HTTP_READAHEAD_SIZE %Zd is not a multiple of 512\n", | ||
343 | + s->readahead_size); | ||
344 | + goto out_noclean; | ||
345 | + } | ||
346 | + | ||
304 | if (!inited) { | 347 | if (!inited) { |
305 | curl_global_init(CURL_GLOBAL_ALL); | 348 | curl_global_init(CURL_GLOBAL_ALL); |
306 | inited = 1; | 349 | inited = 1; |
307 | } | 350 | } |
308 | 351 | ||
309 | - dprintf("CURL: Opening %s\n", filename); | ||
310 | - s->url = strdup(filename); | 352 | + dprintf("CURL: Opening %s\n", file); |
353 | + s->url = file; | ||
311 | state = curl_init_state(s); | 354 | state = curl_init_state(s); |
312 | if (!state) | 355 | if (!state) |
313 | goto out_noclean; | 356 | goto out_noclean; |
@@ -346,6 +389,7 @@ out: | @@ -346,6 +389,7 @@ out: | ||
346 | curl_easy_cleanup(state->curl); | 389 | curl_easy_cleanup(state->curl); |
347 | state->curl = NULL; | 390 | state->curl = NULL; |
348 | out_noclean: | 391 | out_noclean: |
392 | + qemu_free(file); | ||
349 | return -EINVAL; | 393 | return -EINVAL; |
350 | } | 394 | } |
351 | 395 | ||
@@ -401,7 +445,7 @@ static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs, | @@ -401,7 +445,7 @@ static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs, | ||
401 | if (state->orig_buf) | 445 | if (state->orig_buf) |
402 | qemu_free(state->orig_buf); | 446 | qemu_free(state->orig_buf); |
403 | state->buf_start = start; | 447 | state->buf_start = start; |
404 | - state->buf_len = acb->end + READ_AHEAD_SIZE; | 448 | + state->buf_len = acb->end + s->readahead_size; |
405 | end = MIN(start + state->buf_len, s->len) - 1; | 449 | end = MIN(start + state->buf_len, s->len) - 1; |
406 | state->orig_buf = qemu_malloc(state->buf_len); | 450 | state->orig_buf = qemu_malloc(state->buf_len); |
407 | state->acb[0] = acb; | 451 | state->acb[0] = acb; |