From: Olga Krishtal <okrish...@virtuozzo.com>

To lock the image file flock (LockFileEx) is used.
We lock file handle/descriptor. If lock is failed -
an error is returned.

In win32 realization we can lock reagion of bytes within the file.
For this reason we at first have to get file size and only than lock it.

Signed-off-by: Olga Krishtal <okrish...@virtuozzo.com>
Signed-off-by: Denis V. Lunev <d...@openvz.org>
CC: Kevin Wolf <kw...@redhat.com>
CC: Max Reitz <mre...@redhat.com>
CC: Eric Blake <ebl...@redhat.com>
CC: Fam Zheng <f...@redhat.com>
---
 block/raw-posix.c | 15 +++++++++++++++
 block/raw-win32.c | 19 +++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 076d070..6226a5c 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -33,6 +33,7 @@
 #include "raw-aio.h"
 #include "qapi/util.h"
 #include "qapi/qmp/qstring.h"
+#include <sys/file.h>
 
 #if defined(__APPLE__) && (__MACH__)
 #include <paths.h>
@@ -576,6 +577,19 @@ fail:
     return ret;
 }
 
+static int raw_lock_image(BlockDriverState *bs, BdrvLockImage lock)
+{
+    int ret;
+    if (lock != BDRV_LOCK_IMAGE_LOCKFILE) {
+        return -ENOTSUP;
+    }
+    ret = flock(((BDRVRawState *)(bs->opaque))->fd, LOCK_EX|LOCK_NB);
+    if (ret != 0) {
+        return -ret;
+    }
+    return ret;
+}
+
 static int raw_open(BlockDriverState *bs, QDict *options, int flags,
                     Error **errp)
 {
@@ -1946,6 +1960,7 @@ BlockDriver bdrv_file = {
     .bdrv_co_get_block_status = raw_co_get_block_status,
     .bdrv_co_write_zeroes = raw_co_write_zeroes,
 
+    .bdrv_lock_image = raw_lock_image,
     .bdrv_aio_readv = raw_aio_readv,
     .bdrv_aio_writev = raw_aio_writev,
     .bdrv_aio_flush = raw_aio_flush,
diff --git a/block/raw-win32.c b/block/raw-win32.c
index 2d0907a..d05160a 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -370,6 +370,24 @@ fail:
     return ret;
 }
 
+static int raw_lock_image(BlockDriverState *bs, BdrvLockImage lock)
+{
+    DWORD size_high = 0, size_low = 0;
+    BDRVRawState *s = bs->opaque;
+    if (lock != BDRV_LOCK_IMAGE_LOCKFILE) {
+        return -ENOTSUP;
+    }
+    size_low = GetFileSize(s->hfile, &size_high);
+    if (GetLastError() != 0) {
+        return -EINVAL;
+    }
+    if (!LockFileEx(s->hfile, 
LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
+                        0, size_high, size_low, NULL)) {
+            return -EINVAL;
+    }
+    return 0;
+}
+
 static BlockAIOCB *raw_aio_readv(BlockDriverState *bs,
                          int64_t sector_num, QEMUIOVector *qiov, int 
nb_sectors,
                          BlockCompletionFunc *cb, void *opaque)
@@ -552,6 +570,7 @@ BlockDriver bdrv_file = {
     .bdrv_create        = raw_create,
     .bdrv_has_zero_init = bdrv_has_zero_init_1,
 
+    .bdrv_lock_image    = raw_lock_image,
     .bdrv_aio_readv     = raw_aio_readv,
     .bdrv_aio_writev    = raw_aio_writev,
     .bdrv_aio_flush     = raw_aio_flush,
-- 
2.1.4


Reply via email to