All of lore.kernel.org
 help / color / mirror / Atom feed
From: Max Reitz <mreitz@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Kevin Wolf" <kwolf@redhat.com>,
	"Benoît Canet" <benoit@irqsave.net>,
	"Stefan Hajnoczi" <stefanha@redhat.com>,
	"Max Reitz" <mreitz@redhat.com>
Subject: [Qemu-devel] [PATCH v4 7/8] block: Reuse success path from bdrv_open()
Date: Tue, 18 Feb 2014 18:33:11 +0100	[thread overview]
Message-ID: <1392744792-9512-8-git-send-email-mreitz@redhat.com> (raw)
In-Reply-To: <1392744792-9512-1-git-send-email-mreitz@redhat.com>

The fail and success paths of bdrv_file_open() may be further shortened
by reusing code already existent in bdrv_open(). This includes
bdrv_file_open() not taking the reference to options which allows the
removal of QDECREF(options) in that function.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
---
 block.c | 63 +++++++++++++++++++++++++++++----------------------------------
 1 file changed, 29 insertions(+), 34 deletions(-)

diff --git a/block.c b/block.c
index 7e50e7a..71ed977 100644
--- a/block.c
+++ b/block.c
@@ -955,13 +955,15 @@ free_and_fail:
 /*
  * Opens a file using a protocol (file, host_device, nbd, ...)
  *
- * options is a QDict of options to pass to the block drivers, or NULL for an
- * empty set of options. The reference to the QDict belongs to the block layer
- * after the call (even on failure), so if the caller intends to reuse the
- * dictionary, it needs to use QINCREF() before calling bdrv_file_open.
+ * options is an indirect pointer to a QDict of options to pass to the block
+ * drivers, or pointer to NULL for an empty set of options. If this function
+ * takes ownership of the QDict reference, it will set *options to NULL;
+ * otherwise, it will contain unused/unrecognized options after this function
+ * returns. Then, the caller is responsible for freeing it. If it intends to
+ * reuse the QDict, QINCREF() should be called beforehand.
  */
 static int bdrv_file_open(BlockDriverState *bs, const char *filename,
-                          QDict *options, int flags, Error **errp)
+                          QDict **options, int flags, Error **errp)
 {
     BlockDriver *drv;
     const char *drvname;
@@ -971,9 +973,9 @@ static int bdrv_file_open(BlockDriverState *bs, const char *filename,
 
     /* Fetch the file name from the options QDict if necessary */
     if (!filename) {
-        filename = qdict_get_try_str(options, "filename");
-    } else if (filename && !qdict_haskey(options, "filename")) {
-        qdict_put(options, "filename", qstring_from_str(filename));
+        filename = qdict_get_try_str(*options, "filename");
+    } else if (filename && !qdict_haskey(*options, "filename")) {
+        qdict_put(*options, "filename", qstring_from_str(filename));
         allow_protocol_prefix = true;
     } else {
         error_setg(errp, "Can't specify 'file' and 'filename' options at the "
@@ -983,13 +985,13 @@ static int bdrv_file_open(BlockDriverState *bs, const char *filename,
     }
 
     /* Find the right block driver */
-    drvname = qdict_get_try_str(options, "driver");
+    drvname = qdict_get_try_str(*options, "driver");
     if (drvname) {
         drv = bdrv_find_format(drvname);
         if (!drv) {
             error_setg(errp, "Unknown driver '%s'", drvname);
         }
-        qdict_del(options, "driver");
+        qdict_del(*options, "driver");
     } else if (filename) {
         drv = bdrv_find_protocol(filename, allow_protocol_prefix);
         if (!drv) {
@@ -1008,41 +1010,30 @@ static int bdrv_file_open(BlockDriverState *bs, const char *filename,
 
     /* Parse the filename and open it */
     if (drv->bdrv_parse_filename && filename) {
-        drv->bdrv_parse_filename(filename, options, &local_err);
+        drv->bdrv_parse_filename(filename, *options, &local_err);
         if (error_is_set(&local_err)) {
             error_propagate(errp, local_err);
             ret = -EINVAL;
             goto fail;
         }
-        qdict_del(options, "filename");
+        qdict_del(*options, "filename");
     }
 
     if (!drv->bdrv_file_open) {
-        ret = bdrv_open(&bs, filename, NULL, options, flags, drv, &local_err);
-        options = NULL;
+        ret = bdrv_open(&bs, filename, NULL, *options, flags, drv, &local_err);
+        *options = NULL;
     } else {
-        ret = bdrv_open_common(bs, NULL, options, flags, drv, &local_err);
+        ret = bdrv_open_common(bs, NULL, *options, flags, drv, &local_err);
     }
     if (ret < 0) {
         error_propagate(errp, local_err);
         goto fail;
     }
 
-    /* Check if any unknown options were used */
-    if (options && (qdict_size(options) != 0)) {
-        const QDictEntry *entry = qdict_first(options);
-        error_setg(errp, "Block protocol '%s' doesn't support the option '%s'",
-                   drv->format_name, entry->key);
-        ret = -EINVAL;
-        goto fail;
-    }
-    QDECREF(options);
-
     bs->growable = 1;
     return 0;
 
 fail:
-    QDECREF(options);
     return ret;
 }
 
@@ -1253,12 +1244,10 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
 
     if (flags & BDRV_O_PROTOCOL) {
         assert(!drv);
-        ret = bdrv_file_open(bs, filename, options, flags & ~BDRV_O_PROTOCOL,
+        ret = bdrv_file_open(bs, filename, &options, flags & ~BDRV_O_PROTOCOL,
                              &local_err);
-        options = NULL;
         if (!ret) {
-            *pbs = bs;
-            return 0;
+            goto done;
         } else if (bs->drv) {
             goto close_and_fail;
         } else {
@@ -1395,12 +1384,18 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
         }
     }
 
+done:
     /* Check if any unknown options were used */
-    if (qdict_size(options) != 0) {
+    if (options && (qdict_size(options) != 0)) {
         const QDictEntry *entry = qdict_first(options);
-        error_setg(errp, "Block format '%s' used by device '%s' doesn't "
-                   "support the option '%s'", drv->format_name, bs->device_name,
-                   entry->key);
+        if (flags & BDRV_O_PROTOCOL) {
+            error_setg(errp, "Block protocol '%s' doesn't support the option "
+                       "'%s'", drv->format_name, entry->key);
+        } else {
+            error_setg(errp, "Block format '%s' used by device '%s' doesn't "
+                       "support the option '%s'", drv->format_name,
+                       bs->device_name, entry->key);
+        }
 
         ret = -EINVAL;
         goto close_and_fail;
-- 
1.8.5.4

  parent reply	other threads:[~2014-02-18 17:34 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-18 17:33 [Qemu-devel] [PATCH v4 0/8] block: Integrate bdrv_file_open() into bdrv_open() Max Reitz
2014-02-18 17:33 ` [Qemu-devel] [PATCH v4 1/8] block: Change BDS parameter of bdrv_open() to ** Max Reitz
2014-02-18 17:33 ` [Qemu-devel] [PATCH v4 2/8] block: Add reference parameter to bdrv_open() Max Reitz
2014-02-18 17:33 ` [Qemu-devel] [PATCH v4 3/8] block: Make bdrv_file_open() static Max Reitz
2014-02-18 17:33 ` [Qemu-devel] [PATCH v4 4/8] block: Reuse reference handling from bdrv_open() Max Reitz
2014-02-18 17:33 ` [Qemu-devel] [PATCH v4 5/8] block: Remove bdrv_new() from bdrv_file_open() Max Reitz
2014-02-18 17:33 ` [Qemu-devel] [PATCH v4 6/8] block: Handle bs->options in bdrv_open() only Max Reitz
2014-02-18 17:33 ` Max Reitz [this message]
2014-02-18 17:33 ` [Qemu-devel] [PATCH v4 8/8] block: Remove bdrv_open_image()'s force_raw option Max Reitz
2014-02-19  9:47 ` [Qemu-devel] [PATCH v4 0/8] block: Integrate bdrv_file_open() into bdrv_open() Kevin Wolf

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=1392744792-9512-8-git-send-email-mreitz@redhat.com \
    --to=mreitz@redhat.com \
    --cc=benoit@irqsave.net \
    --cc=kwolf@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.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.