* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/error-report.h"
#include "qemu/timer.h"
#include <sys/dkio.h>
#endif
#ifdef __linux__
-#include <sys/types.h>
-#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <linux/cdrom.h>
#define FTYPE_FILE 0
#define FTYPE_CD 1
-#define FTYPE_FD 2
-
-/* if the FD is not accessed during that time (in ns), we try to
- reopen it to see if the disk has been changed */
-#define FD_OPEN_TIMEOUT (1000000000)
#define MAX_BLOCKSIZE 4096
int open_flags;
size_t buf_align;
-#if defined(__linux__)
- /* linux floppy specific */
- int64_t fd_open_time;
- int64_t fd_error_time;
- int fd_got_error;
- int fd_media_changed;
-#endif
#ifdef CONFIG_LINUX_AIO
int use_aio;
void *aio_ctx;
goto fail;
}
if (!s->use_aio && (bdrv_flags & BDRV_O_NATIVE_AIO)) {
- error_printf("WARNING: aio=native was specified for '%s', but "
- "it requires cache.direct=on, which was not "
- "specified. Falling back to aio=threads.\n"
- " This will become an error condition in "
- "future QEMU versions.\n",
- bs->filename);
+ error_setg(errp, "aio=native was specified, but it requires "
+ "cache.direct=on, which was not specified.");
+ ret = -EINVAL;
+ goto fail;
}
-#endif
+#else
+ if (bdrv_flags & BDRV_O_NATIVE_AIO) {
+ error_setg(errp, "aio=native was specified, but is not supported "
+ "in this build.");
+ ret = -EINVAL;
+ goto fail;
+ }
+#endif /* !defined(CONFIG_LINUX_AIO) */
s->has_discard = true;
s->has_write_zeroes = true;
}
#endif
- if (s->type == FTYPE_FD || s->type == FTYPE_CD) {
+ if (s->type == FTYPE_CD) {
raw_s->open_flags |= O_NONBLOCK;
}
{
BDRVRawState *s = bs->opaque;
struct hd_geometry ioctl_geo = {0};
- uint32_t blksize;
/* If DASD, get its geometry */
if (check_for_dasd(s->fd) < 0) {
}
geo->heads = ioctl_geo.heads;
geo->sectors = ioctl_geo.sectors;
- if (!probe_physical_blocksize(s->fd, &blksize)) {
- /* overwrite cyls: HDIO_GETGEO result is incorrect for big drives */
- geo->cylinders = bdrv_nb_sectors(bs) / (blksize / BDRV_SECTOR_SIZE)
- / (geo->heads * geo->sectors);
- return 0;
- }
geo->cylinders = ioctl_geo.cylinders;
return 0;
break;
}
- g_slice_free(RawPosixAIOData, aiocb);
+ g_free(aiocb);
return ret;
}
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
int type)
{
- RawPosixAIOData *acb = g_slice_new(RawPosixAIOData);
+ RawPosixAIOData *acb = g_new(RawPosixAIOData, 1);
ThreadPool *pool;
acb->bs = bs;
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockCompletionFunc *cb, void *opaque, int type)
{
- RawPosixAIOData *acb = g_slice_new(RawPosixAIOData);
+ RawPosixAIOData *acb = g_new(RawPosixAIOData, 1);
ThreadPool *pool;
acb->bs = bs;
nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false);
buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
- PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
+ PREALLOC_MODE__MAX, PREALLOC_MODE_OFF,
&local_err);
g_free(buf);
if (local_err) {
*/
static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
int64_t sector_num,
- int nb_sectors, int *pnum)
+ int nb_sectors, int *pnum,
+ BlockDriverState **file)
{
off_t start, data = 0, hole = 0;
int64_t total_size;
*pnum = MIN(nb_sectors, (data - start) / BDRV_SECTOR_SIZE);
ret = BDRV_BLOCK_ZERO;
}
+ *file = bs;
return ret | BDRV_BLOCK_OFFSET_VALID | start;
}
#if defined(__APPLE__) && defined(__MACH__)
static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
-static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
-
+static kern_return_t GetBSDPath(io_iterator_t mediaIterator, char *bsdPath,
+ CFIndex maxPathSize, int flags);
kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
{
kern_return_t kernResult;
return kernResult;
}
-kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
+kern_return_t GetBSDPath(io_iterator_t mediaIterator, char *bsdPath,
+ CFIndex maxPathSize, int flags)
{
io_object_t nextMedia;
kern_return_t kernResult = KERN_FAILURE;
if ( bsdPathAsCFString ) {
size_t devPathLength;
strcpy( bsdPath, _PATH_DEV );
- strcat( bsdPath, "r" );
+ if (flags & BDRV_O_NOCACHE) {
+ strcat(bsdPath, "r");
+ }
devPathLength = strlen( bsdPath );
if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
kernResult = KERN_SUCCESS;
int fd;
kernResult = FindEjectableCDMedia( &mediaIterator );
- kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
-
+ kernResult = GetBSDPath(mediaIterator, bsdPath, sizeof(bsdPath),
+ flags);
if ( bsdPath[ 0 ] != '\0' ) {
strcat(bsdPath,"s0");
/* some CDs don't have a partition 0 */
}
#if defined(__linux__)
-/* Note: we do not have a reliable method to detect if the floppy is
- present. The current method is to try to open the floppy at every
- I/O and to keep it opened during a few hundreds of ms. */
-static int fd_open(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- int last_media_present;
-
- if (s->type != FTYPE_FD)
- return 0;
- last_media_present = (s->fd >= 0);
- if (s->fd >= 0 &&
- (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
- qemu_close(s->fd);
- s->fd = -1;
- DPRINTF("Floppy closed\n");
- }
- if (s->fd < 0) {
- if (s->fd_got_error &&
- (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
- DPRINTF("No floppy (open delayed)\n");
- return -EIO;
- }
- s->fd = qemu_open(bs->filename, s->open_flags & ~O_NONBLOCK);
- if (s->fd < 0) {
- s->fd_error_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
- s->fd_got_error = 1;
- if (last_media_present)
- s->fd_media_changed = 1;
- DPRINTF("No floppy\n");
- return -EIO;
- }
- DPRINTF("Floppy opened\n");
- }
- if (!last_media_present)
- s->fd_media_changed = 1;
- s->fd_open_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
- s->fd_got_error = 0;
- return 0;
-}
-
-static int hdev_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
-{
- BDRVRawState *s = bs->opaque;
-
- return ioctl(s->fd, req, buf);
-}
static BlockAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
unsigned long int req, void *buf,
if (fd_open(bs) < 0)
return NULL;
- acb = g_slice_new(RawPosixAIOData);
+ acb = g_new(RawPosixAIOData, 1);
acb->bs = bs;
acb->aio_type = QEMU_AIO_IOCTL;
acb->aio_fildes = s->fd;
pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque);
}
+#endif /* linux */
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
static int fd_open(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
return 0;
return -EIO;
}
-#else /* !linux && !FreeBSD */
-
-static int fd_open(BlockDriverState *bs)
-{
- return 0;
-}
-
-#endif /* !linux && !FreeBSD */
static coroutine_fn BlockAIOCB *hdev_aio_discard(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
int64_t total_size = 0;
bool has_prefix;
- /* This function is used by all three protocol block drivers and therefore
- * any of these three prefixes may be given.
+ /* This function is used by both protocol block drivers and therefore either
+ * of these prefixes may be given.
* The return value has to be stored somewhere, otherwise this is an error
* due to -Werror=unused-value. */
has_prefix =
strstart(filename, "host_device:", &filename) ||
- strstart(filename, "host_cdrom:" , &filename) ||
- strstart(filename, "host_floppy:", &filename);
+ strstart(filename, "host_cdrom:" , &filename);
(void)has_prefix;
/* generic scsi device */
#ifdef __linux__
- .bdrv_ioctl = hdev_ioctl,
.bdrv_aio_ioctl = hdev_aio_ioctl,
#endif
};
-#ifdef __linux__
-static void floppy_parse_filename(const char *filename, QDict *options,
- Error **errp)
-{
- /* The prefix is optional, just as for "file". */
- strstart(filename, "host_floppy:", &filename);
-
- qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
-}
-
-static int floppy_open(BlockDriverState *bs, QDict *options, int flags,
- Error **errp)
-{
- BDRVRawState *s = bs->opaque;
- Error *local_err = NULL;
- int ret;
-
- s->type = FTYPE_FD;
-
- /* open will not fail even if no floppy is inserted, so add O_NONBLOCK */
- ret = raw_open_common(bs, options, flags, O_NONBLOCK, &local_err);
- if (ret) {
- if (local_err) {
- error_propagate(errp, local_err);
- }
- return ret;
- }
-
- /* close fd so that we can reopen it as needed */
- qemu_close(s->fd);
- s->fd = -1;
- s->fd_media_changed = 1;
-
- error_report("Host floppy pass-through is deprecated");
- error_printf("Support for it will be removed in a future release.\n");
- return 0;
-}
-
-static int floppy_probe_device(const char *filename)
-{
- int fd, ret;
- int prio = 0;
- struct floppy_struct fdparam;
- struct stat st;
-
- if (strstart(filename, "/dev/fd", NULL) &&
- !strstart(filename, "/dev/fdset/", NULL) &&
- !strstart(filename, "/dev/fd/", NULL)) {
- prio = 50;
- }
-
- fd = qemu_open(filename, O_RDONLY | O_NONBLOCK);
- if (fd < 0) {
- goto out;
- }
- ret = fstat(fd, &st);
- if (ret == -1 || !S_ISBLK(st.st_mode)) {
- goto outc;
- }
-
- /* Attempt to detect via a floppy specific ioctl */
- ret = ioctl(fd, FDGETPRM, &fdparam);
- if (ret >= 0)
- prio = 100;
-
-outc:
- qemu_close(fd);
-out:
- return prio;
-}
-
-
-static int floppy_is_inserted(BlockDriverState *bs)
-{
- return fd_open(bs) >= 0;
-}
-
-static int floppy_media_changed(BlockDriverState *bs)
-{
- BDRVRawState *s = bs->opaque;
- int ret;
-
- /*
- * XXX: we do not have a true media changed indication.
- * It does not work if the floppy is changed without trying to read it.
- */
- fd_open(bs);
- ret = s->fd_media_changed;
- s->fd_media_changed = 0;
- DPRINTF("Floppy changed=%d\n", ret);
- return ret;
-}
-
-static void floppy_eject(BlockDriverState *bs, bool eject_flag)
-{
- BDRVRawState *s = bs->opaque;
- int fd;
-
- if (s->fd >= 0) {
- qemu_close(s->fd);
- s->fd = -1;
- }
- fd = qemu_open(bs->filename, s->open_flags | O_NONBLOCK);
- if (fd >= 0) {
- if (ioctl(fd, FDEJECT, 0) < 0)
- perror("FDEJECT");
- qemu_close(fd);
- }
-}
-
-static BlockDriver bdrv_host_floppy = {
- .format_name = "host_floppy",
- .protocol_name = "host_floppy",
- .instance_size = sizeof(BDRVRawState),
- .bdrv_needs_filename = true,
- .bdrv_probe_device = floppy_probe_device,
- .bdrv_parse_filename = floppy_parse_filename,
- .bdrv_file_open = floppy_open,
- .bdrv_close = raw_close,
- .bdrv_reopen_prepare = raw_reopen_prepare,
- .bdrv_reopen_commit = raw_reopen_commit,
- .bdrv_reopen_abort = raw_reopen_abort,
- .bdrv_create = hdev_create,
- .create_opts = &raw_create_opts,
-
- .bdrv_aio_readv = raw_aio_readv,
- .bdrv_aio_writev = raw_aio_writev,
- .bdrv_aio_flush = raw_aio_flush,
- .bdrv_refresh_limits = raw_refresh_limits,
- .bdrv_io_plug = raw_aio_plug,
- .bdrv_io_unplug = raw_aio_unplug,
- .bdrv_flush_io_queue = raw_aio_flush_io_queue,
-
- .bdrv_truncate = raw_truncate,
- .bdrv_getlength = raw_getlength,
- .has_variable_length = true,
- .bdrv_get_allocated_file_size
- = raw_get_allocated_file_size,
-
- .bdrv_detach_aio_context = raw_detach_aio_context,
- .bdrv_attach_aio_context = raw_attach_aio_context,
-
- /* removable device support */
- .bdrv_is_inserted = floppy_is_inserted,
- .bdrv_media_changed = floppy_media_changed,
- .bdrv_eject = floppy_eject,
-};
-#endif
-
#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
static void cdrom_parse_filename(const char *filename, QDict *options,
Error **errp)
return prio;
}
-static int cdrom_is_inserted(BlockDriverState *bs)
+static bool cdrom_is_inserted(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
int ret;
ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
- if (ret == CDS_DISC_OK)
- return 1;
- return 0;
+ return ret == CDS_DISC_OK;
}
static void cdrom_eject(BlockDriverState *bs, bool eject_flag)
.bdrv_lock_medium = cdrom_lock_medium,
/* generic scsi device */
- .bdrv_ioctl = hdev_ioctl,
.bdrv_aio_ioctl = hdev_aio_ioctl,
};
#endif /* __linux__ */
return 0;
}
-static int cdrom_is_inserted(BlockDriverState *bs)
+static bool cdrom_is_inserted(BlockDriverState *bs)
{
return raw_getlength(bs) > 0;
}
bdrv_register(&bdrv_file);
bdrv_register(&bdrv_host_device);
#ifdef __linux__
- bdrv_register(&bdrv_host_floppy);
bdrv_register(&bdrv_host_cdrom);
#endif
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)