]> git.proxmox.com Git - qemu.git/blob - block/raw-posix.c
block: use BDRV_O_NOCACHE instead of s->aligned_buf in raw-posix.c
[qemu.git] / block / raw-posix.c
1 /*
2 * Block driver for RAW files (posix)
3 *
4 * Copyright (c) 2006 Fabrice Bellard
5 *
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:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
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.
23 */
24 #include "qemu-common.h"
25 #include "qemu-timer.h"
26 #include "qemu-char.h"
27 #include "qemu-log.h"
28 #include "block_int.h"
29 #include "module.h"
30 #include "block/raw-posix-aio.h"
31
32 #if defined(__APPLE__) && (__MACH__)
33 #include <paths.h>
34 #include <sys/param.h>
35 #include <IOKit/IOKitLib.h>
36 #include <IOKit/IOBSD.h>
37 #include <IOKit/storage/IOMediaBSDClient.h>
38 #include <IOKit/storage/IOMedia.h>
39 #include <IOKit/storage/IOCDMedia.h>
40 //#include <IOKit/storage/IOCDTypes.h>
41 #include <CoreFoundation/CoreFoundation.h>
42 #endif
43
44 #ifdef __sun__
45 #define _POSIX_PTHREAD_SEMANTICS 1
46 #include <sys/dkio.h>
47 #endif
48 #ifdef __linux__
49 #include <sys/types.h>
50 #include <sys/stat.h>
51 #include <sys/ioctl.h>
52 #include <sys/param.h>
53 #include <linux/cdrom.h>
54 #include <linux/fd.h>
55 #include <linux/fs.h>
56 #endif
57 #ifdef CONFIG_FIEMAP
58 #include <linux/fiemap.h>
59 #endif
60 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
61 #include <sys/disk.h>
62 #include <sys/cdio.h>
63 #endif
64
65 #ifdef __OpenBSD__
66 #include <sys/ioctl.h>
67 #include <sys/disklabel.h>
68 #include <sys/dkio.h>
69 #endif
70
71 #ifdef __NetBSD__
72 #include <sys/ioctl.h>
73 #include <sys/disklabel.h>
74 #include <sys/dkio.h>
75 #include <sys/disk.h>
76 #endif
77
78 #ifdef __DragonFly__
79 #include <sys/ioctl.h>
80 #include <sys/diskslice.h>
81 #endif
82
83 #ifdef CONFIG_XFS
84 #include <xfs/xfs.h>
85 #endif
86
87 //#define DEBUG_FLOPPY
88
89 //#define DEBUG_BLOCK
90 #if defined(DEBUG_BLOCK)
91 #define DEBUG_BLOCK_PRINT(formatCstr, ...) do { if (qemu_log_enabled()) \
92 { qemu_log(formatCstr, ## __VA_ARGS__); qemu_log_flush(); } } while (0)
93 #else
94 #define DEBUG_BLOCK_PRINT(formatCstr, ...)
95 #endif
96
97 /* OS X does not have O_DSYNC */
98 #ifndef O_DSYNC
99 #ifdef O_SYNC
100 #define O_DSYNC O_SYNC
101 #elif defined(O_FSYNC)
102 #define O_DSYNC O_FSYNC
103 #endif
104 #endif
105
106 /* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */
107 #ifndef O_DIRECT
108 #define O_DIRECT O_DSYNC
109 #endif
110
111 #define FTYPE_FILE 0
112 #define FTYPE_CD 1
113 #define FTYPE_FD 2
114
115 /* if the FD is not accessed during that time (in ns), we try to
116 reopen it to see if the disk has been changed */
117 #define FD_OPEN_TIMEOUT (1000000000)
118
119 #define MAX_BLOCKSIZE 4096
120
121 typedef struct BDRVRawState {
122 int fd;
123 int type;
124 int open_flags;
125 #if defined(__linux__)
126 /* linux floppy specific */
127 int64_t fd_open_time;
128 int64_t fd_error_time;
129 int fd_got_error;
130 int fd_media_changed;
131 #endif
132 #ifdef CONFIG_LINUX_AIO
133 int use_aio;
134 void *aio_ctx;
135 #endif
136 uint8_t *aligned_buf;
137 unsigned aligned_buf_size;
138 #ifdef CONFIG_XFS
139 bool is_xfs : 1;
140 #endif
141 } BDRVRawState;
142
143 static int fd_open(BlockDriverState *bs);
144 static int64_t raw_getlength(BlockDriverState *bs);
145
146 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
147 static int cdrom_reopen(BlockDriverState *bs);
148 #endif
149
150 #if defined(__NetBSD__)
151 static int raw_normalize_devicepath(const char **filename)
152 {
153 static char namebuf[PATH_MAX];
154 const char *dp, *fname;
155 struct stat sb;
156
157 fname = *filename;
158 dp = strrchr(fname, '/');
159 if (lstat(fname, &sb) < 0) {
160 fprintf(stderr, "%s: stat failed: %s\n",
161 fname, strerror(errno));
162 return -errno;
163 }
164
165 if (!S_ISBLK(sb.st_mode)) {
166 return 0;
167 }
168
169 if (dp == NULL) {
170 snprintf(namebuf, PATH_MAX, "r%s", fname);
171 } else {
172 snprintf(namebuf, PATH_MAX, "%.*s/r%s",
173 (int)(dp - fname), fname, dp + 1);
174 }
175 fprintf(stderr, "%s is a block device", fname);
176 *filename = namebuf;
177 fprintf(stderr, ", using %s\n", *filename);
178
179 return 0;
180 }
181 #else
182 static int raw_normalize_devicepath(const char **filename)
183 {
184 return 0;
185 }
186 #endif
187
188 static void raw_parse_flags(int bdrv_flags, int *open_flags)
189 {
190 assert(open_flags != NULL);
191
192 *open_flags |= O_BINARY;
193 *open_flags &= ~O_ACCMODE;
194 if (bdrv_flags & BDRV_O_RDWR) {
195 *open_flags |= O_RDWR;
196 } else {
197 *open_flags |= O_RDONLY;
198 }
199
200 /* Use O_DSYNC for write-through caching, no flags for write-back caching,
201 * and O_DIRECT for no caching. */
202 if ((bdrv_flags & BDRV_O_NOCACHE)) {
203 *open_flags |= O_DIRECT;
204 }
205 }
206
207 #ifdef CONFIG_LINUX_AIO
208 static int raw_set_aio(void **aio_ctx, int *use_aio, int bdrv_flags)
209 {
210 int ret = -1;
211 assert(aio_ctx != NULL);
212 assert(use_aio != NULL);
213 /*
214 * Currently Linux do AIO only for files opened with O_DIRECT
215 * specified so check NOCACHE flag too
216 */
217 if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) ==
218 (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) {
219
220 /* if non-NULL, laio_init() has already been run */
221 if (*aio_ctx == NULL) {
222 *aio_ctx = laio_init();
223 if (!*aio_ctx) {
224 goto error;
225 }
226 }
227 *use_aio = 1;
228 } else {
229 *use_aio = 0;
230 }
231
232 ret = 0;
233
234 error:
235 return ret;
236 }
237 #endif
238
239 static int raw_open_common(BlockDriverState *bs, const char *filename,
240 int bdrv_flags, int open_flags)
241 {
242 BDRVRawState *s = bs->opaque;
243 int fd, ret;
244
245 ret = raw_normalize_devicepath(&filename);
246 if (ret != 0) {
247 return ret;
248 }
249
250 s->open_flags = open_flags;
251 raw_parse_flags(bdrv_flags, &s->open_flags);
252
253 s->fd = -1;
254 fd = qemu_open(filename, s->open_flags, 0644);
255 if (fd < 0) {
256 ret = -errno;
257 if (ret == -EROFS)
258 ret = -EACCES;
259 return ret;
260 }
261 s->fd = fd;
262 s->aligned_buf = NULL;
263
264 if ((bdrv_flags & BDRV_O_NOCACHE)) {
265 /*
266 * Allocate a buffer for read/modify/write cycles. Chose the size
267 * pessimistically as we don't know the block size yet.
268 */
269 s->aligned_buf_size = 32 * MAX_BLOCKSIZE;
270 s->aligned_buf = qemu_memalign(MAX_BLOCKSIZE, s->aligned_buf_size);
271 if (s->aligned_buf == NULL) {
272 goto out_close;
273 }
274 }
275
276 /* We're falling back to POSIX AIO in some cases so init always */
277 if (paio_init() < 0) {
278 goto out_free_buf;
279 }
280
281 #ifdef CONFIG_LINUX_AIO
282 if (raw_set_aio(&s->aio_ctx, &s->use_aio, bdrv_flags)) {
283 goto out_close;
284 }
285 #endif
286
287 #ifdef CONFIG_XFS
288 if (platform_test_xfs_fd(s->fd)) {
289 s->is_xfs = 1;
290 }
291 #endif
292
293 return 0;
294
295 out_free_buf:
296 qemu_vfree(s->aligned_buf);
297 out_close:
298 qemu_close(fd);
299 return -errno;
300 }
301
302 static int raw_open(BlockDriverState *bs, const char *filename, int flags)
303 {
304 BDRVRawState *s = bs->opaque;
305
306 s->type = FTYPE_FILE;
307 return raw_open_common(bs, filename, flags, 0);
308 }
309
310 /* XXX: use host sector size if necessary with:
311 #ifdef DIOCGSECTORSIZE
312 {
313 unsigned int sectorsize = 512;
314 if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
315 sectorsize > bufsize)
316 bufsize = sectorsize;
317 }
318 #endif
319 #ifdef CONFIG_COCOA
320 uint32_t blockSize = 512;
321 if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
322 bufsize = blockSize;
323 }
324 #endif
325 */
326
327 /*
328 * Check if all memory in this vector is sector aligned.
329 */
330 static int qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
331 {
332 int i;
333
334 for (i = 0; i < qiov->niov; i++) {
335 if ((uintptr_t) qiov->iov[i].iov_base % bs->buffer_alignment) {
336 return 0;
337 }
338 }
339
340 return 1;
341 }
342
343 static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,
344 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
345 BlockDriverCompletionFunc *cb, void *opaque, int type)
346 {
347 BDRVRawState *s = bs->opaque;
348
349 if (fd_open(bs) < 0)
350 return NULL;
351
352 /*
353 * If O_DIRECT is used the buffer needs to be aligned on a sector
354 * boundary. Check if this is the case or tell the low-level
355 * driver that it needs to copy the buffer.
356 */
357 if ((bs->open_flags & BDRV_O_NOCACHE)) {
358 if (!qiov_is_aligned(bs, qiov)) {
359 type |= QEMU_AIO_MISALIGNED;
360 #ifdef CONFIG_LINUX_AIO
361 } else if (s->use_aio) {
362 return laio_submit(bs, s->aio_ctx, s->fd, sector_num, qiov,
363 nb_sectors, cb, opaque, type);
364 #endif
365 }
366 }
367
368 return paio_submit(bs, s->fd, sector_num, qiov, nb_sectors,
369 cb, opaque, type);
370 }
371
372 static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
373 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
374 BlockDriverCompletionFunc *cb, void *opaque)
375 {
376 return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
377 cb, opaque, QEMU_AIO_READ);
378 }
379
380 static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
381 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
382 BlockDriverCompletionFunc *cb, void *opaque)
383 {
384 return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
385 cb, opaque, QEMU_AIO_WRITE);
386 }
387
388 static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
389 BlockDriverCompletionFunc *cb, void *opaque)
390 {
391 BDRVRawState *s = bs->opaque;
392
393 if (fd_open(bs) < 0)
394 return NULL;
395
396 return paio_submit(bs, s->fd, 0, NULL, 0, cb, opaque, QEMU_AIO_FLUSH);
397 }
398
399 static void raw_close(BlockDriverState *bs)
400 {
401 BDRVRawState *s = bs->opaque;
402 if (s->fd >= 0) {
403 qemu_close(s->fd);
404 s->fd = -1;
405 if (s->aligned_buf != NULL)
406 qemu_vfree(s->aligned_buf);
407 }
408 }
409
410 static int raw_truncate(BlockDriverState *bs, int64_t offset)
411 {
412 BDRVRawState *s = bs->opaque;
413 struct stat st;
414
415 if (fstat(s->fd, &st)) {
416 return -errno;
417 }
418
419 if (S_ISREG(st.st_mode)) {
420 if (ftruncate(s->fd, offset) < 0) {
421 return -errno;
422 }
423 } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
424 if (offset > raw_getlength(bs)) {
425 return -EINVAL;
426 }
427 } else {
428 return -ENOTSUP;
429 }
430
431 return 0;
432 }
433
434 #ifdef __OpenBSD__
435 static int64_t raw_getlength(BlockDriverState *bs)
436 {
437 BDRVRawState *s = bs->opaque;
438 int fd = s->fd;
439 struct stat st;
440
441 if (fstat(fd, &st))
442 return -1;
443 if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
444 struct disklabel dl;
445
446 if (ioctl(fd, DIOCGDINFO, &dl))
447 return -1;
448 return (uint64_t)dl.d_secsize *
449 dl.d_partitions[DISKPART(st.st_rdev)].p_size;
450 } else
451 return st.st_size;
452 }
453 #elif defined(__NetBSD__)
454 static int64_t raw_getlength(BlockDriverState *bs)
455 {
456 BDRVRawState *s = bs->opaque;
457 int fd = s->fd;
458 struct stat st;
459
460 if (fstat(fd, &st))
461 return -1;
462 if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
463 struct dkwedge_info dkw;
464
465 if (ioctl(fd, DIOCGWEDGEINFO, &dkw) != -1) {
466 return dkw.dkw_size * 512;
467 } else {
468 struct disklabel dl;
469
470 if (ioctl(fd, DIOCGDINFO, &dl))
471 return -1;
472 return (uint64_t)dl.d_secsize *
473 dl.d_partitions[DISKPART(st.st_rdev)].p_size;
474 }
475 } else
476 return st.st_size;
477 }
478 #elif defined(__sun__)
479 static int64_t raw_getlength(BlockDriverState *bs)
480 {
481 BDRVRawState *s = bs->opaque;
482 struct dk_minfo minfo;
483 int ret;
484
485 ret = fd_open(bs);
486 if (ret < 0) {
487 return ret;
488 }
489
490 /*
491 * Use the DKIOCGMEDIAINFO ioctl to read the size.
492 */
493 ret = ioctl(s->fd, DKIOCGMEDIAINFO, &minfo);
494 if (ret != -1) {
495 return minfo.dki_lbsize * minfo.dki_capacity;
496 }
497
498 /*
499 * There are reports that lseek on some devices fails, but
500 * irc discussion said that contingency on contingency was overkill.
501 */
502 return lseek(s->fd, 0, SEEK_END);
503 }
504 #elif defined(CONFIG_BSD)
505 static int64_t raw_getlength(BlockDriverState *bs)
506 {
507 BDRVRawState *s = bs->opaque;
508 int fd = s->fd;
509 int64_t size;
510 struct stat sb;
511 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
512 int reopened = 0;
513 #endif
514 int ret;
515
516 ret = fd_open(bs);
517 if (ret < 0)
518 return ret;
519
520 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
521 again:
522 #endif
523 if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
524 #ifdef DIOCGMEDIASIZE
525 if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
526 #elif defined(DIOCGPART)
527 {
528 struct partinfo pi;
529 if (ioctl(fd, DIOCGPART, &pi) == 0)
530 size = pi.media_size;
531 else
532 size = 0;
533 }
534 if (size == 0)
535 #endif
536 #if defined(__APPLE__) && defined(__MACH__)
537 size = LONG_LONG_MAX;
538 #else
539 size = lseek(fd, 0LL, SEEK_END);
540 #endif
541 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
542 switch(s->type) {
543 case FTYPE_CD:
544 /* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */
545 if (size == 2048LL * (unsigned)-1)
546 size = 0;
547 /* XXX no disc? maybe we need to reopen... */
548 if (size <= 0 && !reopened && cdrom_reopen(bs) >= 0) {
549 reopened = 1;
550 goto again;
551 }
552 }
553 #endif
554 } else {
555 size = lseek(fd, 0, SEEK_END);
556 }
557 return size;
558 }
559 #else
560 static int64_t raw_getlength(BlockDriverState *bs)
561 {
562 BDRVRawState *s = bs->opaque;
563 int ret;
564
565 ret = fd_open(bs);
566 if (ret < 0) {
567 return ret;
568 }
569
570 return lseek(s->fd, 0, SEEK_END);
571 }
572 #endif
573
574 static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
575 {
576 struct stat st;
577 BDRVRawState *s = bs->opaque;
578
579 if (fstat(s->fd, &st) < 0) {
580 return -errno;
581 }
582 return (int64_t)st.st_blocks * 512;
583 }
584
585 static int raw_create(const char *filename, QEMUOptionParameter *options)
586 {
587 int fd;
588 int result = 0;
589 int64_t total_size = 0;
590
591 /* Read out options */
592 while (options && options->name) {
593 if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
594 total_size = options->value.n / BDRV_SECTOR_SIZE;
595 }
596 options++;
597 }
598
599 fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
600 0644);
601 if (fd < 0) {
602 result = -errno;
603 } else {
604 if (ftruncate(fd, total_size * BDRV_SECTOR_SIZE) != 0) {
605 result = -errno;
606 }
607 if (qemu_close(fd) != 0) {
608 result = -errno;
609 }
610 }
611 return result;
612 }
613
614 /*
615 * Returns true iff the specified sector is present in the disk image. Drivers
616 * not implementing the functionality are assumed to not support backing files,
617 * hence all their sectors are reported as allocated.
618 *
619 * If 'sector_num' is beyond the end of the disk image the return value is 0
620 * and 'pnum' is set to 0.
621 *
622 * 'pnum' is set to the number of sectors (including and immediately following
623 * the specified sector) that are known to be in the same
624 * allocated/unallocated state.
625 *
626 * 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes
627 * beyond the end of the disk image it will be clamped.
628 */
629 static int coroutine_fn raw_co_is_allocated(BlockDriverState *bs,
630 int64_t sector_num,
631 int nb_sectors, int *pnum)
632 {
633 off_t start, data, hole;
634 int ret;
635
636 ret = fd_open(bs);
637 if (ret < 0) {
638 return ret;
639 }
640
641 start = sector_num * BDRV_SECTOR_SIZE;
642
643 #ifdef CONFIG_FIEMAP
644
645 BDRVRawState *s = bs->opaque;
646 struct {
647 struct fiemap fm;
648 struct fiemap_extent fe;
649 } f;
650
651 f.fm.fm_start = start;
652 f.fm.fm_length = (int64_t)nb_sectors * BDRV_SECTOR_SIZE;
653 f.fm.fm_flags = 0;
654 f.fm.fm_extent_count = 1;
655 f.fm.fm_reserved = 0;
656 if (ioctl(s->fd, FS_IOC_FIEMAP, &f) == -1) {
657 /* Assume everything is allocated. */
658 *pnum = nb_sectors;
659 return 1;
660 }
661
662 if (f.fm.fm_mapped_extents == 0) {
663 /* No extents found, data is beyond f.fm.fm_start + f.fm.fm_length.
664 * f.fm.fm_start + f.fm.fm_length must be clamped to the file size!
665 */
666 off_t length = lseek(s->fd, 0, SEEK_END);
667 hole = f.fm.fm_start;
668 data = MIN(f.fm.fm_start + f.fm.fm_length, length);
669 } else {
670 data = f.fe.fe_logical;
671 hole = f.fe.fe_logical + f.fe.fe_length;
672 }
673
674 #elif defined SEEK_HOLE && defined SEEK_DATA
675
676 BDRVRawState *s = bs->opaque;
677
678 hole = lseek(s->fd, start, SEEK_HOLE);
679 if (hole == -1) {
680 /* -ENXIO indicates that sector_num was past the end of the file.
681 * There is a virtual hole there. */
682 assert(errno != -ENXIO);
683
684 /* Most likely EINVAL. Assume everything is allocated. */
685 *pnum = nb_sectors;
686 return 1;
687 }
688
689 if (hole > start) {
690 data = start;
691 } else {
692 /* On a hole. We need another syscall to find its end. */
693 data = lseek(s->fd, start, SEEK_DATA);
694 if (data == -1) {
695 data = lseek(s->fd, 0, SEEK_END);
696 }
697 }
698 #else
699 *pnum = nb_sectors;
700 return 1;
701 #endif
702
703 if (data <= start) {
704 /* On a data extent, compute sectors to the end of the extent. */
705 *pnum = MIN(nb_sectors, (hole - start) / BDRV_SECTOR_SIZE);
706 return 1;
707 } else {
708 /* On a hole, compute sectors to the beginning of the next extent. */
709 *pnum = MIN(nb_sectors, (data - start) / BDRV_SECTOR_SIZE);
710 return 0;
711 }
712 }
713
714 #ifdef CONFIG_XFS
715 static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors)
716 {
717 struct xfs_flock64 fl;
718
719 memset(&fl, 0, sizeof(fl));
720 fl.l_whence = SEEK_SET;
721 fl.l_start = sector_num << 9;
722 fl.l_len = (int64_t)nb_sectors << 9;
723
724 if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) {
725 DEBUG_BLOCK_PRINT("cannot punch hole (%s)\n", strerror(errno));
726 return -errno;
727 }
728
729 return 0;
730 }
731 #endif
732
733 static coroutine_fn int raw_co_discard(BlockDriverState *bs,
734 int64_t sector_num, int nb_sectors)
735 {
736 #ifdef CONFIG_XFS
737 BDRVRawState *s = bs->opaque;
738
739 if (s->is_xfs) {
740 return xfs_discard(s, sector_num, nb_sectors);
741 }
742 #endif
743
744 return 0;
745 }
746
747 static QEMUOptionParameter raw_create_options[] = {
748 {
749 .name = BLOCK_OPT_SIZE,
750 .type = OPT_SIZE,
751 .help = "Virtual disk size"
752 },
753 { NULL }
754 };
755
756 static BlockDriver bdrv_file = {
757 .format_name = "file",
758 .protocol_name = "file",
759 .instance_size = sizeof(BDRVRawState),
760 .bdrv_probe = NULL, /* no probe for protocols */
761 .bdrv_file_open = raw_open,
762 .bdrv_close = raw_close,
763 .bdrv_create = raw_create,
764 .bdrv_co_discard = raw_co_discard,
765 .bdrv_co_is_allocated = raw_co_is_allocated,
766
767 .bdrv_aio_readv = raw_aio_readv,
768 .bdrv_aio_writev = raw_aio_writev,
769 .bdrv_aio_flush = raw_aio_flush,
770
771 .bdrv_truncate = raw_truncate,
772 .bdrv_getlength = raw_getlength,
773 .bdrv_get_allocated_file_size
774 = raw_get_allocated_file_size,
775
776 .create_options = raw_create_options,
777 };
778
779 /***********************************************/
780 /* host device */
781
782 #if defined(__APPLE__) && defined(__MACH__)
783 static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
784 static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
785
786 kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
787 {
788 kern_return_t kernResult;
789 mach_port_t masterPort;
790 CFMutableDictionaryRef classesToMatch;
791
792 kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
793 if ( KERN_SUCCESS != kernResult ) {
794 printf( "IOMasterPort returned %d\n", kernResult );
795 }
796
797 classesToMatch = IOServiceMatching( kIOCDMediaClass );
798 if ( classesToMatch == NULL ) {
799 printf( "IOServiceMatching returned a NULL dictionary.\n" );
800 } else {
801 CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
802 }
803 kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
804 if ( KERN_SUCCESS != kernResult )
805 {
806 printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
807 }
808
809 return kernResult;
810 }
811
812 kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
813 {
814 io_object_t nextMedia;
815 kern_return_t kernResult = KERN_FAILURE;
816 *bsdPath = '\0';
817 nextMedia = IOIteratorNext( mediaIterator );
818 if ( nextMedia )
819 {
820 CFTypeRef bsdPathAsCFString;
821 bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
822 if ( bsdPathAsCFString ) {
823 size_t devPathLength;
824 strcpy( bsdPath, _PATH_DEV );
825 strcat( bsdPath, "r" );
826 devPathLength = strlen( bsdPath );
827 if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
828 kernResult = KERN_SUCCESS;
829 }
830 CFRelease( bsdPathAsCFString );
831 }
832 IOObjectRelease( nextMedia );
833 }
834
835 return kernResult;
836 }
837
838 #endif
839
840 static int hdev_probe_device(const char *filename)
841 {
842 struct stat st;
843
844 /* allow a dedicated CD-ROM driver to match with a higher priority */
845 if (strstart(filename, "/dev/cdrom", NULL))
846 return 50;
847
848 if (stat(filename, &st) >= 0 &&
849 (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
850 return 100;
851 }
852
853 return 0;
854 }
855
856 static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
857 {
858 BDRVRawState *s = bs->opaque;
859
860 #if defined(__APPLE__) && defined(__MACH__)
861 if (strstart(filename, "/dev/cdrom", NULL)) {
862 kern_return_t kernResult;
863 io_iterator_t mediaIterator;
864 char bsdPath[ MAXPATHLEN ];
865 int fd;
866
867 kernResult = FindEjectableCDMedia( &mediaIterator );
868 kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
869
870 if ( bsdPath[ 0 ] != '\0' ) {
871 strcat(bsdPath,"s0");
872 /* some CDs don't have a partition 0 */
873 fd = qemu_open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
874 if (fd < 0) {
875 bsdPath[strlen(bsdPath)-1] = '1';
876 } else {
877 qemu_close(fd);
878 }
879 filename = bsdPath;
880 }
881
882 if ( mediaIterator )
883 IOObjectRelease( mediaIterator );
884 }
885 #endif
886
887 s->type = FTYPE_FILE;
888 #if defined(__linux__)
889 {
890 char resolved_path[ MAXPATHLEN ], *temp;
891
892 temp = realpath(filename, resolved_path);
893 if (temp && strstart(temp, "/dev/sg", NULL)) {
894 bs->sg = 1;
895 }
896 }
897 #endif
898
899 return raw_open_common(bs, filename, flags, 0);
900 }
901
902 #if defined(__linux__)
903 /* Note: we do not have a reliable method to detect if the floppy is
904 present. The current method is to try to open the floppy at every
905 I/O and to keep it opened during a few hundreds of ms. */
906 static int fd_open(BlockDriverState *bs)
907 {
908 BDRVRawState *s = bs->opaque;
909 int last_media_present;
910
911 if (s->type != FTYPE_FD)
912 return 0;
913 last_media_present = (s->fd >= 0);
914 if (s->fd >= 0 &&
915 (get_clock() - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
916 qemu_close(s->fd);
917 s->fd = -1;
918 #ifdef DEBUG_FLOPPY
919 printf("Floppy closed\n");
920 #endif
921 }
922 if (s->fd < 0) {
923 if (s->fd_got_error &&
924 (get_clock() - s->fd_error_time) < FD_OPEN_TIMEOUT) {
925 #ifdef DEBUG_FLOPPY
926 printf("No floppy (open delayed)\n");
927 #endif
928 return -EIO;
929 }
930 s->fd = qemu_open(bs->filename, s->open_flags & ~O_NONBLOCK);
931 if (s->fd < 0) {
932 s->fd_error_time = get_clock();
933 s->fd_got_error = 1;
934 if (last_media_present)
935 s->fd_media_changed = 1;
936 #ifdef DEBUG_FLOPPY
937 printf("No floppy\n");
938 #endif
939 return -EIO;
940 }
941 #ifdef DEBUG_FLOPPY
942 printf("Floppy opened\n");
943 #endif
944 }
945 if (!last_media_present)
946 s->fd_media_changed = 1;
947 s->fd_open_time = get_clock();
948 s->fd_got_error = 0;
949 return 0;
950 }
951
952 static int hdev_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
953 {
954 BDRVRawState *s = bs->opaque;
955
956 return ioctl(s->fd, req, buf);
957 }
958
959 static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
960 unsigned long int req, void *buf,
961 BlockDriverCompletionFunc *cb, void *opaque)
962 {
963 BDRVRawState *s = bs->opaque;
964
965 if (fd_open(bs) < 0)
966 return NULL;
967 return paio_ioctl(bs, s->fd, req, buf, cb, opaque);
968 }
969
970 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
971 static int fd_open(BlockDriverState *bs)
972 {
973 BDRVRawState *s = bs->opaque;
974
975 /* this is just to ensure s->fd is sane (its called by io ops) */
976 if (s->fd >= 0)
977 return 0;
978 return -EIO;
979 }
980 #else /* !linux && !FreeBSD */
981
982 static int fd_open(BlockDriverState *bs)
983 {
984 return 0;
985 }
986
987 #endif /* !linux && !FreeBSD */
988
989 static int hdev_create(const char *filename, QEMUOptionParameter *options)
990 {
991 int fd;
992 int ret = 0;
993 struct stat stat_buf;
994 int64_t total_size = 0;
995
996 /* Read out options */
997 while (options && options->name) {
998 if (!strcmp(options->name, "size")) {
999 total_size = options->value.n / BDRV_SECTOR_SIZE;
1000 }
1001 options++;
1002 }
1003
1004 fd = qemu_open(filename, O_WRONLY | O_BINARY);
1005 if (fd < 0)
1006 return -errno;
1007
1008 if (fstat(fd, &stat_buf) < 0)
1009 ret = -errno;
1010 else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode))
1011 ret = -ENODEV;
1012 else if (lseek(fd, 0, SEEK_END) < total_size * BDRV_SECTOR_SIZE)
1013 ret = -ENOSPC;
1014
1015 qemu_close(fd);
1016 return ret;
1017 }
1018
1019 static int hdev_has_zero_init(BlockDriverState *bs)
1020 {
1021 return 0;
1022 }
1023
1024 static BlockDriver bdrv_host_device = {
1025 .format_name = "host_device",
1026 .protocol_name = "host_device",
1027 .instance_size = sizeof(BDRVRawState),
1028 .bdrv_probe_device = hdev_probe_device,
1029 .bdrv_file_open = hdev_open,
1030 .bdrv_close = raw_close,
1031 .bdrv_create = hdev_create,
1032 .create_options = raw_create_options,
1033 .bdrv_has_zero_init = hdev_has_zero_init,
1034
1035 .bdrv_aio_readv = raw_aio_readv,
1036 .bdrv_aio_writev = raw_aio_writev,
1037 .bdrv_aio_flush = raw_aio_flush,
1038
1039 .bdrv_truncate = raw_truncate,
1040 .bdrv_getlength = raw_getlength,
1041 .bdrv_get_allocated_file_size
1042 = raw_get_allocated_file_size,
1043
1044 /* generic scsi device */
1045 #ifdef __linux__
1046 .bdrv_ioctl = hdev_ioctl,
1047 .bdrv_aio_ioctl = hdev_aio_ioctl,
1048 #endif
1049 };
1050
1051 #ifdef __linux__
1052 static int floppy_open(BlockDriverState *bs, const char *filename, int flags)
1053 {
1054 BDRVRawState *s = bs->opaque;
1055 int ret;
1056
1057 s->type = FTYPE_FD;
1058
1059 /* open will not fail even if no floppy is inserted, so add O_NONBLOCK */
1060 ret = raw_open_common(bs, filename, flags, O_NONBLOCK);
1061 if (ret)
1062 return ret;
1063
1064 /* close fd so that we can reopen it as needed */
1065 qemu_close(s->fd);
1066 s->fd = -1;
1067 s->fd_media_changed = 1;
1068
1069 return 0;
1070 }
1071
1072 static int floppy_probe_device(const char *filename)
1073 {
1074 int fd, ret;
1075 int prio = 0;
1076 struct floppy_struct fdparam;
1077 struct stat st;
1078
1079 if (strstart(filename, "/dev/fd", NULL) &&
1080 !strstart(filename, "/dev/fdset/", NULL)) {
1081 prio = 50;
1082 }
1083
1084 fd = qemu_open(filename, O_RDONLY | O_NONBLOCK);
1085 if (fd < 0) {
1086 goto out;
1087 }
1088 ret = fstat(fd, &st);
1089 if (ret == -1 || !S_ISBLK(st.st_mode)) {
1090 goto outc;
1091 }
1092
1093 /* Attempt to detect via a floppy specific ioctl */
1094 ret = ioctl(fd, FDGETPRM, &fdparam);
1095 if (ret >= 0)
1096 prio = 100;
1097
1098 outc:
1099 qemu_close(fd);
1100 out:
1101 return prio;
1102 }
1103
1104
1105 static int floppy_is_inserted(BlockDriverState *bs)
1106 {
1107 return fd_open(bs) >= 0;
1108 }
1109
1110 static int floppy_media_changed(BlockDriverState *bs)
1111 {
1112 BDRVRawState *s = bs->opaque;
1113 int ret;
1114
1115 /*
1116 * XXX: we do not have a true media changed indication.
1117 * It does not work if the floppy is changed without trying to read it.
1118 */
1119 fd_open(bs);
1120 ret = s->fd_media_changed;
1121 s->fd_media_changed = 0;
1122 #ifdef DEBUG_FLOPPY
1123 printf("Floppy changed=%d\n", ret);
1124 #endif
1125 return ret;
1126 }
1127
1128 static void floppy_eject(BlockDriverState *bs, bool eject_flag)
1129 {
1130 BDRVRawState *s = bs->opaque;
1131 int fd;
1132
1133 if (s->fd >= 0) {
1134 qemu_close(s->fd);
1135 s->fd = -1;
1136 }
1137 fd = qemu_open(bs->filename, s->open_flags | O_NONBLOCK);
1138 if (fd >= 0) {
1139 if (ioctl(fd, FDEJECT, 0) < 0)
1140 perror("FDEJECT");
1141 qemu_close(fd);
1142 }
1143 }
1144
1145 static BlockDriver bdrv_host_floppy = {
1146 .format_name = "host_floppy",
1147 .protocol_name = "host_floppy",
1148 .instance_size = sizeof(BDRVRawState),
1149 .bdrv_probe_device = floppy_probe_device,
1150 .bdrv_file_open = floppy_open,
1151 .bdrv_close = raw_close,
1152 .bdrv_create = hdev_create,
1153 .create_options = raw_create_options,
1154 .bdrv_has_zero_init = hdev_has_zero_init,
1155
1156 .bdrv_aio_readv = raw_aio_readv,
1157 .bdrv_aio_writev = raw_aio_writev,
1158 .bdrv_aio_flush = raw_aio_flush,
1159
1160 .bdrv_truncate = raw_truncate,
1161 .bdrv_getlength = raw_getlength,
1162 .bdrv_get_allocated_file_size
1163 = raw_get_allocated_file_size,
1164
1165 /* removable device support */
1166 .bdrv_is_inserted = floppy_is_inserted,
1167 .bdrv_media_changed = floppy_media_changed,
1168 .bdrv_eject = floppy_eject,
1169 };
1170
1171 static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1172 {
1173 BDRVRawState *s = bs->opaque;
1174
1175 s->type = FTYPE_CD;
1176
1177 /* open will not fail even if no CD is inserted, so add O_NONBLOCK */
1178 return raw_open_common(bs, filename, flags, O_NONBLOCK);
1179 }
1180
1181 static int cdrom_probe_device(const char *filename)
1182 {
1183 int fd, ret;
1184 int prio = 0;
1185 struct stat st;
1186
1187 fd = qemu_open(filename, O_RDONLY | O_NONBLOCK);
1188 if (fd < 0) {
1189 goto out;
1190 }
1191 ret = fstat(fd, &st);
1192 if (ret == -1 || !S_ISBLK(st.st_mode)) {
1193 goto outc;
1194 }
1195
1196 /* Attempt to detect via a CDROM specific ioctl */
1197 ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1198 if (ret >= 0)
1199 prio = 100;
1200
1201 outc:
1202 qemu_close(fd);
1203 out:
1204 return prio;
1205 }
1206
1207 static int cdrom_is_inserted(BlockDriverState *bs)
1208 {
1209 BDRVRawState *s = bs->opaque;
1210 int ret;
1211
1212 ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1213 if (ret == CDS_DISC_OK)
1214 return 1;
1215 return 0;
1216 }
1217
1218 static void cdrom_eject(BlockDriverState *bs, bool eject_flag)
1219 {
1220 BDRVRawState *s = bs->opaque;
1221
1222 if (eject_flag) {
1223 if (ioctl(s->fd, CDROMEJECT, NULL) < 0)
1224 perror("CDROMEJECT");
1225 } else {
1226 if (ioctl(s->fd, CDROMCLOSETRAY, NULL) < 0)
1227 perror("CDROMEJECT");
1228 }
1229 }
1230
1231 static void cdrom_lock_medium(BlockDriverState *bs, bool locked)
1232 {
1233 BDRVRawState *s = bs->opaque;
1234
1235 if (ioctl(s->fd, CDROM_LOCKDOOR, locked) < 0) {
1236 /*
1237 * Note: an error can happen if the distribution automatically
1238 * mounts the CD-ROM
1239 */
1240 /* perror("CDROM_LOCKDOOR"); */
1241 }
1242 }
1243
1244 static BlockDriver bdrv_host_cdrom = {
1245 .format_name = "host_cdrom",
1246 .protocol_name = "host_cdrom",
1247 .instance_size = sizeof(BDRVRawState),
1248 .bdrv_probe_device = cdrom_probe_device,
1249 .bdrv_file_open = cdrom_open,
1250 .bdrv_close = raw_close,
1251 .bdrv_create = hdev_create,
1252 .create_options = raw_create_options,
1253 .bdrv_has_zero_init = hdev_has_zero_init,
1254
1255 .bdrv_aio_readv = raw_aio_readv,
1256 .bdrv_aio_writev = raw_aio_writev,
1257 .bdrv_aio_flush = raw_aio_flush,
1258
1259 .bdrv_truncate = raw_truncate,
1260 .bdrv_getlength = raw_getlength,
1261 .bdrv_get_allocated_file_size
1262 = raw_get_allocated_file_size,
1263
1264 /* removable device support */
1265 .bdrv_is_inserted = cdrom_is_inserted,
1266 .bdrv_eject = cdrom_eject,
1267 .bdrv_lock_medium = cdrom_lock_medium,
1268
1269 /* generic scsi device */
1270 .bdrv_ioctl = hdev_ioctl,
1271 .bdrv_aio_ioctl = hdev_aio_ioctl,
1272 };
1273 #endif /* __linux__ */
1274
1275 #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
1276 static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1277 {
1278 BDRVRawState *s = bs->opaque;
1279 int ret;
1280
1281 s->type = FTYPE_CD;
1282
1283 ret = raw_open_common(bs, filename, flags, 0);
1284 if (ret)
1285 return ret;
1286
1287 /* make sure the door isn't locked at this time */
1288 ioctl(s->fd, CDIOCALLOW);
1289 return 0;
1290 }
1291
1292 static int cdrom_probe_device(const char *filename)
1293 {
1294 if (strstart(filename, "/dev/cd", NULL) ||
1295 strstart(filename, "/dev/acd", NULL))
1296 return 100;
1297 return 0;
1298 }
1299
1300 static int cdrom_reopen(BlockDriverState *bs)
1301 {
1302 BDRVRawState *s = bs->opaque;
1303 int fd;
1304
1305 /*
1306 * Force reread of possibly changed/newly loaded disc,
1307 * FreeBSD seems to not notice sometimes...
1308 */
1309 if (s->fd >= 0)
1310 qemu_close(s->fd);
1311 fd = qemu_open(bs->filename, s->open_flags, 0644);
1312 if (fd < 0) {
1313 s->fd = -1;
1314 return -EIO;
1315 }
1316 s->fd = fd;
1317
1318 /* make sure the door isn't locked at this time */
1319 ioctl(s->fd, CDIOCALLOW);
1320 return 0;
1321 }
1322
1323 static int cdrom_is_inserted(BlockDriverState *bs)
1324 {
1325 return raw_getlength(bs) > 0;
1326 }
1327
1328 static void cdrom_eject(BlockDriverState *bs, bool eject_flag)
1329 {
1330 BDRVRawState *s = bs->opaque;
1331
1332 if (s->fd < 0)
1333 return;
1334
1335 (void) ioctl(s->fd, CDIOCALLOW);
1336
1337 if (eject_flag) {
1338 if (ioctl(s->fd, CDIOCEJECT) < 0)
1339 perror("CDIOCEJECT");
1340 } else {
1341 if (ioctl(s->fd, CDIOCCLOSE) < 0)
1342 perror("CDIOCCLOSE");
1343 }
1344
1345 cdrom_reopen(bs);
1346 }
1347
1348 static void cdrom_lock_medium(BlockDriverState *bs, bool locked)
1349 {
1350 BDRVRawState *s = bs->opaque;
1351
1352 if (s->fd < 0)
1353 return;
1354 if (ioctl(s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) {
1355 /*
1356 * Note: an error can happen if the distribution automatically
1357 * mounts the CD-ROM
1358 */
1359 /* perror("CDROM_LOCKDOOR"); */
1360 }
1361 }
1362
1363 static BlockDriver bdrv_host_cdrom = {
1364 .format_name = "host_cdrom",
1365 .protocol_name = "host_cdrom",
1366 .instance_size = sizeof(BDRVRawState),
1367 .bdrv_probe_device = cdrom_probe_device,
1368 .bdrv_file_open = cdrom_open,
1369 .bdrv_close = raw_close,
1370 .bdrv_create = hdev_create,
1371 .create_options = raw_create_options,
1372 .bdrv_has_zero_init = hdev_has_zero_init,
1373
1374 .bdrv_aio_readv = raw_aio_readv,
1375 .bdrv_aio_writev = raw_aio_writev,
1376 .bdrv_aio_flush = raw_aio_flush,
1377
1378 .bdrv_truncate = raw_truncate,
1379 .bdrv_getlength = raw_getlength,
1380 .bdrv_get_allocated_file_size
1381 = raw_get_allocated_file_size,
1382
1383 /* removable device support */
1384 .bdrv_is_inserted = cdrom_is_inserted,
1385 .bdrv_eject = cdrom_eject,
1386 .bdrv_lock_medium = cdrom_lock_medium,
1387 };
1388 #endif /* __FreeBSD__ */
1389
1390 static void bdrv_file_init(void)
1391 {
1392 /*
1393 * Register all the drivers. Note that order is important, the driver
1394 * registered last will get probed first.
1395 */
1396 bdrv_register(&bdrv_file);
1397 bdrv_register(&bdrv_host_device);
1398 #ifdef __linux__
1399 bdrv_register(&bdrv_host_floppy);
1400 bdrv_register(&bdrv_host_cdrom);
1401 #endif
1402 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1403 bdrv_register(&bdrv_host_cdrom);
1404 #endif
1405 }
1406
1407 block_init(bdrv_file_init);