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