From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48320) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aqGod-0006WP-EC for qemu-devel@nongnu.org; Wed, 13 Apr 2016 05:10:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aqGoZ-0001n1-AF for qemu-devel@nongnu.org; Wed, 13 Apr 2016 05:10:27 -0400 From: Fam Zheng Date: Wed, 13 Apr 2016 17:09:53 +0800 Message-Id: <1460538604-12132-5-git-send-email-famz@redhat.com> In-Reply-To: <1460538604-12132-1-git-send-email-famz@redhat.com> References: <1460538604-12132-1-git-send-email-famz@redhat.com> Subject: [Qemu-devel] [PATCH for-2.7 04/15] block: Introduce image file locking interface List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Max Reitz , Jeff Cody , Markus Armbruster , Eric Blake , John Snow , qemu-block@nongnu.org, berrange@redhat.com, pbonzini@redhat.com, den@openvz.org Block drivers can implement this new operation .bdrv_lockf to actually lock the image in the protocol specific way. Signed-off-by: Fam Zheng --- block.c | 25 +++++++++++++++++++++++++ include/block/block.h | 8 ++++++++ include/block/block_int.h | 5 +++++ 3 files changed, 38 insertions(+) diff --git a/block.c b/block.c index d4939b4..7f6e903 100644 --- a/block.c +++ b/block.c @@ -995,6 +995,15 @@ static int bdrv_open_common(BlockDriverState *bs, BdrvChild *file, goto free_and_fail; } + if (!(open_flags & BDRV_O_NO_LOCK)) { + BdrvLockfCmd cmd = open_flags & BDRV_O_RDWR ? BDRV_LOCKF_RWLOCK : + BDRV_LOCKF_ROLOCK; + ret = bdrv_lockf(bs, cmd, errp); + if (ret != 0 && ret != -ENOTSUP) { + goto free_and_fail; + } + } + ret = refresh_total_sectors(bs, bs->total_sectors); if (ret < 0) { error_setg_errno(errp, -ret, "Could not refresh total sector count"); @@ -2141,6 +2150,10 @@ static void bdrv_close(BlockDriverState *bs) blk_dev_change_media_cb(bs->blk, false); } + if (bs->drv && !(bs->open_flags & BDRV_O_NO_LOCK)) { + bdrv_lockf(bs, BDRV_LOCKF_UNLOCK, &error_abort); + } + if (bs->drv) { BdrvChild *child, *next; @@ -3981,3 +3994,15 @@ void bdrv_refresh_filename(BlockDriverState *bs) QDECREF(json); } } + +int bdrv_lockf(BlockDriverState *bs, BdrvLockfCmd cmd, Error **errp) +{ + if (!bs->drv) { + error_setg(errp, "No medium to lock"); + return -ENOMEDIUM; + } else if (!bs->drv->bdrv_lockf) { + return -ENOTSUP; + } else { + return bs->drv->bdrv_lockf(bs, cmd, errp); + } +} diff --git a/include/block/block.h b/include/block/block.h index b803597..36e1271 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -542,4 +542,12 @@ void bdrv_drained_begin(BlockDriverState *bs); */ void bdrv_drained_end(BlockDriverState *bs); +typedef enum { + BDRV_LOCKF_RWLOCK, + BDRV_LOCKF_ROLOCK, + BDRV_LOCKF_UNLOCK, +} BdrvLockfCmd; + +int bdrv_lockf(BlockDriverState *bs, BdrvLockfCmd cmd, Error **errp); + #endif diff --git a/include/block/block_int.h b/include/block/block_int.h index 10d8759..0a79eba 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -317,6 +317,11 @@ struct BlockDriver { */ void (*bdrv_drain)(BlockDriverState *bs); + /** + * Lock/unlock the image. + */ + int (*bdrv_lockf)(BlockDriverState *bs, BdrvLockfCmd cmd, Error **errp); + QLIST_ENTRY(BlockDriver) list; }; -- 2.8.0