Commit c76f4952bbf47116255bc00780ceae3bc8a657c0

Authored by Nolan
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;