[01/17] vvfat: Use BdrvChild for s->qcow
diff mbox

Message ID 1466500894-9710-2-git-send-email-kwolf@redhat.com
State New
Headers show

Commit Message

Kevin Wolf June 21, 2016, 9:21 a.m. UTC
vvfat uses a temporary qcow file to cache written data in read-write
mode. In order to do things properly, this should show up in the BDS
graph and I/O should go through BdrvChild like for every other node.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vvfat.c | 66 ++++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 43 insertions(+), 23 deletions(-)

Comments

Max Reitz June 22, 2016, 4:54 p.m. UTC | #1
On 21.06.2016 11:21, Kevin Wolf wrote:
> vvfat uses a temporary qcow file to cache written data in read-write
> mode. In order to do things properly, this should show up in the BDS
> graph and I/O should go through BdrvChild like for every other node.
> 
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  block/vvfat.c | 66 ++++++++++++++++++++++++++++++++++++++---------------------
>  1 file changed, 43 insertions(+), 23 deletions(-)

checkpatch.pl has some complaints:

ERROR: "foo* bar" should be "foo *bar"
#43: FILE: block/vvfat.c:348:
+    BdrvChild* qcow;

ERROR: spaces required around that '-' (ctx:VxV)
#81: FILE: block/vvfat.c:1392:
+            if (bdrv_is_allocated(s->qcow->bs, sector_num,
nb_sectors-i, &n)) {
                                                                      ^

ERROR: spaces required around that '*' (ctx:VxV)
#84: FILE: block/vvfat.c:1395:
+                if (bdrv_read(s->qcow->bs, sector_num, buf + i*0x200, n)) {
                                                               ^

ERROR: code indent should never use tabs
#103: FILE: block/vvfat.c:1677:
+^I                                     cluster2sector(s, cluster_num) + i,$

The fourth is actually something you introduced (more or less, at least
all of the surrounding code uses spaces), so that must be fixed.

The rest is preexisting, but I think some of those are worth fixing
still; namely all but the first. You know how I think about the first
and I know how you think about it, so I won't complain if it's
surrounded by code in the same style.

> diff --git a/block/vvfat.c b/block/vvfat.c
> index 6d2e21c..2eb2536 100644
> --- a/block/vvfat.c
> +++ b/block/vvfat.c

[...]

> @@ -2949,7 +2958,7 @@ write_target_commit(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
>  
>  static void write_target_close(BlockDriverState *bs) {
>      BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
> -    bdrv_unref(s->qcow);
> +    bdrv_unref_child(NULL, s->qcow);

Not that it matters, but why not s->bs instead of NULL?

>      g_free(s->qcow_filename);
>  }
>  
> @@ -2959,8 +2968,19 @@ static BlockDriver vvfat_write_target = {
>      .bdrv_close         = write_target_close,
>  };
>  
> -static int enable_write_target(BDRVVVFATState *s, Error **errp)
> +static void vvfat_qcow_options(int *child_flags, QDict *child_options,
> +                               int parent_flags, QDict *parent_options)
>  {
> +    *child_flags = BDRV_O_RDWR | BDRV_O_NO_FLUSH;
> +}
> +
> +const BdrvChildRole child_vvfat_qcow = {

Any reason for not making this static?

> +    .inherit_options    = vvfat_qcow_options,
> +};
> +
> +static int enable_write_target(BlockDriverState *bs, Error **errp)
> +{
> +    BDRVVVFATState *s = bs->opaque;
>      BlockDriver *bdrv_qcow = NULL;
>      BlockDriverState *backing;
>      QemuOpts *opts = NULL;
> @@ -2999,8 +3019,8 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp)
>  
>      options = qdict_new();
>      qdict_put(options, "driver", qstring_from_str("qcow"));
> -    s->qcow = bdrv_open(s->qcow_filename, NULL, options,
> -                        BDRV_O_RDWR | BDRV_O_NO_FLUSH, errp);
> +    s->qcow = bdrv_open_child(s->qcow_filename, options, "qcow", bs,

I'd have called it "write_target", but, well.

Max

> +                              &child_vvfat_qcow, false, errp);
>      if (!s->qcow) {
>          ret = -EINVAL;
>          goto err;
>

Patch
diff mbox

diff --git a/block/vvfat.c b/block/vvfat.c
index 6d2e21c..2eb2536 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -344,9 +344,8 @@  typedef struct BDRVVVFATState {
     unsigned int current_cluster;
 
     /* write support */
-    BlockDriverState* write_target;
     char* qcow_filename;
-    BlockDriverState* qcow;
+    BdrvChild* qcow;
     void* fat2;
     char* used_clusters;
     array_t commits;
@@ -984,7 +983,7 @@  static int init_directories(BDRVVVFATState* s,
 static BDRVVVFATState *vvv = NULL;
 #endif
 
-static int enable_write_target(BDRVVVFATState *s, Error **errp);
+static int enable_write_target(BlockDriverState *bs, Error **errp);
 static int is_consistent(BDRVVVFATState *s);
 
 static QemuOptsList runtime_opts = {
@@ -1162,7 +1161,7 @@  static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
 
     /* read only is the default for safety */
     bs->read_only = 1;
-    s->qcow = s->write_target = NULL;
+    s->qcow = NULL;
     s->qcow_filename = NULL;
     s->fat2 = NULL;
     s->downcase_short_names = 1;
@@ -1173,7 +1172,7 @@  static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
     s->sector_count = cyls * heads * secs - (s->first_sectors_number - 1);
 
     if (qemu_opt_get_bool(opts, "rw", false)) {
-        ret = enable_write_target(s, errp);
+        ret = enable_write_target(bs, errp);
         if (ret < 0) {
             goto fail;
         }
@@ -1390,9 +1389,10 @@  static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
 	   return -1;
 	if (s->qcow) {
 	    int n;
-            if (bdrv_is_allocated(s->qcow, sector_num, nb_sectors-i, &n)) {
-DLOG(fprintf(stderr, "sectors %d+%d allocated\n", (int)sector_num, n));
-                if (bdrv_read(s->qcow, sector_num, buf + i*0x200, n)) {
+            if (bdrv_is_allocated(s->qcow->bs, sector_num, nb_sectors-i, &n)) {
+                DLOG(fprintf(stderr, "sectors %d+%d allocated\n",
+                             (int)sector_num, n));
+                if (bdrv_read(s->qcow->bs, sector_num, buf + i*0x200, n)) {
                     return -1;
                 }
                 i += n - 1;
@@ -1668,12 +1668,15 @@  static inline int cluster_was_modified(BDRVVVFATState* s, uint32_t cluster_num)
     int was_modified = 0;
     int i, dummy;
 
-    if (s->qcow == NULL)
-	return 0;
+    if (s->qcow == NULL) {
+        return 0;
+    }
 
-    for (i = 0; !was_modified && i < s->sectors_per_cluster; i++)
-	was_modified = bdrv_is_allocated(s->qcow,
-		cluster2sector(s, cluster_num) + i, 1, &dummy);
+    for (i = 0; !was_modified && i < s->sectors_per_cluster; i++) {
+        was_modified = bdrv_is_allocated(s->qcow->bs,
+	                                     cluster2sector(s, cluster_num) + i,
+                                         1, &dummy);
+    }
 
     return was_modified;
 }
@@ -1822,11 +1825,17 @@  static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
 
 		vvfat_close_current_file(s);
                 for (i = 0; i < s->sectors_per_cluster; i++) {
-                    if (!bdrv_is_allocated(s->qcow, offset + i, 1, &dummy)) {
-                        if (vvfat_read(s->bs, offset, s->cluster_buffer, 1)) {
+                    int res;
+
+                    res = bdrv_is_allocated(s->qcow->bs, offset + i, 1, &dummy);
+                    if (!res) {
+                        res = vvfat_read(s->bs, offset, s->cluster_buffer, 1);
+                        if (res) {
                             return -1;
                         }
-                        if (bdrv_write(s->qcow, offset, s->cluster_buffer, 1)) {
+                        res = bdrv_write(s->qcow->bs, offset,
+                                         s->cluster_buffer, 1);
+                        if (res) {
                             return -2;
                         }
                     }
@@ -2782,8 +2791,8 @@  static int do_commit(BDRVVVFATState* s)
 	return ret;
     }
 
-    if (s->qcow->drv->bdrv_make_empty) {
-        s->qcow->drv->bdrv_make_empty(s->qcow);
+    if (s->qcow->bs->drv->bdrv_make_empty) {
+        s->qcow->bs->drv->bdrv_make_empty(s->qcow->bs);
     }
 
     memset(s->used_clusters, 0, sector2cluster(s, s->sector_count));
@@ -2879,7 +2888,7 @@  DLOG(checkpoint());
      * Use qcow backend. Commit later.
      */
 DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors));
-    ret = bdrv_write(s->qcow, sector_num, buf, nb_sectors);
+    ret = bdrv_write(s->qcow->bs, sector_num, buf, nb_sectors);
     if (ret < 0) {
 	fprintf(stderr, "Error writing to qcow backend\n");
 	return ret;
@@ -2949,7 +2958,7 @@  write_target_commit(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
 
 static void write_target_close(BlockDriverState *bs) {
     BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
-    bdrv_unref(s->qcow);
+    bdrv_unref_child(NULL, s->qcow);
     g_free(s->qcow_filename);
 }
 
@@ -2959,8 +2968,19 @@  static BlockDriver vvfat_write_target = {
     .bdrv_close         = write_target_close,
 };
 
-static int enable_write_target(BDRVVVFATState *s, Error **errp)
+static void vvfat_qcow_options(int *child_flags, QDict *child_options,
+                               int parent_flags, QDict *parent_options)
 {
+    *child_flags = BDRV_O_RDWR | BDRV_O_NO_FLUSH;
+}
+
+const BdrvChildRole child_vvfat_qcow = {
+    .inherit_options    = vvfat_qcow_options,
+};
+
+static int enable_write_target(BlockDriverState *bs, Error **errp)
+{
+    BDRVVVFATState *s = bs->opaque;
     BlockDriver *bdrv_qcow = NULL;
     BlockDriverState *backing;
     QemuOpts *opts = NULL;
@@ -2999,8 +3019,8 @@  static int enable_write_target(BDRVVVFATState *s, Error **errp)
 
     options = qdict_new();
     qdict_put(options, "driver", qstring_from_str("qcow"));
-    s->qcow = bdrv_open(s->qcow_filename, NULL, options,
-                        BDRV_O_RDWR | BDRV_O_NO_FLUSH, errp);
+    s->qcow = bdrv_open_child(s->qcow_filename, options, "qcow", bs,
+                              &child_vvfat_qcow, false, errp);
     if (!s->qcow) {
         ret = -EINVAL;
         goto err;