#include <linux/cdrom.h>
#include <linux/fd.h>
#endif
-#ifdef __FreeBSD__
+#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <signal.h>
#include <sys/disk.h>
#include <sys/cdio.h>
int type;
unsigned int lseek_err_cnt;
int open_flags;
- void *aio_ctx;
#if defined(__linux__)
/* linux floppy specific */
int64_t fd_open_time;
#endif
#ifdef CONFIG_LINUX_AIO
int use_aio;
+ void *aio_ctx;
#endif
uint8_t* aligned_buf;
} BDRVRawState;
static int fd_open(BlockDriverState *bs);
static int64_t raw_getlength(BlockDriverState *bs);
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
static int cdrom_reopen(BlockDriverState *bs);
#endif
s->open_flags = open_flags | O_BINARY;
s->open_flags &= ~O_ACCMODE;
- if ((bdrv_flags & BDRV_O_ACCESS) == BDRV_O_RDWR) {
+ if (bdrv_flags & BDRV_O_RDWR) {
s->open_flags |= O_RDWR;
} else {
s->open_flags |= O_RDONLY;
- bs->read_only = 1;
}
/* Use O_DSYNC for write-through caching, no flags for write-back caching,
s->open_flags |= O_DSYNC;
s->fd = -1;
- fd = open(filename, s->open_flags, 0644);
+ fd = qemu_open(filename, s->open_flags, 0644);
if (fd < 0) {
ret = -errno;
if (ret == -EROFS)
#ifdef CONFIG_LINUX_AIO
if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) ==
(BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) {
+
+ /* We're falling back to POSIX AIO in some cases */
+ paio_init();
+
s->aio_ctx = laio_init();
if (!s->aio_ctx) {
goto out_free_buf;
} else
#endif
{
- s->aio_ctx = paio_init();
- if (!s->aio_ctx) {
+ if (paio_init() < 0) {
goto out_free_buf;
}
#ifdef CONFIG_LINUX_AIO
static int raw_open(BlockDriverState *bs, const char *filename, int flags)
{
BDRVRawState *s = bs->opaque;
- int open_flags = 0;
s->type = FTYPE_FILE;
- if (flags & BDRV_O_CREAT)
- open_flags = O_CREAT | O_TRUNC;
-
- return raw_open_common(bs, filename, flags, open_flags);
+ return raw_open_common(bs, filename, flags, 0);
}
/* XXX: use host sector size if necessary with:
size = ALIGNED_BUFFER_SIZE;
ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);
- if (ret < 0)
+ if (ret < 0) {
return ret;
+ } else if (ret == 0) {
+ fprintf(stderr, "raw_pread: read beyond end of file\n");
+ abort();
+ }
size = ret;
if (size > count)
}
}
- return paio_submit(bs, s->aio_ctx, s->fd, sector_num, qiov, nb_sectors,
+ return paio_submit(bs, s->fd, sector_num, qiov, nb_sectors,
cb, opaque, type);
}
if (fd_open(bs) < 0)
return NULL;
- return paio_submit(bs, s->aio_ctx, s->fd, 0, NULL, 0,
- cb, opaque, QEMU_AIO_FLUSH);
+ return paio_submit(bs, s->fd, 0, NULL, 0, cb, opaque, QEMU_AIO_FLUSH);
}
static void raw_close(BlockDriverState *bs)
close(s->fd);
s->fd = -1;
if (s->aligned_buf != NULL)
- qemu_free(s->aligned_buf);
+ qemu_vfree(s->aligned_buf);
}
}
} else
return st.st_size;
}
-#else /* !__OpenBSD__ */
-static int64_t raw_getlength(BlockDriverState *bs)
+#elif defined(__sun__)
+static int64_t raw_getlength(BlockDriverState *bs)
+{
+ BDRVRawState *s = bs->opaque;
+ struct dk_minfo minfo;
+ int ret;
+
+ ret = fd_open(bs);
+ if (ret < 0) {
+ return ret;
+ }
+
+ /*
+ * Use the DKIOCGMEDIAINFO ioctl to read the size.
+ */
+ ret = ioctl(s->fd, DKIOCGMEDIAINFO, &minfo);
+ if (ret != -1) {
+ return minfo.dki_lbsize * minfo.dki_capacity;
+ }
+
+ /*
+ * There are reports that lseek on some devices fails, but
+ * irc discussion said that contingency on contingency was overkill.
+ */
+ return lseek(s->fd, 0, SEEK_END);
+}
+#elif defined(CONFIG_BSD)
+static int64_t raw_getlength(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
int fd = s->fd;
int64_t size;
-#ifdef CONFIG_BSD
struct stat sb;
-#ifdef __FreeBSD__
+#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
int reopened = 0;
-#endif
-#endif
-#ifdef __sun__
- struct dk_minfo minfo;
- int rv;
#endif
int ret;
if (ret < 0)
return ret;
-#ifdef CONFIG_BSD
-#ifdef __FreeBSD__
+#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
again:
#endif
if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
#else
size = lseek(fd, 0LL, SEEK_END);
#endif
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
switch(s->type) {
case FTYPE_CD:
/* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */
}
}
#endif
- } else
-#endif
-#ifdef __sun__
- /*
- * use the DKIOCGMEDIAINFO ioctl to read the size.
- */
- rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
- if ( rv != -1 ) {
- size = minfo.dki_lbsize * minfo.dki_capacity;
- } else /* there are reports that lseek on some devices
- fails, but irc discussion said that contingency
- on contingency was overkill */
-#endif
- {
+ } else {
size = lseek(fd, 0, SEEK_END);
}
return size;
}
+#else
+static int64_t raw_getlength(BlockDriverState *bs)
+{
+ BDRVRawState *s = bs->opaque;
+ int ret;
+
+ ret = fd_open(bs);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return lseek(s->fd, 0, SEEK_END);
+}
#endif
static int raw_create(const char *filename, QEMUOptionParameter *options)
{ NULL }
};
-static BlockDriver bdrv_raw = {
- .format_name = "raw",
+static BlockDriver bdrv_file = {
+ .format_name = "file",
+ .protocol_name = "file",
.instance_size = sizeof(BDRVRawState),
.bdrv_probe = NULL, /* no probe for protocols */
.bdrv_open = raw_open,
return paio_ioctl(bs, s->fd, req, buf, cb, opaque);
}
-#elif defined(__FreeBSD__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
static int fd_open(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
fd = open(filename, O_WRONLY | O_BINARY);
if (fd < 0)
- return -EIO;
+ return -errno;
if (fstat(fd, &stat_buf) < 0)
- ret = -EIO;
+ ret = -errno;
else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode))
- ret = -EIO;
+ ret = -ENODEV;
else if (lseek(fd, 0, SEEK_END) < total_size * 512)
ret = -ENOSPC;
static BlockDriver bdrv_host_device = {
.format_name = "host_device",
+ .protocol_name = "host_device",
.instance_size = sizeof(BDRVRawState),
.bdrv_probe_device = hdev_probe_device,
.bdrv_open = hdev_open,
.bdrv_close = raw_close,
.bdrv_create = hdev_create,
.create_options = raw_create_options,
+ .no_zero_init = 1,
.bdrv_flush = raw_flush,
.bdrv_aio_readv = raw_aio_readv,
static int floppy_probe_device(const char *filename)
{
+ int fd, ret;
+ int prio = 0;
+ struct floppy_struct fdparam;
+
if (strstart(filename, "/dev/fd", NULL))
- return 100;
- return 0;
+ prio = 50;
+
+ fd = open(filename, O_RDONLY | O_NONBLOCK);
+ if (fd < 0) {
+ goto out;
+ }
+
+ /* Attempt to detect via a floppy specific ioctl */
+ ret = ioctl(fd, FDGETPRM, &fdparam);
+ if (ret >= 0)
+ prio = 100;
+
+ close(fd);
+out:
+ return prio;
}
static BlockDriver bdrv_host_floppy = {
.format_name = "host_floppy",
+ .protocol_name = "host_floppy",
.instance_size = sizeof(BDRVRawState),
.bdrv_probe_device = floppy_probe_device,
.bdrv_open = floppy_open,
.bdrv_close = raw_close,
.bdrv_create = hdev_create,
.create_options = raw_create_options,
+ .no_zero_init = 1,
.bdrv_flush = raw_flush,
.bdrv_aio_readv = raw_aio_readv,
static int cdrom_probe_device(const char *filename)
{
+ int fd, ret;
+ int prio = 0;
+
if (strstart(filename, "/dev/cd", NULL))
- return 100;
- return 0;
+ prio = 50;
+
+ fd = open(filename, O_RDONLY | O_NONBLOCK);
+ if (fd < 0) {
+ goto out;
+ }
+
+ /* Attempt to detect via a CDROM specific ioctl */
+ ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
+ if (ret >= 0)
+ prio = 100;
+
+ close(fd);
+out:
+ return prio;
}
static int cdrom_is_inserted(BlockDriverState *bs)
static BlockDriver bdrv_host_cdrom = {
.format_name = "host_cdrom",
+ .protocol_name = "host_cdrom",
.instance_size = sizeof(BDRVRawState),
.bdrv_probe_device = cdrom_probe_device,
.bdrv_open = cdrom_open,
.bdrv_close = raw_close,
.bdrv_create = hdev_create,
.create_options = raw_create_options,
+ .no_zero_init = 1,
.bdrv_flush = raw_flush,
.bdrv_aio_readv = raw_aio_readv,
};
#endif /* __linux__ */
-#ifdef __FreeBSD__
+#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
{
BDRVRawState *s = bs->opaque;
static BlockDriver bdrv_host_cdrom = {
.format_name = "host_cdrom",
+ .protocol_name = "host_cdrom",
.instance_size = sizeof(BDRVRawState),
.bdrv_probe_device = cdrom_probe_device,
.bdrv_open = cdrom_open,
.bdrv_close = raw_close,
.bdrv_create = hdev_create,
.create_options = raw_create_options,
+ .no_zero_init = 1,
.bdrv_flush = raw_flush,
.bdrv_aio_readv = raw_aio_readv,
};
#endif /* __FreeBSD__ */
-static void bdrv_raw_init(void)
+static void bdrv_file_init(void)
{
/*
* Register all the drivers. Note that order is important, the driver
* registered last will get probed first.
*/
- bdrv_register(&bdrv_raw);
+ bdrv_register(&bdrv_file);
bdrv_register(&bdrv_host_device);
#ifdef __linux__
bdrv_register(&bdrv_host_floppy);
bdrv_register(&bdrv_host_cdrom);
#endif
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
bdrv_register(&bdrv_host_cdrom);
#endif
}
-block_init(bdrv_raw_init);
+block_init(bdrv_file_init);