aboutsummaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/backup.c5
-rw-r--r--block/commit.c10
-rw-r--r--block/gluster.c124
-rw-r--r--block/mirror.c30
-rw-r--r--block/rbd.c25
-rw-r--r--block/replication.c14
-rw-r--r--block/stream.c9
-rw-r--r--block/trace-events5
8 files changed, 152 insertions, 70 deletions
diff --git a/block/backup.c b/block/backup.c
index 44c7ff3d16..7b5d8a3757 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -16,7 +16,7 @@
#include "trace.h"
#include "block/block.h"
#include "block/block_int.h"
-#include "block/blockjob.h"
+#include "block/blockjob_int.h"
#include "block/block_backup.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
@@ -543,6 +543,7 @@ void backup_start(const char *job_id, BlockDriverState *bs,
bool compress,
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
+ int creation_flags,
BlockCompletionFunc *cb, void *opaque,
BlockJobTxn *txn, Error **errp)
{
@@ -612,7 +613,7 @@ void backup_start(const char *job_id, BlockDriverState *bs,
}
job = block_job_create(job_id, &backup_job_driver, bs, speed,
- cb, opaque, errp);
+ creation_flags, cb, opaque, errp);
if (!job) {
goto error;
}
diff --git a/block/commit.c b/block/commit.c
index a5e17f610f..e1eda8908b 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -15,7 +15,7 @@
#include "qemu/osdep.h"
#include "trace.h"
#include "block/block_int.h"
-#include "block/blockjob.h"
+#include "block/blockjob_int.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/ratelimit.h"
@@ -209,8 +209,8 @@ static const BlockJobDriver commit_job_driver = {
void commit_start(const char *job_id, BlockDriverState *bs,
BlockDriverState *base, BlockDriverState *top, int64_t speed,
- BlockdevOnError on_error, BlockCompletionFunc *cb,
- void *opaque, const char *backing_file_str, Error **errp)
+ BlockdevOnError on_error, const char *backing_file_str,
+ Error **errp)
{
CommitBlockJob *s;
BlockReopenQueue *reopen_queue = NULL;
@@ -234,7 +234,7 @@ void commit_start(const char *job_id, BlockDriverState *bs,
}
s = block_job_create(job_id, &commit_job_driver, bs, speed,
- cb, opaque, errp);
+ BLOCK_JOB_DEFAULT, NULL, NULL, errp);
if (!s) {
return;
}
@@ -290,7 +290,7 @@ void commit_start(const char *job_id, BlockDriverState *bs,
s->on_error = on_error;
s->common.co = qemu_coroutine_create(commit_run, s);
- trace_commit_start(bs, base, top, s, s->common.co, opaque);
+ trace_commit_start(bs, base, top, s, s->common.co);
qemu_coroutine_enter(s->common.co);
}
diff --git a/block/gluster.c b/block/gluster.c
index af76d7d59a..0ce15f7adc 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -14,6 +14,7 @@
#include "qapi/qmp/qerror.h"
#include "qemu/uri.h"
#include "qemu/error-report.h"
+#include "qemu/cutils.h"
#define GLUSTER_OPT_FILENAME "filename"
#define GLUSTER_OPT_VOLUME "volume"
@@ -56,6 +57,19 @@ typedef struct BDRVGlusterReopenState {
} BDRVGlusterReopenState;
+typedef struct GlfsPreopened {
+ char *volume;
+ glfs_t *fs;
+ int ref;
+} GlfsPreopened;
+
+typedef struct ListElement {
+ QLIST_ENTRY(ListElement) list;
+ GlfsPreopened saved;
+} ListElement;
+
+static QLIST_HEAD(glfs_list, ListElement) glfs_list;
+
static QemuOptsList qemu_gluster_create_opts = {
.name = "qemu-gluster-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(qemu_gluster_create_opts.head),
@@ -172,7 +186,7 @@ static QemuOptsList runtime_tcp_opts = {
},
{
.name = GLUSTER_OPT_PORT,
- .type = QEMU_OPT_NUMBER,
+ .type = QEMU_OPT_STRING,
.help = "port number on which glusterd is listening (default 24007)",
},
{
@@ -194,6 +208,57 @@ static QemuOptsList runtime_tcp_opts = {
},
};
+static void glfs_set_preopened(const char *volume, glfs_t *fs)
+{
+ ListElement *entry = NULL;
+
+ entry = g_new(ListElement, 1);
+
+ entry->saved.volume = g_strdup(volume);
+
+ entry->saved.fs = fs;
+ entry->saved.ref = 1;
+
+ QLIST_INSERT_HEAD(&glfs_list, entry, list);
+}
+
+static glfs_t *glfs_find_preopened(const char *volume)
+{
+ ListElement *entry = NULL;
+
+ QLIST_FOREACH(entry, &glfs_list, list) {
+ if (strcmp(entry->saved.volume, volume) == 0) {
+ entry->saved.ref++;
+ return entry->saved.fs;
+ }
+ }
+
+ return NULL;
+}
+
+static void glfs_clear_preopened(glfs_t *fs)
+{
+ ListElement *entry = NULL;
+
+ if (fs == NULL) {
+ return;
+ }
+
+ QLIST_FOREACH(entry, &glfs_list, list) {
+ if (entry->saved.fs == fs) {
+ if (--entry->saved.ref) {
+ return;
+ }
+
+ QLIST_REMOVE(entry, list);
+
+ glfs_fini(entry->saved.fs);
+ g_free(entry->saved.volume);
+ g_free(entry);
+ }
+ }
+}
+
static int parse_volume_options(BlockdevOptionsGluster *gconf, char *path)
{
char *p, *q;
@@ -330,22 +395,37 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
int ret;
int old_errno;
GlusterServerList *server;
+ unsigned long long port;
+
+ glfs = glfs_find_preopened(gconf->volume);
+ if (glfs) {
+ return glfs;
+ }
glfs = glfs_new(gconf->volume);
if (!glfs) {
goto out;
}
+ glfs_set_preopened(gconf->volume, glfs);
+
for (server = gconf->server; server; server = server->next) {
if (server->value->type == GLUSTER_TRANSPORT_UNIX) {
ret = glfs_set_volfile_server(glfs,
GlusterTransport_lookup[server->value->type],
server->value->u.q_unix.path, 0);
} else {
+ if (parse_uint_full(server->value->u.tcp.port, &port, 10) < 0 ||
+ port > 65535) {
+ error_setg(errp, "'%s' is not a valid port number",
+ server->value->u.tcp.port);
+ errno = EINVAL;
+ goto out;
+ }
ret = glfs_set_volfile_server(glfs,
GlusterTransport_lookup[server->value->type],
server->value->u.tcp.host,
- atoi(server->value->u.tcp.port));
+ (int)port);
}
if (ret < 0) {
@@ -387,7 +467,7 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
out:
if (glfs) {
old_errno = errno;
- glfs_fini(glfs);
+ glfs_clear_preopened(glfs);
errno = old_errno;
}
return NULL;
@@ -668,7 +748,10 @@ static void qemu_gluster_parse_flags(int bdrv_flags, int *open_flags)
*/
static bool qemu_gluster_test_seek(struct glfs_fd *fd)
{
- off_t ret, eof;
+ off_t ret = 0;
+
+#if defined SEEK_HOLE && defined SEEK_DATA
+ off_t eof;
eof = glfs_lseek(fd, 0, SEEK_END);
if (eof < 0) {
@@ -678,6 +761,8 @@ static bool qemu_gluster_test_seek(struct glfs_fd *fd)
/* this should always fail with ENXIO if SEEK_DATA is supported */
ret = glfs_lseek(fd, eof, SEEK_DATA);
+#endif
+
return (ret < 0) && (errno == ENXIO);
}
@@ -762,9 +847,9 @@ out:
if (s->fd) {
glfs_close(s->fd);
}
- if (s->glfs) {
- glfs_fini(s->glfs);
- }
+
+ glfs_clear_preopened(s->glfs);
+
return ret;
}
@@ -831,9 +916,8 @@ static void qemu_gluster_reopen_commit(BDRVReopenState *state)
if (s->fd) {
glfs_close(s->fd);
}
- if (s->glfs) {
- glfs_fini(s->glfs);
- }
+
+ glfs_clear_preopened(s->glfs);
/* use the newly opened image / connection */
s->fd = reop_s->fd;
@@ -858,9 +942,7 @@ static void qemu_gluster_reopen_abort(BDRVReopenState *state)
glfs_close(reop_s->fd);
}
- if (reop_s->glfs) {
- glfs_fini(reop_s->glfs);
- }
+ glfs_clear_preopened(reop_s->glfs);
g_free(state->opaque);
state->opaque = NULL;
@@ -984,9 +1066,7 @@ static int qemu_gluster_create(const char *filename,
out:
g_free(tmp);
qapi_free_BlockdevOptionsGluster(gconf);
- if (glfs) {
- glfs_fini(glfs);
- }
+ glfs_clear_preopened(glfs);
return ret;
}
@@ -1059,7 +1139,7 @@ static void qemu_gluster_close(BlockDriverState *bs)
glfs_close(s->fd);
s->fd = NULL;
}
- glfs_fini(s->glfs);
+ glfs_clear_preopened(s->glfs);
}
static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs)
@@ -1178,12 +1258,14 @@ static int find_allocation(BlockDriverState *bs, off_t start,
off_t *data, off_t *hole)
{
BDRVGlusterState *s = bs->opaque;
- off_t offs;
if (!s->supports_seek_data) {
- return -ENOTSUP;
+ goto exit;
}
+#if defined SEEK_HOLE && defined SEEK_DATA
+ off_t offs;
+
/*
* SEEK_DATA cases:
* D1. offs == start: start is in data
@@ -1247,6 +1329,10 @@ static int find_allocation(BlockDriverState *bs, off_t start,
/* D1 and H1 */
return -EBUSY;
+#endif
+
+exit:
+ return -ENOTSUP;
}
/*
diff --git a/block/mirror.c b/block/mirror.c
index 7e99f3a880..b2c1fb855b 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -13,7 +13,7 @@
#include "qemu/osdep.h"
#include "trace.h"
-#include "block/blockjob.h"
+#include "block/blockjob_int.h"
#include "block/block_int.h"
#include "sysemu/block-backend.h"
#include "qapi/error.h"
@@ -937,9 +937,9 @@ static const BlockJobDriver commit_active_job_driver = {
};
static void mirror_start_job(const char *job_id, BlockDriverState *bs,
- BlockDriverState *target, const char *replaces,
- int64_t speed, uint32_t granularity,
- int64_t buf_size,
+ int creation_flags, BlockDriverState *target,
+ const char *replaces, int64_t speed,
+ uint32_t granularity, int64_t buf_size,
BlockMirrorBackingMode backing_mode,
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
@@ -967,7 +967,8 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
buf_size = DEFAULT_MIRROR_BUF_SIZE;
}
- s = block_job_create(job_id, driver, bs, speed, cb, opaque, errp);
+ s = block_job_create(job_id, driver, bs, speed, creation_flags,
+ cb, opaque, errp);
if (!s) {
return;
}
@@ -1017,9 +1018,7 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
- bool unmap,
- BlockCompletionFunc *cb,
- void *opaque, Error **errp)
+ bool unmap, Error **errp)
{
bool is_none_mode;
BlockDriverState *base;
@@ -1030,17 +1029,16 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
}
is_none_mode = mode == MIRROR_SYNC_MODE_NONE;
base = mode == MIRROR_SYNC_MODE_TOP ? backing_bs(bs) : NULL;
- mirror_start_job(job_id, bs, target, replaces,
+ mirror_start_job(job_id, bs, BLOCK_JOB_DEFAULT, target, replaces,
speed, granularity, buf_size, backing_mode,
- on_source_error, on_target_error, unmap, cb, opaque, errp,
+ on_source_error, on_target_error, unmap, NULL, NULL, errp,
&mirror_job_driver, is_none_mode, base, false);
}
void commit_active_start(const char *job_id, BlockDriverState *bs,
- BlockDriverState *base, int64_t speed,
- BlockdevOnError on_error,
- BlockCompletionFunc *cb,
- void *opaque, Error **errp,
+ BlockDriverState *base, int creation_flags,
+ int64_t speed, BlockdevOnError on_error,
+ BlockCompletionFunc *cb, void *opaque, Error **errp,
bool auto_complete)
{
int64_t length, base_length;
@@ -1079,9 +1077,9 @@ void commit_active_start(const char *job_id, BlockDriverState *bs,
}
}
- mirror_start_job(job_id, bs, base, NULL, speed, 0, 0,
+ mirror_start_job(job_id, bs, creation_flags, base, NULL, speed, 0, 0,
MIRROR_LEAVE_BACKING_CHAIN,
- on_error, on_error, false, cb, opaque, &local_err,
+ on_error, on_error, true, cb, opaque, &local_err,
&commit_active_job_driver, false, base, auto_complete);
if (local_err) {
error_propagate(errp, local_err);
diff --git a/block/rbd.c b/block/rbd.c
index f6e1d4bc11..a57b3e3c5d 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -365,45 +365,44 @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
rados_conf_read_file(cluster, NULL);
} else if (conf[0] != '\0' &&
qemu_rbd_set_conf(cluster, conf, true, &local_err) < 0) {
- rados_shutdown(cluster);
error_propagate(errp, local_err);
- return -EIO;
+ ret = -EIO;
+ goto shutdown;
}
if (conf[0] != '\0' &&
qemu_rbd_set_conf(cluster, conf, false, &local_err) < 0) {
- rados_shutdown(cluster);
error_propagate(errp, local_err);
- return -EIO;
+ ret = -EIO;
+ goto shutdown;
}
if (qemu_rbd_set_auth(cluster, secretid, errp) < 0) {
- rados_shutdown(cluster);
- return -EIO;
+ ret = -EIO;
+ goto shutdown;
}
ret = rados_connect(cluster);
if (ret < 0) {
error_setg_errno(errp, -ret, "error connecting");
- rados_shutdown(cluster);
- return ret;
+ goto shutdown;
}
ret = rados_ioctx_create(cluster, pool, &io_ctx);
if (ret < 0) {
error_setg_errno(errp, -ret, "error opening pool %s", pool);
- rados_shutdown(cluster);
- return ret;
+ goto shutdown;
}
ret = rbd_create(io_ctx, name, bytes, &obj_order);
- rados_ioctx_destroy(io_ctx);
- rados_shutdown(cluster);
if (ret < 0) {
error_setg_errno(errp, -ret, "error rbd create");
- return ret;
}
+ rados_ioctx_destroy(io_ctx);
+
+shutdown:
+ rados_shutdown(cluster);
return ret;
}
diff --git a/block/replication.c b/block/replication.c
index 02aeaaf7d0..d5e2b0f497 100644
--- a/block/replication.c
+++ b/block/replication.c
@@ -508,10 +508,11 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
bdrv_op_block_all(top_bs, s->blocker);
bdrv_op_unblock(top_bs, BLOCK_OP_TYPE_DATAPLANE, s->blocker);
- backup_start("replication-backup", s->secondary_disk->bs,
- s->hidden_disk->bs, 0, MIRROR_SYNC_MODE_NONE, NULL, false,
+ backup_start(NULL, s->secondary_disk->bs, s->hidden_disk->bs, 0,
+ MIRROR_SYNC_MODE_NONE, NULL, false,
BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
- backup_job_completed, bs, NULL, &local_err);
+ BLOCK_JOB_INTERNAL, backup_job_completed, bs,
+ NULL, &local_err);
if (local_err) {
error_propagate(errp, local_err);
backup_job_cleanup(bs);
@@ -633,10 +634,9 @@ static void replication_stop(ReplicationState *rs, bool failover, Error **errp)
}
s->replication_state = BLOCK_REPLICATION_FAILOVER;
- commit_active_start("replication-commit", s->active_disk->bs,
- s->secondary_disk->bs, 0, BLOCKDEV_ON_ERROR_REPORT,
- replication_done,
- bs, errp, true);
+ commit_active_start(NULL, s->active_disk->bs, s->secondary_disk->bs,
+ BLOCK_JOB_INTERNAL, 0, BLOCKDEV_ON_ERROR_REPORT,
+ replication_done, bs, errp, true);
break;
default:
aio_context_release(aio_context);
diff --git a/block/stream.c b/block/stream.c
index b8ab89a105..b05856bd65 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -14,7 +14,7 @@
#include "qemu/osdep.h"
#include "trace.h"
#include "block/block_int.h"
-#include "block/blockjob.h"
+#include "block/blockjob_int.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/ratelimit.h"
@@ -222,15 +222,14 @@ static const BlockJobDriver stream_job_driver = {
void stream_start(const char *job_id, BlockDriverState *bs,
BlockDriverState *base, const char *backing_file_str,
- int64_t speed, BlockdevOnError on_error,
- BlockCompletionFunc *cb, void *opaque, Error **errp)
+ int64_t speed, BlockdevOnError on_error, Error **errp)
{
StreamBlockJob *s;
BlockDriverState *iter;
int orig_bs_flags;
s = block_job_create(job_id, &stream_job_driver, bs, speed,
- cb, opaque, errp);
+ BLOCK_JOB_DEFAULT, NULL, NULL, errp);
if (!s) {
return;
}
@@ -256,6 +255,6 @@ void stream_start(const char *job_id, BlockDriverState *bs,
s->on_error = on_error;
s->common.co = qemu_coroutine_create(stream_run, s);
- trace_stream_start(bs, base, s, s->common.co, opaque);
+ trace_stream_start(bs, base, s, s->common.co);
qemu_coroutine_enter(s->common.co);
}
diff --git a/block/trace-events b/block/trace-events
index aff8a9674d..882c9034c2 100644
--- a/block/trace-events
+++ b/block/trace-events
@@ -19,11 +19,11 @@ bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned int bytes, int64_t c
# block/stream.c
stream_one_iteration(void *s, int64_t sector_num, int nb_sectors, int is_allocated) "s %p sector_num %"PRId64" nb_sectors %d is_allocated %d"
-stream_start(void *bs, void *base, void *s, void *co, void *opaque) "bs %p base %p s %p co %p opaque %p"
+stream_start(void *bs, void *base, void *s, void *co) "bs %p base %p s %p co %p"
# block/commit.c
commit_one_iteration(void *s, int64_t sector_num, int nb_sectors, int is_allocated) "s %p sector_num %"PRId64" nb_sectors %d is_allocated %d"
-commit_start(void *bs, void *base, void *top, void *s, void *co, void *opaque) "bs %p base %p top %p s %p co %p opaque %p"
+commit_start(void *bs, void *base, void *top, void *s, void *co) "bs %p base %p top %p s %p co %p"
# block/mirror.c
mirror_start(void *bs, void *s, void *co, void *opaque) "bs %p s %p co %p opaque %p"
@@ -51,7 +51,6 @@ qmp_block_job_cancel(void *job) "job %p"
qmp_block_job_pause(void *job) "job %p"
qmp_block_job_resume(void *job) "job %p"
qmp_block_job_complete(void *job) "job %p"
-block_job_cb(void *bs, void *job, int ret) "bs %p job %p ret %d"
qmp_block_stream(void *bs, void *job) "bs %p job %p"
# block/raw-win32.c