* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "vl.h"
+#include "qemu-common.h"
+#ifndef QEMU_IMG
+#include "console.h"
+#endif
#include "block_int.h"
#ifdef _BSD
static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors);
-static BlockDriverState *bdrv_first;
+BlockDriverState *bdrv_first;
static BlockDriver *first_drv;
int path_is_absolute(const char *path)
}
-void bdrv_register(BlockDriver *bdrv)
+static void bdrv_register(BlockDriver *bdrv)
{
if (!bdrv->bdrv_aio_read) {
/* add AIO emulation layer */
void get_tmp_filename(char *filename, int size)
{
int fd;
+ char *tmpdir;
/* XXX: race condition possible */
- pstrcpy(filename, size, "/tmp/vl.XXXXXX");
+ tmpdir = getenv("TMPDIR");
+ if (!tmpdir)
+ tmpdir = "/tmp";
+ snprintf(filename, size, "%s/vl.XXXXXX", tmpdir);
fd = mkstemp(filename);
close(fd);
}
/* Note: for compatibility, we open disk image files as RDWR, and
RDONLY as fallback */
if (!(flags & BDRV_O_FILE))
- open_flags = BDRV_O_RDWR;
+ open_flags = BDRV_O_RDWR | (flags & BDRV_O_DIRECT);
else
open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
ret = drv->bdrv_open(bs, filename, open_flags);
void bdrv_delete(BlockDriverState *bs)
{
- /* XXX: remove the driver list */
+ BlockDriverState **pbs;
+
+ pbs = &bdrv_first;
+ while (*pbs != bs && *pbs != NULL)
+ pbs = &(*pbs)->next;
+ if (*pbs == bs)
+ *pbs = bs->next;
+
bdrv_close(bs);
qemu_free(bs);
}
return ret;
else if (ret != len)
return -EINVAL;
- else
+ else {
+ bs->rd_bytes += (unsigned) len;
+ bs->rd_ops ++;
return 0;
+ }
} else {
return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
}
return ret;
else if (ret != len)
return -EIO;
- else
+ else {
+ bs->wr_bytes += (unsigned) len;
+ bs->wr_ops ++;
return 0;
+ }
} else {
return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
}
}
/* return 0 as number of sectors if no device present or error */
-void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr)
+void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
{
int64_t length;
length = bdrv_getlength(bs);
return bs->read_only;
}
+int bdrv_is_sg(BlockDriverState *bs)
+{
+ return bs->sg;
+}
+
/* XXX: no longer used */
void bdrv_set_change_cb(BlockDriverState *bs,
void (*change_cb)(void *opaque), void *opaque)
bdrv_flush(bs->backing_hd);
}
+#ifndef QEMU_IMG
void bdrv_info(void)
{
BlockDriverState *bs;
}
}
+/* The "info blockstats" command. */
+void bdrv_info_stats (void)
+{
+ BlockDriverState *bs;
+
+ for (bs = bdrv_first; bs != NULL; bs = bs->next) {
+ term_printf ("%s:"
+ " rd_bytes=%" PRIu64
+ " wr_bytes=%" PRIu64
+ " rd_operations=%" PRIu64
+ " wr_operations=%" PRIu64
+ "\n",
+ bs->device_name,
+ bs->rd_bytes, bs->wr_bytes,
+ bs->rd_ops, bs->wr_ops);
+ }
+}
+#endif
+
void bdrv_get_backing_filename(BlockDriverState *bs,
char *filename, int filename_size)
{
BlockDriverCompletionFunc *cb, void *opaque)
{
BlockDriver *drv = bs->drv;
+ BlockDriverAIOCB *ret;
if (!drv)
return NULL;
buf += 512;
}
- return drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
+ ret = drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
+
+ if (ret) {
+ /* Update stats even though technically transfer has not happened. */
+ bs->rd_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
+ bs->rd_ops ++;
+ }
+
+ return ret;
}
BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
BlockDriverCompletionFunc *cb, void *opaque)
{
BlockDriver *drv = bs->drv;
+ BlockDriverAIOCB *ret;
if (!drv)
return NULL;
memcpy(bs->boot_sector_data, buf, 512);
}
- return drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
+ ret = drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
+
+ if (ret) {
+ /* Update stats even though technically transfer has not happened. */
+ bs->wr_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
+ bs->wr_ops ++;
+ }
+
+ return ret;
}
void bdrv_aio_cancel(BlockDriverAIOCB *acb)
/**************************************************************/
/* async block device emulation */
-#ifdef QEMU_TOOL
+#ifdef QEMU_IMG
static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
int64_t sector_num, uint8_t *buf, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque)
qemu_bh_cancel(acb->bh);
qemu_aio_release(acb);
}
-#endif /* !QEMU_TOOL */
+#endif /* !QEMU_IMG */
/**************************************************************/
/* sync block device emulation */
drv->bdrv_set_locked(bs, locked);
}
}
+
+/* needed for generic scsi interface */
+
+int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
+{
+ BlockDriver *drv = bs->drv;
+
+ if (drv && drv->bdrv_ioctl)
+ return drv->bdrv_ioctl(bs, req, buf);
+ return -ENOTSUP;
+}