Define a few structures instead of including a file, add "static"
[qemu/mini2440.git] / block-raw-posix.c
blobeaf3bf26957807004433fde5e1747d28be82cdcd
1 /*
2 * Block driver for RAW files (posix)
4 * Copyright (c) 2006 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
24 #include "qemu-common.h"
25 #if !defined(QEMU_IMG) && !defined(QEMU_NBD)
26 #include "qemu-timer.h"
27 #include "exec-all.h"
28 #include "qemu-char.h"
29 #endif
30 #include "block_int.h"
31 #include "compatfd.h"
32 #include <assert.h>
33 #ifdef CONFIG_AIO
34 #include <aio.h>
35 #endif
37 #ifdef CONFIG_COCOA
38 #include <paths.h>
39 #include <sys/param.h>
40 #include <IOKit/IOKitLib.h>
41 #include <IOKit/IOBSD.h>
42 #include <IOKit/storage/IOMediaBSDClient.h>
43 #include <IOKit/storage/IOMedia.h>
44 #include <IOKit/storage/IOCDMedia.h>
45 //#include <IOKit/storage/IOCDTypes.h>
46 #include <CoreFoundation/CoreFoundation.h>
47 #endif
49 #ifdef __sun__
50 #define _POSIX_PTHREAD_SEMANTICS 1
51 #include <signal.h>
52 #include <sys/dkio.h>
53 #endif
54 #ifdef __linux__
55 #include <sys/ioctl.h>
56 #include <linux/cdrom.h>
57 #include <linux/fd.h>
58 #endif
59 #ifdef __FreeBSD__
60 #include <signal.h>
61 #include <sys/disk.h>
62 #endif
64 #ifdef __OpenBSD__
65 #include <sys/ioctl.h>
66 #include <sys/disklabel.h>
67 #include <sys/dkio.h>
68 #endif
70 //#define DEBUG_FLOPPY
72 //#define DEBUG_BLOCK
73 #if defined(DEBUG_BLOCK) && !defined(QEMU_IMG) && !defined(QEMU_NBD)
74 #define DEBUG_BLOCK_PRINT(formatCstr, args...) do { if (loglevel != 0) \
75 { fprintf(logfile, formatCstr, ##args); fflush(logfile); } } while (0)
76 #else
77 #define DEBUG_BLOCK_PRINT(formatCstr, args...)
78 #endif
80 #define FTYPE_FILE 0
81 #define FTYPE_CD 1
82 #define FTYPE_FD 2
84 #define ALIGNED_BUFFER_SIZE (32 * 512)
86 /* if the FD is not accessed during that time (in ms), we try to
87 reopen it to see if the disk has been changed */
88 #define FD_OPEN_TIMEOUT 1000
90 typedef struct BDRVRawState {
91 int fd;
92 int type;
93 unsigned int lseek_err_cnt;
94 #if defined(__linux__)
95 /* linux floppy specific */
96 int fd_open_flags;
97 int64_t fd_open_time;
98 int64_t fd_error_time;
99 int fd_got_error;
100 int fd_media_changed;
101 #endif
102 #if defined(O_DIRECT) && !defined(QEMU_IMG)
103 uint8_t* aligned_buf;
104 #endif
105 } BDRVRawState;
107 static int fd_open(BlockDriverState *bs);
109 static int raw_open(BlockDriverState *bs, const char *filename, int flags)
111 BDRVRawState *s = bs->opaque;
112 int fd, open_flags, ret;
114 s->lseek_err_cnt = 0;
116 open_flags = O_BINARY;
117 if ((flags & BDRV_O_ACCESS) == O_RDWR) {
118 open_flags |= O_RDWR;
119 } else {
120 open_flags |= O_RDONLY;
121 bs->read_only = 1;
123 if (flags & BDRV_O_CREAT)
124 open_flags |= O_CREAT | O_TRUNC;
125 #ifdef O_DIRECT
126 if (flags & BDRV_O_DIRECT)
127 open_flags |= O_DIRECT;
128 #endif
130 s->type = FTYPE_FILE;
132 fd = open(filename, open_flags, 0644);
133 if (fd < 0) {
134 ret = -errno;
135 if (ret == -EROFS)
136 ret = -EACCES;
137 return ret;
139 s->fd = fd;
140 #if defined(O_DIRECT) && !defined(QEMU_IMG)
141 s->aligned_buf = NULL;
142 if (flags & BDRV_O_DIRECT) {
143 s->aligned_buf = qemu_memalign(512, ALIGNED_BUFFER_SIZE);
144 if (s->aligned_buf == NULL) {
145 ret = -errno;
146 close(fd);
147 return ret;
150 #endif
151 return 0;
154 /* XXX: use host sector size if necessary with:
155 #ifdef DIOCGSECTORSIZE
157 unsigned int sectorsize = 512;
158 if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
159 sectorsize > bufsize)
160 bufsize = sectorsize;
162 #endif
163 #ifdef CONFIG_COCOA
164 u_int32_t blockSize = 512;
165 if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
166 bufsize = blockSize;
168 #endif
172 * offset and count are in bytes, but must be multiples of 512 for files
173 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
175 * This function may be called without alignment if the caller ensures
176 * that O_DIRECT is not in effect.
178 static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
179 uint8_t *buf, int count)
181 BDRVRawState *s = bs->opaque;
182 int ret;
184 ret = fd_open(bs);
185 if (ret < 0)
186 return ret;
188 if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
189 ++(s->lseek_err_cnt);
190 if(s->lseek_err_cnt <= 10) {
191 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
192 "] lseek failed : %d = %s\n",
193 s->fd, bs->filename, offset, buf, count,
194 bs->total_sectors, errno, strerror(errno));
196 return -1;
198 s->lseek_err_cnt=0;
200 ret = read(s->fd, buf, count);
201 if (ret == count)
202 goto label__raw_read__success;
204 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
205 "] read failed %d : %d = %s\n",
206 s->fd, bs->filename, offset, buf, count,
207 bs->total_sectors, ret, errno, strerror(errno));
209 /* Try harder for CDrom. */
210 if (bs->type == BDRV_TYPE_CDROM) {
211 lseek(s->fd, offset, SEEK_SET);
212 ret = read(s->fd, buf, count);
213 if (ret == count)
214 goto label__raw_read__success;
215 lseek(s->fd, offset, SEEK_SET);
216 ret = read(s->fd, buf, count);
217 if (ret == count)
218 goto label__raw_read__success;
220 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
221 "] retry read failed %d : %d = %s\n",
222 s->fd, bs->filename, offset, buf, count,
223 bs->total_sectors, ret, errno, strerror(errno));
226 label__raw_read__success:
228 return ret;
232 * offset and count are in bytes, but must be multiples of 512 for files
233 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
235 * This function may be called without alignment if the caller ensures
236 * that O_DIRECT is not in effect.
238 static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
239 const uint8_t *buf, int count)
241 BDRVRawState *s = bs->opaque;
242 int ret;
244 ret = fd_open(bs);
245 if (ret < 0)
246 return ret;
248 if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
249 ++(s->lseek_err_cnt);
250 if(s->lseek_err_cnt) {
251 DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
252 PRId64 "] lseek failed : %d = %s\n",
253 s->fd, bs->filename, offset, buf, count,
254 bs->total_sectors, errno, strerror(errno));
256 return -1;
258 s->lseek_err_cnt = 0;
260 ret = write(s->fd, buf, count);
261 if (ret == count)
262 goto label__raw_write__success;
264 DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
265 "] write failed %d : %d = %s\n",
266 s->fd, bs->filename, offset, buf, count,
267 bs->total_sectors, ret, errno, strerror(errno));
269 label__raw_write__success:
271 return ret;
275 #if defined(O_DIRECT) && !defined(QEMU_IMG)
277 * offset and count are in bytes and possibly not aligned. For files opened
278 * with O_DIRECT, necessary alignments are ensured before calling
279 * raw_pread_aligned to do the actual read.
281 static int raw_pread(BlockDriverState *bs, int64_t offset,
282 uint8_t *buf, int count)
284 BDRVRawState *s = bs->opaque;
285 int size, ret, shift, sum;
287 sum = 0;
289 if (s->aligned_buf != NULL) {
291 if (offset & 0x1ff) {
292 /* align offset on a 512 bytes boundary */
294 shift = offset & 0x1ff;
295 size = (shift + count + 0x1ff) & ~0x1ff;
296 if (size > ALIGNED_BUFFER_SIZE)
297 size = ALIGNED_BUFFER_SIZE;
298 ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size);
299 if (ret < 0)
300 return ret;
302 size = 512 - shift;
303 if (size > count)
304 size = count;
305 memcpy(buf, s->aligned_buf + shift, size);
307 buf += size;
308 offset += size;
309 count -= size;
310 sum += size;
312 if (count == 0)
313 return sum;
315 if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
317 /* read on aligned buffer */
319 while (count) {
321 size = (count + 0x1ff) & ~0x1ff;
322 if (size > ALIGNED_BUFFER_SIZE)
323 size = ALIGNED_BUFFER_SIZE;
325 ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);
326 if (ret < 0)
327 return ret;
329 size = ret;
330 if (size > count)
331 size = count;
333 memcpy(buf, s->aligned_buf, size);
335 buf += size;
336 offset += size;
337 count -= size;
338 sum += size;
341 return sum;
345 return raw_pread_aligned(bs, offset, buf, count) + sum;
349 * offset and count are in bytes and possibly not aligned. For files opened
350 * with O_DIRECT, necessary alignments are ensured before calling
351 * raw_pwrite_aligned to do the actual write.
353 static int raw_pwrite(BlockDriverState *bs, int64_t offset,
354 const uint8_t *buf, int count)
356 BDRVRawState *s = bs->opaque;
357 int size, ret, shift, sum;
359 sum = 0;
361 if (s->aligned_buf != NULL) {
363 if (offset & 0x1ff) {
364 /* align offset on a 512 bytes boundary */
365 shift = offset & 0x1ff;
366 ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, 512);
367 if (ret < 0)
368 return ret;
370 size = 512 - shift;
371 if (size > count)
372 size = count;
373 memcpy(s->aligned_buf + shift, buf, size);
375 ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf, 512);
376 if (ret < 0)
377 return ret;
379 buf += size;
380 offset += size;
381 count -= size;
382 sum += size;
384 if (count == 0)
385 return sum;
387 if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
389 while ((size = (count & ~0x1ff)) != 0) {
391 if (size > ALIGNED_BUFFER_SIZE)
392 size = ALIGNED_BUFFER_SIZE;
394 memcpy(s->aligned_buf, buf, size);
396 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, size);
397 if (ret < 0)
398 return ret;
400 buf += ret;
401 offset += ret;
402 count -= ret;
403 sum += ret;
405 /* here, count < 512 because (count & ~0x1ff) == 0 */
406 if (count) {
407 ret = raw_pread_aligned(bs, offset, s->aligned_buf, 512);
408 if (ret < 0)
409 return ret;
410 memcpy(s->aligned_buf, buf, count);
412 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, 512);
413 if (ret < 0)
414 return ret;
415 if (count < ret)
416 ret = count;
418 sum += ret;
420 return sum;
423 return raw_pwrite_aligned(bs, offset, buf, count) + sum;
426 #else
427 #define raw_pread raw_pread_aligned
428 #define raw_pwrite raw_pwrite_aligned
429 #endif
432 #ifdef CONFIG_AIO
433 /***********************************************************/
434 /* Unix AIO using POSIX AIO */
436 typedef struct RawAIOCB {
437 BlockDriverAIOCB common;
438 struct aiocb aiocb;
439 struct RawAIOCB *next;
440 int ret;
441 } RawAIOCB;
443 static int aio_sig_fd = -1;
444 static int aio_sig_num = SIGUSR2;
445 static RawAIOCB *first_aio; /* AIO issued */
446 static int aio_initialized = 0;
448 static void qemu_aio_poll(void *opaque)
450 RawAIOCB *acb, **pacb;
451 int ret;
452 size_t offset;
453 union {
454 struct qemu_signalfd_siginfo siginfo;
455 char buf[128];
456 } sig;
458 /* try to read from signalfd, don't freak out if we can't read anything */
459 offset = 0;
460 while (offset < 128) {
461 ssize_t len;
463 len = read(aio_sig_fd, sig.buf + offset, 128 - offset);
464 if (len == -1 && errno == EINTR)
465 continue;
466 if (len == -1 && errno == EAGAIN) {
467 /* there is no natural reason for this to happen,
468 * so we'll spin hard until we get everything just
469 * to be on the safe side. */
470 if (offset > 0)
471 continue;
474 offset += len;
477 for(;;) {
478 pacb = &first_aio;
479 for(;;) {
480 acb = *pacb;
481 if (!acb)
482 goto the_end;
483 ret = aio_error(&acb->aiocb);
484 if (ret == ECANCELED) {
485 /* remove the request */
486 *pacb = acb->next;
487 qemu_aio_release(acb);
488 } else if (ret != EINPROGRESS) {
489 /* end of aio */
490 if (ret == 0) {
491 ret = aio_return(&acb->aiocb);
492 if (ret == acb->aiocb.aio_nbytes)
493 ret = 0;
494 else
495 ret = -EINVAL;
496 } else {
497 ret = -ret;
499 /* remove the request */
500 *pacb = acb->next;
501 /* call the callback */
502 acb->common.cb(acb->common.opaque, ret);
503 qemu_aio_release(acb);
504 break;
505 } else {
506 pacb = &acb->next;
510 the_end: ;
513 void qemu_aio_init(void)
515 sigset_t mask;
517 aio_initialized = 1;
519 /* Make sure to block AIO signal */
520 sigemptyset(&mask);
521 sigaddset(&mask, aio_sig_num);
522 sigprocmask(SIG_BLOCK, &mask, NULL);
524 aio_sig_fd = qemu_signalfd(&mask);
526 fcntl(aio_sig_fd, F_SETFL, O_NONBLOCK);
528 #if !defined(QEMU_IMG) && !defined(QEMU_NBD)
529 qemu_set_fd_handler2(aio_sig_fd, NULL, qemu_aio_poll, NULL, NULL);
530 #endif
532 #if defined(__GLIBC__) && defined(__linux__)
534 /* XXX: aio thread exit seems to hang on RedHat 9 and this init
535 seems to fix the problem. */
536 struct aioinit ai;
537 memset(&ai, 0, sizeof(ai));
538 ai.aio_threads = 1;
539 ai.aio_num = 1;
540 ai.aio_idle_time = 365 * 100000;
541 aio_init(&ai);
543 #endif
546 /* Wait for all IO requests to complete. */
547 void qemu_aio_flush(void)
549 qemu_aio_poll(NULL);
550 while (first_aio) {
551 qemu_aio_wait();
555 void qemu_aio_wait(void)
557 int ret;
559 #if !defined(QEMU_IMG) && !defined(QEMU_NBD)
560 if (qemu_bh_poll())
561 return;
562 #endif
564 if (!first_aio)
565 return;
567 do {
568 fd_set rdfds;
570 FD_ZERO(&rdfds);
571 FD_SET(aio_sig_fd, &rdfds);
573 ret = select(aio_sig_fd + 1, &rdfds, NULL, NULL, NULL);
574 if (ret == -1 && errno == EINTR)
575 continue;
576 } while (ret == 0);
578 qemu_aio_poll(NULL);
581 static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
582 int64_t sector_num, uint8_t *buf, int nb_sectors,
583 BlockDriverCompletionFunc *cb, void *opaque)
585 BDRVRawState *s = bs->opaque;
586 RawAIOCB *acb;
588 if (fd_open(bs) < 0)
589 return NULL;
591 acb = qemu_aio_get(bs, cb, opaque);
592 if (!acb)
593 return NULL;
594 acb->aiocb.aio_fildes = s->fd;
595 acb->aiocb.aio_sigevent.sigev_signo = aio_sig_num;
596 acb->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
597 acb->aiocb.aio_buf = buf;
598 if (nb_sectors < 0)
599 acb->aiocb.aio_nbytes = -nb_sectors;
600 else
601 acb->aiocb.aio_nbytes = nb_sectors * 512;
602 acb->aiocb.aio_offset = sector_num * 512;
603 acb->next = first_aio;
604 first_aio = acb;
605 return acb;
608 #if !defined(QEMU_IMG) && !defined(QEMU_NBD)
609 static void raw_aio_em_cb(void* opaque)
611 RawAIOCB *acb = opaque;
612 acb->common.cb(acb->common.opaque, acb->ret);
613 qemu_aio_release(acb);
615 #endif
617 static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
618 int64_t sector_num, uint8_t *buf, int nb_sectors,
619 BlockDriverCompletionFunc *cb, void *opaque)
621 RawAIOCB *acb;
624 * If O_DIRECT is used and the buffer is not aligned fall back
625 * to synchronous IO.
627 #if defined(O_DIRECT) && !defined(QEMU_IMG) && !defined(QEMU_NBD)
628 BDRVRawState *s = bs->opaque;
630 if (unlikely(s->aligned_buf != NULL && ((uintptr_t) buf % 512))) {
631 QEMUBH *bh;
632 acb = qemu_aio_get(bs, cb, opaque);
633 acb->ret = raw_pread(bs, 512 * sector_num, buf, 512 * nb_sectors);
634 bh = qemu_bh_new(raw_aio_em_cb, acb);
635 qemu_bh_schedule(bh);
636 return &acb->common;
638 #endif
640 acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
641 if (!acb)
642 return NULL;
643 if (aio_read(&acb->aiocb) < 0) {
644 qemu_aio_release(acb);
645 return NULL;
647 return &acb->common;
650 static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
651 int64_t sector_num, const uint8_t *buf, int nb_sectors,
652 BlockDriverCompletionFunc *cb, void *opaque)
654 RawAIOCB *acb;
657 * If O_DIRECT is used and the buffer is not aligned fall back
658 * to synchronous IO.
660 #if defined(O_DIRECT) && !defined(QEMU_IMG) && !defined(QEMU_NBD)
661 BDRVRawState *s = bs->opaque;
663 if (unlikely(s->aligned_buf != NULL && ((uintptr_t) buf % 512))) {
664 QEMUBH *bh;
665 acb = qemu_aio_get(bs, cb, opaque);
666 acb->ret = raw_pwrite(bs, 512 * sector_num, buf, 512 * nb_sectors);
667 bh = qemu_bh_new(raw_aio_em_cb, acb);
668 qemu_bh_schedule(bh);
669 return &acb->common;
671 #endif
673 acb = raw_aio_setup(bs, sector_num, (uint8_t*)buf, nb_sectors, cb, opaque);
674 if (!acb)
675 return NULL;
676 if (aio_write(&acb->aiocb) < 0) {
677 qemu_aio_release(acb);
678 return NULL;
680 return &acb->common;
683 static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
685 int ret;
686 RawAIOCB *acb = (RawAIOCB *)blockacb;
687 RawAIOCB **pacb;
689 ret = aio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
690 if (ret == AIO_NOTCANCELED) {
691 /* fail safe: if the aio could not be canceled, we wait for
692 it */
693 while (aio_error(&acb->aiocb) == EINPROGRESS);
696 /* remove the callback from the queue */
697 pacb = &first_aio;
698 for(;;) {
699 if (*pacb == NULL) {
700 break;
701 } else if (*pacb == acb) {
702 *pacb = acb->next;
703 qemu_aio_release(acb);
704 break;
706 pacb = &acb->next;
710 # else /* CONFIG_AIO */
712 void qemu_aio_init(void)
716 void qemu_aio_flush(void)
720 void qemu_aio_wait(void)
722 #if !defined(QEMU_IMG) && !defined(QEMU_NBD)
723 qemu_bh_poll();
724 #endif
727 #endif /* CONFIG_AIO */
729 static void raw_close(BlockDriverState *bs)
731 BDRVRawState *s = bs->opaque;
732 if (s->fd >= 0) {
733 close(s->fd);
734 s->fd = -1;
735 #if defined(O_DIRECT) && !defined(QEMU_IMG)
736 if (s->aligned_buf != NULL)
737 qemu_free(s->aligned_buf);
738 #endif
742 static int raw_truncate(BlockDriverState *bs, int64_t offset)
744 BDRVRawState *s = bs->opaque;
745 if (s->type != FTYPE_FILE)
746 return -ENOTSUP;
747 if (ftruncate(s->fd, offset) < 0)
748 return -errno;
749 return 0;
752 #ifdef __OpenBSD__
753 static int64_t raw_getlength(BlockDriverState *bs)
755 BDRVRawState *s = bs->opaque;
756 int fd = s->fd;
757 struct stat st;
759 if (fstat(fd, &st))
760 return -1;
761 if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
762 struct disklabel dl;
764 if (ioctl(fd, DIOCGDINFO, &dl))
765 return -1;
766 return (uint64_t)dl.d_secsize *
767 dl.d_partitions[DISKPART(st.st_rdev)].p_size;
768 } else
769 return st.st_size;
771 #else /* !__OpenBSD__ */
772 static int64_t raw_getlength(BlockDriverState *bs)
774 BDRVRawState *s = bs->opaque;
775 int fd = s->fd;
776 int64_t size;
777 #ifdef _BSD
778 struct stat sb;
779 #endif
780 #ifdef __sun__
781 struct dk_minfo minfo;
782 int rv;
783 #endif
784 int ret;
786 ret = fd_open(bs);
787 if (ret < 0)
788 return ret;
790 #ifdef _BSD
791 if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
792 #ifdef DIOCGMEDIASIZE
793 if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
794 #endif
795 #ifdef CONFIG_COCOA
796 size = LONG_LONG_MAX;
797 #else
798 size = lseek(fd, 0LL, SEEK_END);
799 #endif
800 } else
801 #endif
802 #ifdef __sun__
804 * use the DKIOCGMEDIAINFO ioctl to read the size.
806 rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
807 if ( rv != -1 ) {
808 size = minfo.dki_lbsize * minfo.dki_capacity;
809 } else /* there are reports that lseek on some devices
810 fails, but irc discussion said that contingency
811 on contingency was overkill */
812 #endif
814 size = lseek(fd, 0, SEEK_END);
816 return size;
818 #endif
820 static int raw_create(const char *filename, int64_t total_size,
821 const char *backing_file, int flags)
823 int fd;
825 if (flags || backing_file)
826 return -ENOTSUP;
828 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
829 0644);
830 if (fd < 0)
831 return -EIO;
832 ftruncate(fd, total_size * 512);
833 close(fd);
834 return 0;
837 static void raw_flush(BlockDriverState *bs)
839 BDRVRawState *s = bs->opaque;
840 fsync(s->fd);
843 BlockDriver bdrv_raw = {
844 "raw",
845 sizeof(BDRVRawState),
846 NULL, /* no probe for protocols */
847 raw_open,
848 NULL,
849 NULL,
850 raw_close,
851 raw_create,
852 raw_flush,
854 #ifdef CONFIG_AIO
855 .bdrv_aio_read = raw_aio_read,
856 .bdrv_aio_write = raw_aio_write,
857 .bdrv_aio_cancel = raw_aio_cancel,
858 .aiocb_size = sizeof(RawAIOCB),
859 #endif
860 .protocol_name = "file",
861 .bdrv_pread = raw_pread,
862 .bdrv_pwrite = raw_pwrite,
863 .bdrv_truncate = raw_truncate,
864 .bdrv_getlength = raw_getlength,
867 /***********************************************/
868 /* host device */
870 #ifdef CONFIG_COCOA
871 static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
872 static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
874 kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
876 kern_return_t kernResult;
877 mach_port_t masterPort;
878 CFMutableDictionaryRef classesToMatch;
880 kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
881 if ( KERN_SUCCESS != kernResult ) {
882 printf( "IOMasterPort returned %d\n", kernResult );
885 classesToMatch = IOServiceMatching( kIOCDMediaClass );
886 if ( classesToMatch == NULL ) {
887 printf( "IOServiceMatching returned a NULL dictionary.\n" );
888 } else {
889 CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
891 kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
892 if ( KERN_SUCCESS != kernResult )
894 printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
897 return kernResult;
900 kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
902 io_object_t nextMedia;
903 kern_return_t kernResult = KERN_FAILURE;
904 *bsdPath = '\0';
905 nextMedia = IOIteratorNext( mediaIterator );
906 if ( nextMedia )
908 CFTypeRef bsdPathAsCFString;
909 bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
910 if ( bsdPathAsCFString ) {
911 size_t devPathLength;
912 strcpy( bsdPath, _PATH_DEV );
913 strcat( bsdPath, "r" );
914 devPathLength = strlen( bsdPath );
915 if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
916 kernResult = KERN_SUCCESS;
918 CFRelease( bsdPathAsCFString );
920 IOObjectRelease( nextMedia );
923 return kernResult;
926 #endif
928 static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
930 BDRVRawState *s = bs->opaque;
931 int fd, open_flags, ret;
933 #ifdef CONFIG_COCOA
934 if (strstart(filename, "/dev/cdrom", NULL)) {
935 kern_return_t kernResult;
936 io_iterator_t mediaIterator;
937 char bsdPath[ MAXPATHLEN ];
938 int fd;
940 kernResult = FindEjectableCDMedia( &mediaIterator );
941 kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
943 if ( bsdPath[ 0 ] != '\0' ) {
944 strcat(bsdPath,"s0");
945 /* some CDs don't have a partition 0 */
946 fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
947 if (fd < 0) {
948 bsdPath[strlen(bsdPath)-1] = '1';
949 } else {
950 close(fd);
952 filename = bsdPath;
955 if ( mediaIterator )
956 IOObjectRelease( mediaIterator );
958 #endif
959 open_flags = O_BINARY;
960 if ((flags & BDRV_O_ACCESS) == O_RDWR) {
961 open_flags |= O_RDWR;
962 } else {
963 open_flags |= O_RDONLY;
964 bs->read_only = 1;
966 #ifdef O_DIRECT
967 if (flags & BDRV_O_DIRECT)
968 open_flags |= O_DIRECT;
969 #endif
971 s->type = FTYPE_FILE;
972 #if defined(__linux__)
973 if (strstart(filename, "/dev/cd", NULL)) {
974 /* open will not fail even if no CD is inserted */
975 open_flags |= O_NONBLOCK;
976 s->type = FTYPE_CD;
977 } else if (strstart(filename, "/dev/fd", NULL)) {
978 s->type = FTYPE_FD;
979 s->fd_open_flags = open_flags;
980 /* open will not fail even if no floppy is inserted */
981 open_flags |= O_NONBLOCK;
982 } else if (strstart(filename, "/dev/sg", NULL)) {
983 bs->sg = 1;
985 #endif
986 fd = open(filename, open_flags, 0644);
987 if (fd < 0) {
988 ret = -errno;
989 if (ret == -EROFS)
990 ret = -EACCES;
991 return ret;
993 s->fd = fd;
994 #if defined(__linux__)
995 /* close fd so that we can reopen it as needed */
996 if (s->type == FTYPE_FD) {
997 close(s->fd);
998 s->fd = -1;
999 s->fd_media_changed = 1;
1001 #endif
1002 return 0;
1005 #if defined(__linux__) && !defined(QEMU_IMG) && !defined(QEMU_NBD)
1007 /* Note: we do not have a reliable method to detect if the floppy is
1008 present. The current method is to try to open the floppy at every
1009 I/O and to keep it opened during a few hundreds of ms. */
1010 static int fd_open(BlockDriverState *bs)
1012 BDRVRawState *s = bs->opaque;
1013 int last_media_present;
1015 if (s->type != FTYPE_FD)
1016 return 0;
1017 last_media_present = (s->fd >= 0);
1018 if (s->fd >= 0 &&
1019 (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
1020 close(s->fd);
1021 s->fd = -1;
1022 #ifdef DEBUG_FLOPPY
1023 printf("Floppy closed\n");
1024 #endif
1026 if (s->fd < 0) {
1027 if (s->fd_got_error &&
1028 (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
1029 #ifdef DEBUG_FLOPPY
1030 printf("No floppy (open delayed)\n");
1031 #endif
1032 return -EIO;
1034 s->fd = open(bs->filename, s->fd_open_flags);
1035 if (s->fd < 0) {
1036 s->fd_error_time = qemu_get_clock(rt_clock);
1037 s->fd_got_error = 1;
1038 if (last_media_present)
1039 s->fd_media_changed = 1;
1040 #ifdef DEBUG_FLOPPY
1041 printf("No floppy\n");
1042 #endif
1043 return -EIO;
1045 #ifdef DEBUG_FLOPPY
1046 printf("Floppy opened\n");
1047 #endif
1049 if (!last_media_present)
1050 s->fd_media_changed = 1;
1051 s->fd_open_time = qemu_get_clock(rt_clock);
1052 s->fd_got_error = 0;
1053 return 0;
1055 #else
1056 static int fd_open(BlockDriverState *bs)
1058 return 0;
1060 #endif
1062 #if defined(__linux__)
1064 static int raw_is_inserted(BlockDriverState *bs)
1066 BDRVRawState *s = bs->opaque;
1067 int ret;
1069 switch(s->type) {
1070 case FTYPE_CD:
1071 ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1072 if (ret == CDS_DISC_OK)
1073 return 1;
1074 else
1075 return 0;
1076 break;
1077 case FTYPE_FD:
1078 ret = fd_open(bs);
1079 return (ret >= 0);
1080 default:
1081 return 1;
1085 /* currently only used by fdc.c, but a CD version would be good too */
1086 static int raw_media_changed(BlockDriverState *bs)
1088 BDRVRawState *s = bs->opaque;
1090 switch(s->type) {
1091 case FTYPE_FD:
1093 int ret;
1094 /* XXX: we do not have a true media changed indication. It
1095 does not work if the floppy is changed without trying
1096 to read it */
1097 fd_open(bs);
1098 ret = s->fd_media_changed;
1099 s->fd_media_changed = 0;
1100 #ifdef DEBUG_FLOPPY
1101 printf("Floppy changed=%d\n", ret);
1102 #endif
1103 return ret;
1105 default:
1106 return -ENOTSUP;
1110 static int raw_eject(BlockDriverState *bs, int eject_flag)
1112 BDRVRawState *s = bs->opaque;
1114 switch(s->type) {
1115 case FTYPE_CD:
1116 if (eject_flag) {
1117 if (ioctl (s->fd, CDROMEJECT, NULL) < 0)
1118 perror("CDROMEJECT");
1119 } else {
1120 if (ioctl (s->fd, CDROMCLOSETRAY, NULL) < 0)
1121 perror("CDROMEJECT");
1123 break;
1124 case FTYPE_FD:
1126 int fd;
1127 if (s->fd >= 0) {
1128 close(s->fd);
1129 s->fd = -1;
1131 fd = open(bs->filename, s->fd_open_flags | O_NONBLOCK);
1132 if (fd >= 0) {
1133 if (ioctl(fd, FDEJECT, 0) < 0)
1134 perror("FDEJECT");
1135 close(fd);
1138 break;
1139 default:
1140 return -ENOTSUP;
1142 return 0;
1145 static int raw_set_locked(BlockDriverState *bs, int locked)
1147 BDRVRawState *s = bs->opaque;
1149 switch(s->type) {
1150 case FTYPE_CD:
1151 if (ioctl (s->fd, CDROM_LOCKDOOR, locked) < 0) {
1152 /* Note: an error can happen if the distribution automatically
1153 mounts the CD-ROM */
1154 // perror("CDROM_LOCKDOOR");
1156 break;
1157 default:
1158 return -ENOTSUP;
1160 return 0;
1163 static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1165 BDRVRawState *s = bs->opaque;
1167 return ioctl(s->fd, req, buf);
1169 #else
1171 static int raw_is_inserted(BlockDriverState *bs)
1173 return 1;
1176 static int raw_media_changed(BlockDriverState *bs)
1178 return -ENOTSUP;
1181 static int raw_eject(BlockDriverState *bs, int eject_flag)
1183 return -ENOTSUP;
1186 static int raw_set_locked(BlockDriverState *bs, int locked)
1188 return -ENOTSUP;
1191 static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1193 return -ENOTSUP;
1195 #endif /* !linux */
1197 BlockDriver bdrv_host_device = {
1198 "host_device",
1199 sizeof(BDRVRawState),
1200 NULL, /* no probe for protocols */
1201 hdev_open,
1202 NULL,
1203 NULL,
1204 raw_close,
1205 NULL,
1206 raw_flush,
1208 #ifdef CONFIG_AIO
1209 .bdrv_aio_read = raw_aio_read,
1210 .bdrv_aio_write = raw_aio_write,
1211 .bdrv_aio_cancel = raw_aio_cancel,
1212 .aiocb_size = sizeof(RawAIOCB),
1213 #endif
1214 .bdrv_pread = raw_pread,
1215 .bdrv_pwrite = raw_pwrite,
1216 .bdrv_getlength = raw_getlength,
1218 /* removable device support */
1219 .bdrv_is_inserted = raw_is_inserted,
1220 .bdrv_media_changed = raw_media_changed,
1221 .bdrv_eject = raw_eject,
1222 .bdrv_set_locked = raw_set_locked,
1223 /* generic scsi device */
1224 .bdrv_ioctl = raw_ioctl,