raw-posix driver changes for bdrv_reopen_xx functions to safely reopen image files. Reopening of image files while changing hostcache dynamically, is handled here.
Signed-off-by: Supriya Kannery <supri...@linux.vnet.ibm.com> Index: qemu/block/raw.c =================================================================== --- qemu.orig/block/raw.c +++ qemu/block/raw.c @@ -9,6 +9,24 @@ static int raw_open(BlockDriverState *bs return 0; } +static int raw_reopen_prepare(BlockDriverState *bs, BDRVReopenState **prs, + int flags) +{ + return bdrv_reopen_prepare(bs->file, prs, flags); +} + +static void raw_reopen_commit(BlockDriverState *bs, BDRVReopenState *rs, + int flags) +{ + bdrv_reopen_commit(bs->file, rs, flags); + bs->open_flags = bs->file->open_flags; +} + +static void raw_reopen_abort(BlockDriverState *bs, BDRVReopenState *rs) +{ + bdrv_reopen_abort(bs->file, rs); +} + static int coroutine_fn raw_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) { @@ -107,7 +125,10 @@ static BlockDriver bdrv_raw = { /* It's really 0, but we need to make g_malloc() happy */ .instance_size = 1, - + .bdrv_reopen_prepare + = raw_reopen_prepare, + .bdrv_reopen_commit = raw_reopen_commit, + .bdrv_reopen_abort = raw_reopen_abort, .bdrv_open = raw_open, .bdrv_close = raw_close, Index: qemu/block/raw-posix.c =================================================================== --- qemu.orig/block/raw-posix.c +++ qemu/block/raw-posix.c @@ -279,6 +279,60 @@ static int raw_open(BlockDriverState *bs return raw_open_common(bs, filename, flags, 0); } +static int raw_reopen_prepare(BlockDriverState *bs, BDRVReopenState **prs, + int flags) +{ + BDRVReopenState *raw_rs = g_malloc0(sizeof(BDRVReopenState)); + BDRVRawState *s = bs->opaque; + + raw_rs->bs = bs; + raw_rs->reopen_flags = s->open_flags; + raw_rs->reopen_fd = -1; + *prs = raw_rs; + int ret = 0; + + /* If only O_DIRECT to be toggled, use fcntl */ + if (!((bs->open_flags & ~BDRV_O_NOCACHE) ^ + (flags & ~BDRV_O_NOCACHE))) { + raw_rs->reopen_fd = dup(s->fd); + if (raw_rs->reopen_fd <= 0) { + return -1; + } + if ((flags & BDRV_O_NOCACHE)) { + raw_rs->reopen_flags |= O_DIRECT; + } else { + raw_rs->reopen_flags &= ~O_DIRECT; + } + ret = fcntl_setfl(raw_rs->reopen_fd, raw_rs->reopen_flags); + } + + /* TBD: Handle O_DSYNC and other flags */ + + return ret; +} + +static void raw_reopen_commit(BlockDriverState *bs, BDRVReopenState *rs, + int flags) +{ + BDRVRawState *s = bs->opaque; + + /* Set new flags, so replace old fd with new one */ + close(s->fd); + s->fd = rs->reopen_fd; + s->open_flags = rs->reopen_flags; + bs->open_flags = flags; + g_free(rs); + +} + +static void raw_reopen_abort(BlockDriverState *bs, BDRVReopenState *rs) +{ + if (rs->reopen_fd != -1) { + close(rs->reopen_fd); + } + g_free(rs); +} + /* XXX: use host sector size if necessary with: #ifdef DIOCGSECTORSIZE { @@ -631,6 +685,9 @@ static BlockDriver bdrv_file = { .instance_size = sizeof(BDRVRawState), .bdrv_probe = NULL, /* no probe for protocols */ .bdrv_file_open = raw_open, + .bdrv_reopen_prepare = raw_reopen_prepare, + .bdrv_reopen_commit = raw_reopen_commit, + .bdrv_reopen_abort = raw_reopen_abort, .bdrv_close = raw_close, .bdrv_create = raw_create, .bdrv_co_discard = raw_co_discard,