qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 resend 0/4] block: more read-only changes, related to backing files
@ 2010-02-04 22:04 Naphtali Sprei
  2010-02-04 22:04 ` [Qemu-devel] [PATCH v2 resend 1/4] Add open_flags to BlockDriverState Will be used later Naphtali Sprei
  2010-02-05  2:46 ` [Qemu-devel] [PATCH v2 resend 0/4] block: more read-only changes, related to backing files Sheng Yang
  0 siblings, 2 replies; 8+ messages in thread
From: Naphtali Sprei @ 2010-02-04 22:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Naphtali Sprei

This is version 2. The change between previous patch (only 3/4) is the order of closing/re-opening the image.

Naphtali Sprei (4):
  Add open_flags to BlockDriverState Will be used later
  qemu-img: Fix qemu-img can't create qcow image based on read-only
    image
  Block: readonly changes
  Open backing file read-only also for snapshot mode

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH v2 resend 1/4] Add open_flags to BlockDriverState Will be used later
  2010-02-04 22:04 [Qemu-devel] [PATCH v2 resend 0/4] block: more read-only changes, related to backing files Naphtali Sprei
@ 2010-02-04 22:04 ` Naphtali Sprei
  2010-02-04 22:04   ` [Qemu-devel] [PATCH v2 resend 2/4] qemu-img: Fix qemu-img can't create qcow image based on read-only image Naphtali Sprei
  2010-02-05  2:46 ` [Qemu-devel] [PATCH v2 resend 0/4] block: more read-only changes, related to backing files Sheng Yang
  1 sibling, 1 reply; 8+ messages in thread
From: Naphtali Sprei @ 2010-02-04 22:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Naphtali Sprei


Signed-off-by: Naphtali Sprei <nsprei@redhat.com>
---
 block.c     |    1 +
 block_int.h |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/block.c b/block.c
index 1919d19..66564de 100644
--- a/block.c
+++ b/block.c
@@ -363,6 +363,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
     bs->is_temporary = 0;
     bs->encrypted = 0;
     bs->valid_key = 0;
+    bs->open_flags = flags;
     /* buffer_alignment defaulted to 512, drivers can change this value */
     bs->buffer_alignment = 512;
 
diff --git a/block_int.h b/block_int.h
index a0ebd90..9144d37 100644
--- a/block_int.h
+++ b/block_int.h
@@ -130,6 +130,7 @@ struct BlockDriverState {
     int64_t total_sectors; /* if we are reading a disk image, give its
                               size in sectors */
     int read_only; /* if true, the media is read only */
+    int open_flags; /* flags used to open the file */
     int removable; /* if true, the media can be removed */
     int locked;    /* if true, the media cannot temporarily be ejected */
     int encrypted; /* if true, the media is encrypted */
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH v2 resend 2/4] qemu-img: Fix qemu-img can't create qcow image based on read-only image
  2010-02-04 22:04 ` [Qemu-devel] [PATCH v2 resend 1/4] Add open_flags to BlockDriverState Will be used later Naphtali Sprei
@ 2010-02-04 22:04   ` Naphtali Sprei
  2010-02-04 22:04     ` [Qemu-devel] [PATCH v2 resend 3/4] Block: readonly changes Naphtali Sprei
  2010-02-05  2:45     ` [Qemu-devel] [PATCH v2 resend 2/4] qemu-img: Fix qemu-img can't create qcow image based on read-only image Sheng Yang
  0 siblings, 2 replies; 8+ messages in thread
From: Naphtali Sprei @ 2010-02-04 22:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Naphtali Sprei

Open image file read-only where possible
Patch originally written by Sheng Yang <sheng@linux.intel.com>

Signed-off-by: Naphtali Sprei <nsprei@redhat.com>
---
 qemu-img.c |   15 ++++++++++-----
 1 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index cbba4fc..b0ac9eb 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -188,11 +188,13 @@ static int read_password(char *buf, int buf_size)
 #endif
 
 static BlockDriverState *bdrv_new_open(const char *filename,
-                                       const char *fmt)
+                                       const char *fmt,
+                                       int readonly)
 {
     BlockDriverState *bs;
     BlockDriver *drv;
     char password[256];
+    int flags = BRDV_O_FLAGS;
 
     bs = bdrv_new("");
     if (!bs)
@@ -204,7 +206,10 @@ static BlockDriverState *bdrv_new_open(const char *filename,
     } else {
         drv = NULL;
     }
-    if (bdrv_open2(bs, filename, BRDV_O_FLAGS | BDRV_O_RDWR, drv) < 0) {
+    if (!readonly) {
+        flags |= BDRV_O_RDWR;
+    }
+    if (bdrv_open2(bs, filename, flags, drv) < 0) {
         error("Could not open '%s'", filename);
     }
     if (bdrv_is_encrypted(bs)) {
@@ -343,7 +348,7 @@ static int img_create(int argc, char **argv)
                 }
             }
 
-            bs = bdrv_new_open(backing_file->value.s, fmt);
+            bs = bdrv_new_open(backing_file->value.s, fmt, 1);
             bdrv_get_geometry(bs, &size);
             size *= 512;
             bdrv_delete(bs);
@@ -627,7 +632,7 @@ static int img_convert(int argc, char **argv)
 
     total_sectors = 0;
     for (bs_i = 0; bs_i < bs_n; bs_i++) {
-        bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
+        bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, 1);
         if (!bs[bs_i])
             error("Could not open '%s'", argv[optind + bs_i]);
         bdrv_get_geometry(bs[bs_i], &bs_sectors);
@@ -685,7 +690,7 @@ static int img_convert(int argc, char **argv)
         }
     }
 
-    out_bs = bdrv_new_open(out_filename, out_fmt);
+    out_bs = bdrv_new_open(out_filename, out_fmt, 0);
 
     bs_i = 0;
     bs_offset = 0;
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH v2 resend 3/4] Block: readonly changes
  2010-02-04 22:04   ` [Qemu-devel] [PATCH v2 resend 2/4] qemu-img: Fix qemu-img can't create qcow image based on read-only image Naphtali Sprei
@ 2010-02-04 22:04     ` Naphtali Sprei
  2010-02-04 22:04       ` [Qemu-devel] [PATCH v2 resend 4/4] Open backing file read-only also for snapshot mode Naphtali Sprei
  2010-02-05  8:20       ` [Qemu-devel] [PATCH v2 resend 3/4] Block: readonly changes Kevin Wolf
  2010-02-05  2:45     ` [Qemu-devel] [PATCH v2 resend 2/4] qemu-img: Fix qemu-img can't create qcow image based on read-only image Sheng Yang
  1 sibling, 2 replies; 8+ messages in thread
From: Naphtali Sprei @ 2010-02-04 22:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Naphtali Sprei

Open backing file for read-only
During commit upgrade to read-write and back at end to read-only

Signed-off-by: Naphtali Sprei <nsprei@redhat.com>
---
 block.c     |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 block_int.h |    1 +
 2 files changed, 61 insertions(+), 8 deletions(-)

diff --git a/block.c b/block.c
index 66564de..4a9df91 100644
--- a/block.c
+++ b/block.c
@@ -451,7 +451,6 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
     if (flags & (BDRV_O_CACHE_WB|BDRV_O_NOCACHE))
         bs->enable_write_cache = 1;
 
-    bs->read_only = (flags & BDRV_O_RDWR) == 0;
     if (!(flags & BDRV_O_FILE)) {
         open_flags = (flags & (BDRV_O_RDWR | BDRV_O_CACHE_MASK|BDRV_O_NATIVE_AIO));
         if (bs->is_temporary) { /* snapshot should be writeable */
@@ -466,6 +465,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
         goto free_and_fail;
     }
 
+    bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR);
     if (drv->bdrv_getlength) {
         bs->total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
     }
@@ -482,13 +482,28 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
                      filename, bs->backing_file);
         if (bs->backing_format[0] != '\0')
             back_drv = bdrv_find_format(bs->backing_format);
+
+        open_flags &= ~BDRV_O_RDWR; /* clear RW, then restore from orig */
+        if (bs->is_temporary) {
+            open_flags |= (flags & BDRV_O_RDWR);
+        }
+        
         ret = bdrv_open2(bs->backing_hd, backing_filename, open_flags,
                          back_drv);
-        bs->backing_hd->read_only =  (open_flags & BDRV_O_RDWR) == 0;
+        if (ret < 0) {
+            open_flags &= ~BDRV_O_RDWR;  /* Fall-back to read-only for the backing file */
+            ret = bdrv_open2(bs->backing_hd, backing_filename, open_flags,
+                             back_drv);
+        }
         if (ret < 0) {
             bdrv_close(bs);
             return ret;
         }
+        if (!bs->is_temporary) {
+            bs->backing_hd->keep_read_only = bs->keep_read_only; /* base image inherits from "parent" and open read-only */
+        } else {
+            bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR);
+        }
     }
 
     if (!bdrv_key_required(bs)) {
@@ -564,19 +579,38 @@ int bdrv_commit(BlockDriverState *bs)
 {
     BlockDriver *drv = bs->drv;
     int64_t i, total_sectors;
-    int n, j;
+    int n, j, ro, open_flags;
     int ret = 0;
     unsigned char sector[512];
+    char filename[1024];
+    BlockDriverState *bs_rw, *bs_ro;
 
     if (!drv)
         return -ENOMEDIUM;
+    
+    if (!bs->backing_hd) {
+	return -ENOTSUP;
+    }
 
-    if (bs->read_only) {
+    if (bs->backing_hd->keep_read_only) {
 	return -EACCES;
     }
+    
+    ro = bs->backing_hd->read_only;
+    strncpy(filename, bs->backing_hd->filename, sizeof(filename));
+    open_flags =  bs->backing_hd->open_flags;
 
-    if (!bs->backing_hd) {
-	return -ENOTSUP;
+    if (ro) { /* re-open as RW */
+        bdrv_close(bs->backing_hd);
+        qemu_free(bs->backing_hd);
+
+        bs_rw = bdrv_new("");
+        ret = bdrv_open2(bs_rw, filename, open_flags | BDRV_O_RDWR, NULL);
+        if (ret < 0) {
+            bdrv_delete(bs_rw);
+            return -EACCES;
+        }
+        bs->backing_hd = bs_rw;
     }
 
     total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
@@ -584,11 +618,13 @@ int bdrv_commit(BlockDriverState *bs)
         if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
             for(j = 0; j < n; j++) {
                 if (bdrv_read(bs, i, sector, 1) != 0) {
-                    return -EIO;
+                    ret = -EIO;
+                    goto ro_cleanup;
                 }
 
                 if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
-                    return -EIO;
+                    ret = -EIO;
+                    goto ro_cleanup;
                 }
                 i++;
 	    }
@@ -608,6 +644,22 @@ int bdrv_commit(BlockDriverState *bs)
      */
     if (bs->backing_hd)
         bdrv_flush(bs->backing_hd);
+
+ro_cleanup:
+
+    if (ro) { /* re-open as RO */
+        bdrv_close(bs->backing_hd);
+        qemu_free(bs->backing_hd);
+        bs_ro = bdrv_new("");
+        ret = bdrv_open2(bs_ro, filename, open_flags & ~BDRV_O_RDWR, NULL);
+        if (ret < 0) {
+            bdrv_delete(bs_ro);
+            return -EACCES;
+        }
+        bs->backing_hd = bs_ro;
+        bs->backing_hd->keep_read_only = 0;
+    }
+
     return ret;
 }
 
diff --git a/block_int.h b/block_int.h
index 9144d37..02fae5b 100644
--- a/block_int.h
+++ b/block_int.h
@@ -130,6 +130,7 @@ struct BlockDriverState {
     int64_t total_sectors; /* if we are reading a disk image, give its
                               size in sectors */
     int read_only; /* if true, the media is read only */
+    int keep_read_only; /* if true, the media was requested to stay read only */
     int open_flags; /* flags used to open the file */
     int removable; /* if true, the media can be removed */
     int locked;    /* if true, the media cannot temporarily be ejected */
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH v2 resend 4/4] Open backing file read-only also for snapshot mode
  2010-02-04 22:04     ` [Qemu-devel] [PATCH v2 resend 3/4] Block: readonly changes Naphtali Sprei
@ 2010-02-04 22:04       ` Naphtali Sprei
  2010-02-05  8:20       ` [Qemu-devel] [PATCH v2 resend 3/4] Block: readonly changes Kevin Wolf
  1 sibling, 0 replies; 8+ messages in thread
From: Naphtali Sprei @ 2010-02-04 22:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Naphtali Sprei


Signed-off-by: Naphtali Sprei <nsprei@redhat.com>
---
 block.c |   10 +---------
 1 files changed, 1 insertions(+), 9 deletions(-)

diff --git a/block.c b/block.c
index 4a9df91..780cea9 100644
--- a/block.c
+++ b/block.c
@@ -483,19 +483,11 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
         if (bs->backing_format[0] != '\0')
             back_drv = bdrv_find_format(bs->backing_format);
 
-        open_flags &= ~BDRV_O_RDWR; /* clear RW, then restore from orig */
-        if (bs->is_temporary) {
-            open_flags |= (flags & BDRV_O_RDWR);
-        }
+        open_flags &= ~BDRV_O_RDWR;
         
         ret = bdrv_open2(bs->backing_hd, backing_filename, open_flags,
                          back_drv);
         if (ret < 0) {
-            open_flags &= ~BDRV_O_RDWR;  /* Fall-back to read-only for the backing file */
-            ret = bdrv_open2(bs->backing_hd, backing_filename, open_flags,
-                             back_drv);
-        }
-        if (ret < 0) {
             bdrv_close(bs);
             return ret;
         }
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PATCH v2 resend 2/4] qemu-img: Fix qemu-img can't create qcow image based on read-only image
  2010-02-04 22:04   ` [Qemu-devel] [PATCH v2 resend 2/4] qemu-img: Fix qemu-img can't create qcow image based on read-only image Naphtali Sprei
  2010-02-04 22:04     ` [Qemu-devel] [PATCH v2 resend 3/4] Block: readonly changes Naphtali Sprei
@ 2010-02-05  2:45     ` Sheng Yang
  1 sibling, 0 replies; 8+ messages in thread
From: Sheng Yang @ 2010-02-05  2:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Naphtali Sprei

On Friday 05 February 2010 06:04:27 Naphtali Sprei wrote:
> Open image file read-only where possible
> Patch originally written by Sheng Yang <sheng@linux.intel.com>
> 

Signed-off-by: Sheng Yang <sheng@linux.intel.com>

> Signed-off-by: Naphtali Sprei <nsprei@redhat.com>

-- 
regards
Yang, Sheng
> ---
>  qemu-img.c |   15 ++++++++++-----
>  1 files changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/qemu-img.c b/qemu-img.c
> index cbba4fc..b0ac9eb 100644
> --- a/qemu-img.c
> +++ b/qemu-img.c
> @@ -188,11 +188,13 @@ static int read_password(char *buf, int buf_size)
>  #endif
> 
>  static BlockDriverState *bdrv_new_open(const char *filename,
> -                                       const char *fmt)
> +                                       const char *fmt,
> +                                       int readonly)
>  {
>      BlockDriverState *bs;
>      BlockDriver *drv;
>      char password[256];
> +    int flags = BRDV_O_FLAGS;
> 
>      bs = bdrv_new("");
>      if (!bs)
> @@ -204,7 +206,10 @@ static BlockDriverState *bdrv_new_open(const char
>  *filename, } else {
>          drv = NULL;
>      }
> -    if (bdrv_open2(bs, filename, BRDV_O_FLAGS | BDRV_O_RDWR, drv) < 0) {
> +    if (!readonly) {
> +        flags |= BDRV_O_RDWR;
> +    }
> +    if (bdrv_open2(bs, filename, flags, drv) < 0) {
>          error("Could not open '%s'", filename);
>      }
>      if (bdrv_is_encrypted(bs)) {
> @@ -343,7 +348,7 @@ static int img_create(int argc, char **argv)
>                  }
>              }
> 
> -            bs = bdrv_new_open(backing_file->value.s, fmt);
> +            bs = bdrv_new_open(backing_file->value.s, fmt, 1);
>              bdrv_get_geometry(bs, &size);
>              size *= 512;
>              bdrv_delete(bs);
> @@ -627,7 +632,7 @@ static int img_convert(int argc, char **argv)
> 
>      total_sectors = 0;
>      for (bs_i = 0; bs_i < bs_n; bs_i++) {
> -        bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
> +        bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, 1);
>          if (!bs[bs_i])
>              error("Could not open '%s'", argv[optind + bs_i]);
>          bdrv_get_geometry(bs[bs_i], &bs_sectors);
> @@ -685,7 +690,7 @@ static int img_convert(int argc, char **argv)
>          }
>      }
> 
> -    out_bs = bdrv_new_open(out_filename, out_fmt);
> +    out_bs = bdrv_new_open(out_filename, out_fmt, 0);
> 
>      bs_i = 0;
>      bs_offset = 0;
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PATCH v2 resend 0/4] block: more read-only changes, related to backing files
  2010-02-04 22:04 [Qemu-devel] [PATCH v2 resend 0/4] block: more read-only changes, related to backing files Naphtali Sprei
  2010-02-04 22:04 ` [Qemu-devel] [PATCH v2 resend 1/4] Add open_flags to BlockDriverState Will be used later Naphtali Sprei
@ 2010-02-05  2:46 ` Sheng Yang
  1 sibling, 0 replies; 8+ messages in thread
From: Sheng Yang @ 2010-02-05  2:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Naphtali Sprei, Christoph Hellwig, Alexander Graf

On Friday 05 February 2010 06:04:25 Naphtali Sprei wrote:
> This is version 2. The change between previous patch (only 3/4) is the
>  order of closing/re-opening the image.
> 
> Naphtali Sprei (4):
>   Add open_flags to BlockDriverState Will be used later
>   qemu-img: Fix qemu-img can't create qcow image based on read-only
>     image
>   Block: readonly changes
>   Open backing file read-only also for snapshot mode
> 
(CC to the original reviewers...)

-- 
regards
Yang, Sheng

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PATCH v2 resend 3/4] Block: readonly changes
  2010-02-04 22:04     ` [Qemu-devel] [PATCH v2 resend 3/4] Block: readonly changes Naphtali Sprei
  2010-02-04 22:04       ` [Qemu-devel] [PATCH v2 resend 4/4] Open backing file read-only also for snapshot mode Naphtali Sprei
@ 2010-02-05  8:20       ` Kevin Wolf
  1 sibling, 0 replies; 8+ messages in thread
From: Kevin Wolf @ 2010-02-05  8:20 UTC (permalink / raw)
  To: Naphtali Sprei; +Cc: qemu-devel

Am 04.02.2010 23:04, schrieb Naphtali Sprei:
> Open backing file for read-only
> During commit upgrade to read-write and back at end to read-only
> 
> Signed-off-by: Naphtali Sprei <nsprei@redhat.com>
> ---
>  block.c     |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
>  block_int.h |    1 +
>  2 files changed, 61 insertions(+), 8 deletions(-)
> 
> diff --git a/block.c b/block.c
> index 66564de..4a9df91 100644
> --- a/block.c
> +++ b/block.c
> @@ -451,7 +451,6 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
>      if (flags & (BDRV_O_CACHE_WB|BDRV_O_NOCACHE))
>          bs->enable_write_cache = 1;
>  
> -    bs->read_only = (flags & BDRV_O_RDWR) == 0;
>      if (!(flags & BDRV_O_FILE)) {
>          open_flags = (flags & (BDRV_O_RDWR | BDRV_O_CACHE_MASK|BDRV_O_NATIVE_AIO));
>          if (bs->is_temporary) { /* snapshot should be writeable */
> @@ -466,6 +465,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
>          goto free_and_fail;
>      }
>  
> +    bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR);
>      if (drv->bdrv_getlength) {
>          bs->total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
>      }
> @@ -482,13 +482,28 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
>                       filename, bs->backing_file);
>          if (bs->backing_format[0] != '\0')
>              back_drv = bdrv_find_format(bs->backing_format);
> +
> +        open_flags &= ~BDRV_O_RDWR; /* clear RW, then restore from orig */
> +        if (bs->is_temporary) {
> +            open_flags |= (flags & BDRV_O_RDWR);
> +        }
> +        
>          ret = bdrv_open2(bs->backing_hd, backing_filename, open_flags,
>                           back_drv);
> -        bs->backing_hd->read_only =  (open_flags & BDRV_O_RDWR) == 0;
> +        if (ret < 0) {
> +            open_flags &= ~BDRV_O_RDWR;  /* Fall-back to read-only for the backing file */
> +            ret = bdrv_open2(bs->backing_hd, backing_filename, open_flags,
> +                             back_drv);
> +        }

Why is this needed? The only case in which a backing file is opened
read-write is during commit, right? For commit there is certainly no use
in opening it read-only instead.

This whole code looks like there are cases where a backing file is still
opened read-write by default, though the commit message says that no
such backing files exist. Am I missing something?

>          if (ret < 0) {
>              bdrv_close(bs);
>              return ret;
>          }
> +        if (!bs->is_temporary) {
> +            bs->backing_hd->keep_read_only = bs->keep_read_only; /* base image inherits from "parent" and open read-only */

This looks like more than 80 characters on a line.

What would helps here and also would improve consistency in style is to
move the comments to the line before instead of sticking them at the end
of a code line. This is true even more if the comment actually applies
to a whole block and not only to the line in which it is written (you're
doing this in other places).

> +        } else {
> +            bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR);
> +        }
>      }
>  
>      if (!bdrv_key_required(bs)) {
> @@ -564,19 +579,38 @@ int bdrv_commit(BlockDriverState *bs)
>  {
>      BlockDriver *drv = bs->drv;
>      int64_t i, total_sectors;
> -    int n, j;
> +    int n, j, ro, open_flags;
>      int ret = 0;
>      unsigned char sector[512];
> +    char filename[1024];
> +    BlockDriverState *bs_rw, *bs_ro;
>  
>      if (!drv)
>          return -ENOMEDIUM;
> +    
> +    if (!bs->backing_hd) {
> +	return -ENOTSUP;
> +    }
>  
> -    if (bs->read_only) {
> +    if (bs->backing_hd->keep_read_only) {
>  	return -EACCES;
>      }
> +    
> +    ro = bs->backing_hd->read_only;
> +    strncpy(filename, bs->backing_hd->filename, sizeof(filename));
> +    open_flags =  bs->backing_hd->open_flags;
>  
> -    if (!bs->backing_hd) {
> -	return -ENOTSUP;
> +    if (ro) { /* re-open as RW */
> +        bdrv_close(bs->backing_hd);
> +        qemu_free(bs->backing_hd);

bdrv_delete is doing what you mean here. But actually, you don't need to
delete it, you can just reuse the old bs for re-opening the image.

> +
> +        bs_rw = bdrv_new("");
> +        ret = bdrv_open2(bs_rw, filename, open_flags | BDRV_O_RDWR, NULL);
> +        if (ret < 0) {
> +            bdrv_delete(bs_rw);
> +            return -EACCES;

Why don't you pass the right return value up? Apart from that, you
should re-open the backing file (read-only) or the VM will get into
trouble...

> +        }
> +        bs->backing_hd = bs_rw;

Eek... ;-) Well, it should work, as far as I know the block drivers.

>      }
>  
>      total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
> @@ -584,11 +618,13 @@ int bdrv_commit(BlockDriverState *bs)
>          if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
>              for(j = 0; j < n; j++) {
>                  if (bdrv_read(bs, i, sector, 1) != 0) {
> -                    return -EIO;
> +                    ret = -EIO;
> +                    goto ro_cleanup;
>                  }
>  
>                  if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
> -                    return -EIO;
> +                    ret = -EIO;
> +                    goto ro_cleanup;
>                  }
>                  i++;
>  	    }
> @@ -608,6 +644,22 @@ int bdrv_commit(BlockDriverState *bs)
>       */
>      if (bs->backing_hd)
>          bdrv_flush(bs->backing_hd);
> +
> +ro_cleanup:
> +
> +    if (ro) { /* re-open as RO */
> +        bdrv_close(bs->backing_hd);
> +        qemu_free(bs->backing_hd);

Again, I think bdrv_delete is needed.

> +        bs_ro = bdrv_new("");
> +        ret = bdrv_open2(bs_ro, filename, open_flags & ~BDRV_O_RDWR, NULL);
> +        if (ret < 0) {
> +            bdrv_delete(bs_ro);
> +            return -EACCES;

Again, wrong return value.

> +        }
> +        bs->backing_hd = bs_ro;
> +        bs->backing_hd->keep_read_only = 0;
> +    }
> +
>      return ret;
>  }
>  
> diff --git a/block_int.h b/block_int.h
> index 9144d37..02fae5b 100644
> --- a/block_int.h
> +++ b/block_int.h
> @@ -130,6 +130,7 @@ struct BlockDriverState {
>      int64_t total_sectors; /* if we are reading a disk image, give its
>                                size in sectors */
>      int read_only; /* if true, the media is read only */
> +    int keep_read_only; /* if true, the media was requested to stay read only */
>      int open_flags; /* flags used to open the file */
>      int removable; /* if true, the media can be removed */
>      int locked;    /* if true, the media cannot temporarily be ejected */

Kevin

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-02-05  8:21 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-04 22:04 [Qemu-devel] [PATCH v2 resend 0/4] block: more read-only changes, related to backing files Naphtali Sprei
2010-02-04 22:04 ` [Qemu-devel] [PATCH v2 resend 1/4] Add open_flags to BlockDriverState Will be used later Naphtali Sprei
2010-02-04 22:04   ` [Qemu-devel] [PATCH v2 resend 2/4] qemu-img: Fix qemu-img can't create qcow image based on read-only image Naphtali Sprei
2010-02-04 22:04     ` [Qemu-devel] [PATCH v2 resend 3/4] Block: readonly changes Naphtali Sprei
2010-02-04 22:04       ` [Qemu-devel] [PATCH v2 resend 4/4] Open backing file read-only also for snapshot mode Naphtali Sprei
2010-02-05  8:20       ` [Qemu-devel] [PATCH v2 resend 3/4] Block: readonly changes Kevin Wolf
2010-02-05  2:45     ` [Qemu-devel] [PATCH v2 resend 2/4] qemu-img: Fix qemu-img can't create qcow image based on read-only image Sheng Yang
2010-02-05  2:46 ` [Qemu-devel] [PATCH v2 resend 0/4] block: more read-only changes, related to backing files Sheng Yang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).