All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anthony Liguori <anthony@codemonkey.ws>
To: Naphtali Sprei <nsprei@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>,
	qemu-devel@nongnu.org, Sheng Yang <sheng@linux.intel.com>
Subject: Re: [Qemu-devel] [PATCH v4 rebased] block: more read-only changes, related to backing files
Date: Fri, 19 Feb 2010 15:48:35 -0600	[thread overview]
Message-ID: <4B7F0733.1060304@codemonkey.ws> (raw)
In-Reply-To: <4B77E0E6.1090701@redhat.com>

On 02/14/2010 05:39 AM, Naphtali Sprei wrote:
> Open backing file read-only where possible
> Upgrade backing file to read-write during commit, back to read-only after commit
>    If upgrade fail, back to read-only. If also fail, "disconnect" the drive.
>
> Signed-off-by: Naphtali Sprei<nsprei@redhat.com>
>    

Applied.  Thanks.

Regards,

Anthony Liguori
> ---
>   block.c     |   83 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
>   block_int.h |    2 +
>   2 files changed, 73 insertions(+), 12 deletions(-)
>
> diff --git a/block.c b/block.c
> index af56ea7..31d1ba4 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;
>
> @@ -450,8 +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;
> -
>       /*
>        * Clear flags that are internal to the block layer before opening the
>        * image.
> @@ -472,6 +471,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;
>       }
> @@ -488,13 +488,22 @@ 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);
> +
> +        /* backing files always opened read-only */
> +        open_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) {
>               bdrv_close(bs);
>               return ret;
>           }
> +        if (bs->is_temporary) {
> +            bs->backing_hd->keep_read_only = !(flags&  BDRV_O_RDWR);
> +        } else {
> +            /* base image inherits from "parent" */
> +            bs->backing_hd->keep_read_only = bs->keep_read_only;
> +        }
>       }
>
>       if (!bdrv_key_required(bs)) {
> @@ -570,19 +579,48 @@ int bdrv_commit(BlockDriverState *bs)
>   {
>       BlockDriver *drv = bs->drv;
>       int64_t i, total_sectors;
> -    int n, j;
> -    int ret = 0;
> +    int n, j, ro, open_flags;
> +    int ret = 0, rw_ret = 0;
>       unsigned char sector[512];
> +    char filename[1024];
> +    BlockDriverState *bs_rw, *bs_ro;
>
>       if (!drv)
>           return -ENOMEDIUM;
> -
> -    if (bs->read_only) {
> -	return -EACCES;
> +
> +    if (!bs->backing_hd) {
> +        return -ENOTSUP;
>       }
>
> -    if (!bs->backing_hd) {
> -	return -ENOTSUP;
> +    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 (ro) {
> +        /* re-open as RW */
> +        bdrv_delete(bs->backing_hd);
> +        bs->backing_hd = NULL;
> +        bs_rw = bdrv_new("");
> +        rw_ret = bdrv_open2(bs_rw, filename, open_flags | BDRV_O_RDWR, NULL);
> +        if (rw_ret<  0) {
> +            bdrv_delete(bs_rw);
> +            /* try to re-open read-only */
> +            bs_ro = bdrv_new("");
> +            ret = bdrv_open2(bs_ro, filename, open_flags&  ~BDRV_O_RDWR, NULL);
> +            if (ret<  0) {
> +                bdrv_delete(bs_ro);
> +                /* drive not functional anymore */
> +                bs->drv = NULL;
> +                return ret;
> +            }
> +            bs->backing_hd = bs_ro;
> +            return rw_ret;
> +        }
> +        bs->backing_hd = bs_rw;
>       }
>
>       total_sectors = bdrv_getlength(bs)>>  BDRV_SECTOR_BITS;
> @@ -590,11 +628,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++;
>   	    }
> @@ -614,6 +654,25 @@ int bdrv_commit(BlockDriverState *bs)
>        */
>       if (bs->backing_hd)
>           bdrv_flush(bs->backing_hd);
> +
> +ro_cleanup:
> +
> +    if (ro) {
> +        /* re-open as RO */
> +        bdrv_delete(bs->backing_hd);
> +        bs->backing_hd = NULL;
> +        bs_ro = bdrv_new("");
> +        ret = bdrv_open2(bs_ro, filename, open_flags&  ~BDRV_O_RDWR, NULL);
> +        if (ret<  0) {
> +            bdrv_delete(bs_ro);
> +            /* drive not functional anymore */
> +            bs->drv = NULL;
> +            return ret;
> +        }
> +        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 930a5a4..50e1a0b 100644
> --- a/block_int.h
> +++ b/block_int.h
> @@ -130,6 +130,8 @@ 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, re-used for re-open */
>       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 */
>    

      reply	other threads:[~2010-02-19 21:48 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-02-14 11:39 [Qemu-devel] [PATCH v4 rebased] block: more read-only changes, related to backing files Naphtali Sprei
2010-02-19 21:48 ` Anthony Liguori [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4B7F0733.1060304@codemonkey.ws \
    --to=anthony@codemonkey.ws \
    --cc=kwolf@redhat.com \
    --cc=nsprei@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=sheng@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.