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; |