]> git.proxmox.com Git - mirror_qemu.git/blobdiff - block.c
Update documentation for qemu-img convert options, by Marc Bevand.
[mirror_qemu.git] / block.c
diff --git a/block.c b/block.c
index 3c7039947c9e1d5efd32579698c294f4261dcab4..bd647a6f479c59306e6cc6596a1ff9102a5503d1 100644 (file)
--- a/block.c
+++ b/block.c
  * 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
@@ -53,7 +56,7 @@ static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
 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)
@@ -121,7 +124,7 @@ void path_combine(char *dest, int dest_size,
 }
 
 
-void bdrv_register(BlockDriver *bdrv)
+static void bdrv_register(BlockDriver *bdrv)
 {
     if (!bdrv->bdrv_aio_read) {
         /* add AIO emulation layer */
@@ -188,8 +191,12 @@ void get_tmp_filename(char *filename, int size)
 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);
 }
@@ -377,7 +384,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
     /* 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);
@@ -445,7 +452,14 @@ void bdrv_close(BlockDriverState *bs)
 
 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);
 }
@@ -518,8 +532,11 @@ int bdrv_read(BlockDriverState *bs, int64_t sector_num,
             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);
     }
@@ -550,8 +567,11 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num,
             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);
     }
@@ -708,7 +728,7 @@ int64_t bdrv_getlength(BlockDriverState *bs)
 }
 
 /* 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);
@@ -777,6 +797,11 @@ int bdrv_is_read_only(BlockDriverState *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)
@@ -859,6 +884,7 @@ void bdrv_flush(BlockDriverState *bs)
         bdrv_flush(bs->backing_hd);
 }
 
+#ifndef QEMU_IMG
 void bdrv_info(void)
 {
     BlockDriverState *bs;
@@ -899,6 +925,25 @@ void bdrv_info(void)
     }
 }
 
+/* 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)
 {
@@ -1059,6 +1104,7 @@ BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
                                 BlockDriverCompletionFunc *cb, void *opaque)
 {
     BlockDriver *drv = bs->drv;
+    BlockDriverAIOCB *ret;
 
     if (!drv)
         return NULL;
@@ -1071,7 +1117,15 @@ BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
         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,
@@ -1079,6 +1133,7 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
                                  BlockDriverCompletionFunc *cb, void *opaque)
 {
     BlockDriver *drv = bs->drv;
+    BlockDriverAIOCB *ret;
 
     if (!drv)
         return NULL;
@@ -1088,7 +1143,15 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
         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)
@@ -1102,7 +1165,7 @@ 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)
@@ -1172,7 +1235,7 @@ static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
     qemu_bh_cancel(acb->bh);
     qemu_aio_release(acb);
 }
-#endif /* !QEMU_TOOL */
+#endif /* !QEMU_IMG */
 
 /**************************************************************/
 /* sync block device emulation */
@@ -1347,3 +1410,14 @@ void bdrv_set_locked(BlockDriverState *bs, int locked)
         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;
+}