Revision a76bab49 block-raw-posix.c
b/block-raw-posix.c | ||
---|---|---|
101 | 101 |
#endif |
102 | 102 |
} BDRVRawState; |
103 | 103 |
|
104 |
static int posix_aio_init(void); |
|
105 |
|
|
104 | 106 |
static int fd_open(BlockDriverState *bs); |
105 | 107 |
|
106 | 108 |
static int raw_open(BlockDriverState *bs, const char *filename, int flags) |
... | ... | |
108 | 110 |
BDRVRawState *s = bs->opaque; |
109 | 111 |
int fd, open_flags, ret; |
110 | 112 |
|
113 |
posix_aio_init(); |
|
114 |
|
|
111 | 115 |
s->lseek_err_cnt = 0; |
112 | 116 |
|
113 | 117 |
open_flags = O_BINARY; |
... | ... | |
437 | 441 |
int ret; |
438 | 442 |
} RawAIOCB; |
439 | 443 |
|
440 |
static int aio_sig_fd = -1; |
|
441 |
static int aio_sig_num = SIGUSR2; |
|
442 |
static RawAIOCB *first_aio; /* AIO issued */ |
|
443 |
static int aio_initialized = 0; |
|
444 |
typedef struct PosixAioState |
|
445 |
{ |
|
446 |
int fd; |
|
447 |
RawAIOCB *first_aio; |
|
448 |
} PosixAioState; |
|
444 | 449 |
|
445 |
static void qemu_aio_poll(void *opaque)
|
|
450 |
static void posix_aio_read(void *opaque)
|
|
446 | 451 |
{ |
452 |
PosixAioState *s = opaque; |
|
447 | 453 |
RawAIOCB *acb, **pacb; |
448 | 454 |
int ret; |
449 | 455 |
size_t offset; |
... | ... | |
457 | 463 |
while (offset < 128) { |
458 | 464 |
ssize_t len; |
459 | 465 |
|
460 |
len = read(aio_sig_fd, sig.buf + offset, 128 - offset);
|
|
466 |
len = read(s->fd, sig.buf + offset, 128 - offset);
|
|
461 | 467 |
if (len == -1 && errno == EINTR) |
462 | 468 |
continue; |
463 | 469 |
if (len == -1 && errno == EAGAIN) { |
... | ... | |
472 | 478 |
} |
473 | 479 |
|
474 | 480 |
for(;;) { |
475 |
pacb = &first_aio; |
|
481 |
pacb = &s->first_aio;
|
|
476 | 482 |
for(;;) { |
477 | 483 |
acb = *pacb; |
478 | 484 |
if (!acb) |
... | ... | |
507 | 513 |
the_end: ; |
508 | 514 |
} |
509 | 515 |
|
510 |
void qemu_aio_init(void)
|
|
516 |
static int posix_aio_flush(void *opaque)
|
|
511 | 517 |
{ |
512 |
sigset_t mask; |
|
518 |
PosixAioState *s = opaque; |
|
519 |
return !!s->first_aio; |
|
520 |
} |
|
513 | 521 |
|
514 |
if (aio_initialized) |
|
515 |
return; |
|
522 |
static PosixAioState *posix_aio_state; |
|
516 | 523 |
|
517 |
aio_initialized = 1; |
|
524 |
static int posix_aio_init(void) |
|
525 |
{ |
|
526 |
sigset_t mask; |
|
527 |
PosixAioState *s; |
|
528 |
|
|
529 |
if (posix_aio_state) |
|
530 |
return 0; |
|
531 |
|
|
532 |
s = qemu_malloc(sizeof(PosixAioState)); |
|
533 |
if (s == NULL) |
|
534 |
return -ENOMEM; |
|
518 | 535 |
|
519 | 536 |
/* Make sure to block AIO signal */ |
520 | 537 |
sigemptyset(&mask); |
521 |
sigaddset(&mask, aio_sig_num);
|
|
538 |
sigaddset(&mask, SIGUSR2);
|
|
522 | 539 |
sigprocmask(SIG_BLOCK, &mask, NULL); |
523 | 540 |
|
524 |
aio_sig_fd = qemu_signalfd(&mask); |
|
541 |
s->first_aio = NULL; |
|
542 |
s->fd = qemu_signalfd(&mask); |
|
525 | 543 |
|
526 |
fcntl(aio_sig_fd, F_SETFL, O_NONBLOCK);
|
|
544 |
fcntl(s->fd, F_SETFL, O_NONBLOCK);
|
|
527 | 545 |
|
528 |
qemu_set_fd_handler2(aio_sig_fd, NULL, qemu_aio_poll, NULL, NULL);
|
|
546 |
qemu_aio_set_fd_handler(s->fd, posix_aio_read, NULL, posix_aio_flush, s);
|
|
529 | 547 |
|
530 | 548 |
#if defined(__GLIBC__) && defined(__linux__) |
531 | 549 |
{ |
... | ... | |
539 | 557 |
aio_init(&ai); |
540 | 558 |
} |
541 | 559 |
#endif |
542 |
} |
|
543 |
|
|
544 |
/* Wait for all IO requests to complete. */ |
|
545 |
void qemu_aio_flush(void) |
|
546 |
{ |
|
547 |
qemu_aio_poll(NULL); |
|
548 |
while (first_aio) { |
|
549 |
qemu_aio_wait(); |
|
550 |
} |
|
551 |
} |
|
552 |
|
|
553 |
void qemu_aio_wait(void) |
|
554 |
{ |
|
555 |
int ret; |
|
556 |
|
|
557 |
if (qemu_bh_poll()) |
|
558 |
return; |
|
559 |
|
|
560 |
if (!first_aio) |
|
561 |
return; |
|
562 |
|
|
563 |
do { |
|
564 |
fd_set rdfds; |
|
565 |
|
|
566 |
FD_ZERO(&rdfds); |
|
567 |
FD_SET(aio_sig_fd, &rdfds); |
|
560 |
posix_aio_state = s; |
|
568 | 561 |
|
569 |
ret = select(aio_sig_fd + 1, &rdfds, NULL, NULL, NULL); |
|
570 |
if (ret == -1 && errno == EINTR) |
|
571 |
continue; |
|
572 |
} while (ret == 0); |
|
573 |
|
|
574 |
qemu_aio_poll(NULL); |
|
562 |
return 0; |
|
575 | 563 |
} |
576 | 564 |
|
577 | 565 |
static RawAIOCB *raw_aio_setup(BlockDriverState *bs, |
... | ... | |
588 | 576 |
if (!acb) |
589 | 577 |
return NULL; |
590 | 578 |
acb->aiocb.aio_fildes = s->fd; |
591 |
acb->aiocb.aio_sigevent.sigev_signo = aio_sig_num;
|
|
579 |
acb->aiocb.aio_sigevent.sigev_signo = SIGUSR2;
|
|
592 | 580 |
acb->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL; |
593 | 581 |
acb->aiocb.aio_buf = buf; |
594 | 582 |
if (nb_sectors < 0) |
... | ... | |
596 | 584 |
else |
597 | 585 |
acb->aiocb.aio_nbytes = nb_sectors * 512; |
598 | 586 |
acb->aiocb.aio_offset = sector_num * 512; |
599 |
acb->next = first_aio; |
|
600 |
first_aio = acb; |
|
587 |
acb->next = posix_aio_state->first_aio;
|
|
588 |
posix_aio_state->first_aio = acb;
|
|
601 | 589 |
return acb; |
602 | 590 |
} |
603 | 591 |
|
... | ... | |
688 | 676 |
} |
689 | 677 |
|
690 | 678 |
/* remove the callback from the queue */ |
691 |
pacb = &first_aio; |
|
679 |
pacb = &posix_aio_state->first_aio;
|
|
692 | 680 |
for(;;) { |
693 | 681 |
if (*pacb == NULL) { |
694 | 682 |
break; |
... | ... | |
701 | 689 |
} |
702 | 690 |
} |
703 | 691 |
|
704 |
# else /* CONFIG_AIO */ |
|
705 |
|
|
706 |
void qemu_aio_init(void) |
|
692 |
#else /* CONFIG_AIO */ |
|
693 |
static int posix_aio_init(void) |
|
707 | 694 |
{ |
708 | 695 |
} |
709 |
|
|
710 |
void qemu_aio_flush(void) |
|
711 |
{ |
|
712 |
} |
|
713 |
|
|
714 |
void qemu_aio_wait(void) |
|
715 |
{ |
|
716 |
qemu_bh_poll(); |
|
717 |
} |
|
718 |
|
|
719 | 696 |
#endif /* CONFIG_AIO */ |
720 | 697 |
|
721 | 698 |
static void raw_close(BlockDriverState *bs) |
... | ... | |
921 | 898 |
BDRVRawState *s = bs->opaque; |
922 | 899 |
int fd, open_flags, ret; |
923 | 900 |
|
901 |
posix_aio_init(); |
|
902 |
|
|
924 | 903 |
#ifdef CONFIG_COCOA |
925 | 904 |
if (strstart(filename, "/dev/cdrom", NULL)) { |
926 | 905 |
kern_return_t kernResult; |
Also available in: Unified diff