[pve-devel] [PATCH 22/31] PVE: [Up+Config] file-posix: make locking optiono on create

Dietmar Maurer dietmar at proxmox.com
Fri Mar 6 12:30:02 CET 2020


From: Wolfgang Bumiller <w.bumiller at proxmox.com>

Otherwise creating images on nfs/cifs can be problematic.

Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
---
 block/file-posix.c   | 61 +++++++++++++++++++++++++++++---------------
 qapi/block-core.json |  3 ++-
 2 files changed, 43 insertions(+), 21 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index 44b49265ae..0722b0f529 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -2250,6 +2250,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
     int fd;
     uint64_t perm, shared;
     int result = 0;
+    bool locked = false;
 
     /* Validate options and set default values */
     assert(options->driver == BLOCKDEV_DRIVER_FILE);
@@ -2283,19 +2284,22 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
     perm = BLK_PERM_WRITE | BLK_PERM_RESIZE;
     shared = BLK_PERM_ALL & ~BLK_PERM_RESIZE;
 
-    /* Step one: Take locks */
-    result = raw_apply_lock_bytes(NULL, fd, perm, ~shared, false, errp);
-    if (result < 0) {
-        goto out_close;
-    }
+    if (file_opts->locking != ON_OFF_AUTO_OFF) {
+        /* Step one: Take locks */
+        result = raw_apply_lock_bytes(NULL, fd, perm, ~shared, false, errp);
+        if (result < 0) {
+            goto out_close;
+        }
+        locked = true;
 
-    /* Step two: Check that nobody else has taken conflicting locks */
-    result = raw_check_lock_bytes(fd, perm, shared, errp);
-    if (result < 0) {
-        error_append_hint(errp,
-                          "Is another process using the image [%s]?\n",
-                          file_opts->filename);
-        goto out_unlock;
+        /* Step two: Check that nobody else has taken conflicting locks */
+        result = raw_check_lock_bytes(fd, perm, shared, errp);
+        if (result < 0) {
+            error_append_hint(errp,
+                              "Is another process using the image [%s]?\n",
+                              file_opts->filename);
+            goto out_unlock;
+        }
     }
 
     /* Clear the file by truncating it to 0 */
@@ -2328,13 +2332,15 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
     }
 
 out_unlock:
-    raw_apply_lock_bytes(NULL, fd, 0, 0, true, &local_err);
-    if (local_err) {
-        /* The above call should not fail, and if it does, that does
-         * not mean the whole creation operation has failed.  So
-         * report it the user for their convenience, but do not report
-         * it to the caller. */
-        warn_report_err(local_err);
+    if (locked) {
+        raw_apply_lock_bytes(NULL, fd, 0, 0, true, &local_err);
+        if (local_err) {
+            /* The above call should not fail, and if it does, that does
+             * not mean the whole creation operation has failed.  So
+             * report it the user for their convenience, but do not report
+             * it to the caller. */
+            warn_report_err(local_err);
+        }
     }
 
 out_close:
@@ -2355,6 +2361,7 @@ static int coroutine_fn raw_co_create_opts(const char *filename, QemuOpts *opts,
     PreallocMode prealloc;
     char *buf = NULL;
     Error *local_err = NULL;
+    OnOffAuto locking;
 
     /* Skip file: protocol prefix */
     strstart(filename, "file:", &filename);
@@ -2372,6 +2379,18 @@ static int coroutine_fn raw_co_create_opts(const char *filename, QemuOpts *opts,
         return -EINVAL;
     }
 
+    locking = qapi_enum_parse(&OnOffAuto_lookup,
+                              qemu_opt_get(opts, "locking"),
+                              ON_OFF_AUTO_AUTO, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return -EINVAL;
+    }
+
+    if (locking == ON_OFF_AUTO_AUTO) {
+        locking = ON_OFF_AUTO_OFF;
+    }
+
     options = (BlockdevCreateOptions) {
         .driver     = BLOCKDEV_DRIVER_FILE,
         .u.file     = {
@@ -2381,6 +2400,8 @@ static int coroutine_fn raw_co_create_opts(const char *filename, QemuOpts *opts,
             .preallocation      = prealloc,
             .has_nocow          = true,
             .nocow              = nocow,
+            .has_locking        = true,
+            .locking            = locking,
         },
     };
     return raw_co_create(&options, errp);
@@ -2901,7 +2922,7 @@ static int raw_check_perm(BlockDriverState *bs, uint64_t perm, uint64_t shared,
     }
 
     /* Copy locks to the new fd */
-    if (s->perm_change_fd) {
+    if (s->use_lock && s->perm_change_fd) {
         ret = raw_apply_lock_bytes(NULL, s->perm_change_fd, perm, ~shared,
                                    false, errp);
         if (ret < 0) {
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 0cf68fea14..783a868eb2 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -4259,7 +4259,8 @@
   'data': { 'filename':         'str',
             'size':             'size',
             '*preallocation':   'PreallocMode',
-            '*nocow':           'bool' } }
+            '*nocow':           'bool',
+            '*locking':         'OnOffAuto' } }
 
 ##
 # @BlockdevCreateOptionsGluster:
-- 
2.20.1




More information about the pve-devel mailing list