提交 7b6badb6 编写于 作者: S Stefan Hajnoczi

Merge remote-tracking branch 'jtc/tags/block-pull-request' into staging

# gpg: Signature made Fri 26 May 2017 08:22:27 PM BST
# gpg:                using RSA key 0xBDBE7B27C0DE3057
# gpg: Good signature from "Jeffrey Cody <jcody@redhat.com>"
# gpg:                 aka "Jeffrey Cody <jeff@codyprime.org>"
# gpg:                 aka "Jeffrey Cody <codyprime@gmail.com>"
# Primary key fingerprint: 9957 4B4D 3474 90E7 9D98  D624 BDBE 7B27 C0DE 3057

* jtc/tags/block-pull-request:
  block/gluster: glfs_lseek() workaround
  blockjob: use deferred_to_main_loop to indicate the coroutine has ended
  blockjob: reorganize block_job_completed_txn_abort
  blockjob: strengthen a bit test-blockjob-txn
  blockjob: group BlockJob transaction functions together
  blockjob: introduce block_job_cancel_async, check iostatus invariants
  blockjob: move iostatus reset inside block_job_user_resume
  blockjob: separate monitor and blockjob APIs
  blockjob: introduce block_job_pause/resume_all
  blockjob: introduce block_job_early_fail
  blockjob: remove iostatus_reset callback
  blockjob: remove unnecessary check
Signed-off-by: NStefan Hajnoczi <stefanha@redhat.com>
......@@ -692,7 +692,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
}
if (job) {
backup_clean(&job->common);
block_job_unref(&job->common);
block_job_early_fail(&job->common);
}
return NULL;
......
......@@ -426,7 +426,7 @@ fail:
if (commit_top_bs) {
bdrv_set_backing_hd(overlay_bs, top, &error_abort);
}
block_job_unref(&s->common);
block_job_early_fail(&s->common);
}
......
......@@ -1275,7 +1275,14 @@ static int find_allocation(BlockDriverState *bs, off_t start,
if (offs < 0) {
return -errno; /* D3 or D4 */
}
assert(offs >= start);
if (offs < start) {
/* This is not a valid return by lseek(). We are safe to just return
* -EIO in this case, and we'll treat it like D4. Unfortunately some
* versions of gluster server will return offs < start, so an assert
* here will unnecessarily abort QEMU. */
return -EIO;
}
if (offs > start) {
/* D2: in hole, next data at offs */
......@@ -1307,7 +1314,14 @@ static int find_allocation(BlockDriverState *bs, off_t start,
if (offs < 0) {
return -errno; /* D1 and (H3 or H4) */
}
assert(offs >= start);
if (offs < start) {
/* This is not a valid return by lseek(). We are safe to just return
* -EIO in this case, and we'll treat it like H4. Unfortunately some
* versions of gluster server will return offs < start, so an assert
* here will unnecessarily abort QEMU. */
return -EIO;
}
if (offs > start) {
/*
......
......@@ -26,6 +26,7 @@
#include "trace.h"
#include "sysemu/block-backend.h"
#include "block/blockjob.h"
#include "block/blockjob_int.h"
#include "block/block_int.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
......@@ -301,16 +302,9 @@ void bdrv_drain_all_begin(void)
bool waited = true;
BlockDriverState *bs;
BdrvNextIterator it;
BlockJob *job = NULL;
GSList *aio_ctxs = NULL, *ctx;
while ((job = block_job_next(job))) {
AioContext *aio_context = blk_get_aio_context(job->blk);
aio_context_acquire(aio_context);
block_job_pause(job);
aio_context_release(aio_context);
}
block_job_pause_all();
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
AioContext *aio_context = bdrv_get_aio_context(bs);
......@@ -354,7 +348,6 @@ void bdrv_drain_all_end(void)
{
BlockDriverState *bs;
BdrvNextIterator it;
BlockJob *job = NULL;
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
AioContext *aio_context = bdrv_get_aio_context(bs);
......@@ -365,13 +358,7 @@ void bdrv_drain_all_end(void)
aio_context_release(aio_context);
}
while ((job = block_job_next(job))) {
AioContext *aio_context = blk_get_aio_context(job->blk);
aio_context_acquire(aio_context);
block_job_resume(job);
aio_context_release(aio_context);
}
block_job_resume_all();
}
void bdrv_drain_all(void)
......
......@@ -1252,7 +1252,7 @@ fail:
g_free(s->replaces);
blk_unref(s->target);
block_job_unref(&s->common);
block_job_early_fail(&s->common);
}
bdrv_child_try_set_perm(mirror_top_bs->backing, 0, BLK_PERM_ALL,
......
......@@ -3715,7 +3715,6 @@ void qmp_block_job_resume(const char *device, Error **errp)
}
trace_qmp_block_job_resume(job);
block_job_iostatus_reset(job);
block_job_user_resume(job);
aio_context_release(aio_context);
}
......
此差异已折叠。
......@@ -234,14 +234,6 @@ void block_job_complete(BlockJob *job, Error **errp);
*/
BlockJobInfo *block_job_query(BlockJob *job, Error **errp);
/**
* block_job_pause:
* @job: The job to be paused.
*
* Asynchronously pause the specified job.
*/
void block_job_pause(BlockJob *job);
/**
* block_job_user_pause:
* @job: The job to be paused.
......@@ -259,14 +251,6 @@ void block_job_user_pause(BlockJob *job);
*/
bool block_job_user_paused(BlockJob *job);
/**
* block_job_resume:
* @job: The job to be resumed.
*
* Resume the specified job. Must be paired with a preceding block_job_pause.
*/
void block_job_resume(BlockJob *job);
/**
* block_job_user_resume:
* @job: The job to be resumed.
......
......@@ -44,9 +44,6 @@ struct BlockJobDriver {
/** Optional callback for job types that support setting a speed limit */
void (*set_speed)(BlockJob *job, int64_t speed, Error **errp);
/** Optional callback for job types that need to forward I/O status reset */
void (*iostatus_reset)(BlockJob *job);
/** Mandatory: Entrypoint for the Coroutine. */
CoroutineEntry *start;
......@@ -159,21 +156,26 @@ void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns);
void block_job_yield(BlockJob *job);
/**
* block_job_ref:
* @bs: The block device.
* block_job_pause_all:
*
* Asynchronously pause all jobs.
*/
void block_job_pause_all(void);
/**
* block_job_resume_all:
*
* Grab a reference to the block job. Should be paired with block_job_unref.
* Resume all block jobs. Must be paired with a preceding block_job_pause_all.
*/
void block_job_ref(BlockJob *job);
void block_job_resume_all(void);
/**
* block_job_unref:
* block_job_early_fail:
* @bs: The block device.
*
* Release reference to the block job and release resources if it is the last
* reference.
* The block job could not be started, free it.
*/
void block_job_unref(BlockJob *job);
void block_job_early_fail(BlockJob *job);
/**
* block_job_completed:
......@@ -239,7 +241,8 @@ typedef void BlockJobDeferToMainLoopFn(BlockJob *job, void *opaque);
* @fn: The function to run in the main loop
* @opaque: The opaque value that is passed to @fn
*
* Execute a given function in the main loop with the BlockDriverState
* This function must be called by the main job coroutine just before it
* returns. @fn is executed in the main loop with the BlockDriverState
* AioContext acquired. Block jobs must call bdrv_unref(), bdrv_close(), and
* anything that uses bdrv_drain_all() in the main loop.
*
......
......@@ -167,6 +167,11 @@ static void test_pair_jobs(int expected1, int expected2)
block_job_start(job1);
block_job_start(job2);
/* Release our reference now to trigger as many nice
* use-after-free bugs as possible.
*/
block_job_txn_unref(txn);
if (expected1 == -ECANCELED) {
block_job_cancel(job1);
}
......@@ -187,8 +192,6 @@ static void test_pair_jobs(int expected1, int expected2)
g_assert_cmpint(result1, ==, expected1);
g_assert_cmpint(result2, ==, expected2);
block_job_txn_unref(txn);
}
static void test_pair_jobs_success(void)
......
......@@ -116,11 +116,11 @@ static void test_job_ids(void)
job[1] = do_test_id(blk[1], "id0", false);
/* But once job[0] finishes we can reuse its ID */
block_job_unref(job[0]);
block_job_early_fail(job[0]);
job[1] = do_test_id(blk[1], "id0", true);
/* No job ID specified, defaults to the backend name ('drive1') */
block_job_unref(job[1]);
block_job_early_fail(job[1]);
job[1] = do_test_id(blk[1], NULL, true);
/* Duplicate job ID */
......@@ -133,9 +133,9 @@ static void test_job_ids(void)
/* This one is valid */
job[2] = do_test_id(blk[2], "id_2", true);
block_job_unref(job[0]);
block_job_unref(job[1]);
block_job_unref(job[2]);
block_job_early_fail(job[0]);
block_job_early_fail(job[1]);
block_job_early_fail(job[2]);
destroy_blk(blk[0]);
destroy_blk(blk[1]);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册