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 | 71 | size_t len; |
72 | 72 | CURLState states[CURL_NUM_STATES]; |
73 | 73 | char *url; |
74 | + size_t readahead_size; | |
74 | 75 | } BDRVCURLState; |
75 | 76 | |
76 | 77 | static void curl_clean_state(CURLState *s); |
... | ... | @@ -299,15 +300,57 @@ static int curl_open(BlockDriverState *bs, const char *filename, int flags) |
299 | 300 | BDRVCURLState *s = bs->opaque; |
300 | 301 | CURLState *state = NULL; |
301 | 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 | 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 | 347 | if (!inited) { |
305 | 348 | curl_global_init(CURL_GLOBAL_ALL); |
306 | 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 | 354 | state = curl_init_state(s); |
312 | 355 | if (!state) |
313 | 356 | goto out_noclean; |
... | ... | @@ -346,6 +389,7 @@ out: |
346 | 389 | curl_easy_cleanup(state->curl); |
347 | 390 | state->curl = NULL; |
348 | 391 | out_noclean: |
392 | + qemu_free(file); | |
349 | 393 | return -EINVAL; |
350 | 394 | } |
351 | 395 | |
... | ... | @@ -401,7 +445,7 @@ static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs, |
401 | 445 | if (state->orig_buf) |
402 | 446 | qemu_free(state->orig_buf); |
403 | 447 | state->buf_start = start; |
404 | - state->buf_len = acb->end + READ_AHEAD_SIZE; | |
448 | + state->buf_len = acb->end + s->readahead_size; | |
405 | 449 | end = MIN(start + state->buf_len, s->len) - 1; |
406 | 450 | state->orig_buf = qemu_malloc(state->buf_len); |
407 | 451 | state->acb[0] = acb; | ... | ... |