block.c (4513eafe928ff47486f4167c28d364c72b5ff7e3) | block.c (fa4478d5c8b74a5f0c8b93cc00590ec007be5016) |
---|---|
1/* 2 * QEMU System Emulator block driver 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights --- 4224 unchanged lines hidden (view full) --- 4233 } 4234 4235 job->speed = speed; 4236} 4237 4238void block_job_cancel(BlockJob *job) 4239{ 4240 job->cancelled = true; | 1/* 2 * QEMU System Emulator block driver 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights --- 4224 unchanged lines hidden (view full) --- 4233 } 4234 4235 job->speed = speed; 4236} 4237 4238void block_job_cancel(BlockJob *job) 4239{ 4240 job->cancelled = true; |
4241 if (job->co && !job->busy) { 4242 qemu_coroutine_enter(job->co, NULL); 4243 } |
|
4241} 4242 4243bool block_job_is_cancelled(BlockJob *job) 4244{ 4245 return job->cancelled; 4246} 4247 | 4244} 4245 4246bool block_job_is_cancelled(BlockJob *job) 4247{ 4248 return job->cancelled; 4249} 4250 |
4248void block_job_cancel_sync(BlockJob *job) | 4251struct BlockCancelData { 4252 BlockJob *job; 4253 BlockDriverCompletionFunc *cb; 4254 void *opaque; 4255 bool cancelled; 4256 int ret; 4257}; 4258 4259static void block_job_cancel_cb(void *opaque, int ret) |
4249{ | 4260{ |
4261 struct BlockCancelData *data = opaque; 4262 4263 data->cancelled = block_job_is_cancelled(data->job); 4264 data->ret = ret; 4265 data->cb(data->opaque, ret); 4266} 4267 4268int block_job_cancel_sync(BlockJob *job) 4269{ 4270 struct BlockCancelData data; |
|
4250 BlockDriverState *bs = job->bs; 4251 4252 assert(bs->job == job); | 4271 BlockDriverState *bs = job->bs; 4272 4273 assert(bs->job == job); |
4274 4275 /* Set up our own callback to store the result and chain to 4276 * the original callback. 4277 */ 4278 data.job = job; 4279 data.cb = job->cb; 4280 data.opaque = job->opaque; 4281 data.ret = -EINPROGRESS; 4282 job->cb = block_job_cancel_cb; 4283 job->opaque = &data; |
|
4253 block_job_cancel(job); | 4284 block_job_cancel(job); |
4254 while (bs->job != NULL && bs->job->busy) { | 4285 while (data.ret == -EINPROGRESS) { |
4255 qemu_aio_wait(); 4256 } | 4286 qemu_aio_wait(); 4287 } |
4288 return (data.cancelled && data.ret == 0) ? -ECANCELED : data.ret; |
|
4257} 4258 4259void block_job_sleep_ns(BlockJob *job, QEMUClock *clock, int64_t ns) 4260{ 4261 /* Check cancellation *before* setting busy = false, too! */ 4262 if (!block_job_is_cancelled(job)) { 4263 job->busy = false; 4264 co_sleep_ns(clock, ns); 4265 job->busy = true; 4266 } 4267} | 4289} 4290 4291void block_job_sleep_ns(BlockJob *job, QEMUClock *clock, int64_t ns) 4292{ 4293 /* Check cancellation *before* setting busy = false, too! */ 4294 if (!block_job_is_cancelled(job)) { 4295 job->busy = false; 4296 co_sleep_ns(clock, ns); 4297 job->busy = true; 4298 } 4299} |