| @@ -19,6 +19,7 @@ · 18 unmodified lines |
| 19 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
| 20 | #include <linux/major.h> | 20 | #include <linux/major.h> |
| 21 | #include <linux/wait.h> | 21 | #include <linux/wait.h> |
| | 22 | #include <linux/wait_bit.h> |
| 22 | #include <linux/blkdev.h> | 23 | #include <linux/blkdev.h> |
| 23 | #include <linux/init.h> | 24 | #include <linux/init.h> |
| 24 | #include <linux/swap.h> | 25 | #include <linux/swap.h> |
| @@ -26,7 +27,6 @@ · 1 unmodified line |
| 26 | #include <linux/compat.h> | 27 | #include <linux/compat.h> |
| 27 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
| 28 | #include <linux/writeback.h> | 29 | #include <linux/writeback.h> |
| 29 | #include <linux/completion.h> | | |
| 30 | #include <linux/highmem.h> | 30 | #include <linux/highmem.h> |
| 31 | #include <linux/sysfs.h> | 31 | #include <linux/sysfs.h> |
| 32 | #include <linux/miscdevice.h> | 32 | #include <linux/miscdevice.h> |
| @@ -327,7 +327,6 @@ struct ublk_device { · 294 unmodified lines |
| 327 | | 327 | |
| 328 | struct ublk_params params; | 328 | struct ublk_params params; |
| 329 | | 329 | |
| 330 | struct completion completion; | | |
| 331 | u32 nr_queue_ready; | 330 | u32 nr_queue_ready; |
| 332 | bool unprivileged_daemons; | 331 | bool unprivileged_daemons; |
| 333 | struct mutex cancel_mutex; | 332 | struct mutex cancel_mutex; |
| @@ -3054,12 +3053,12 @@ static void ublk_mark_io_ready(struct ublk_device *ub, u16 q_id, · 2720 unmodified lines |
| 3054 | if (ublk_dev_ready(ub)) { | 3053 | if (ublk_dev_ready(ub)) { |
| 3055 | /* | 3054 | /* |
| 3056 | * All queues ready - clear device-level canceling flag | 3055 | * All queues ready - clear device-level canceling flag |
| 3057 | * and complete the recovery/initialization. | 3056 | * and wake ublk_dev_ready() waiters. |
| 3058 | */ | 3057 | */ |
| 3059 | mutex_lock(&ub->cancel_mutex); | 3058 | mutex_lock(&ub->cancel_mutex); |
| 3060 | ub->canceling = false; | 3059 | ub->canceling = false; |
| 3061 | mutex_unlock(&ub->cancel_mutex); | 3060 | mutex_unlock(&ub->cancel_mutex); |
| 3062 | complete_all(&ub->completion); | 3061 | wake_up_var(&ub->nr_queue_ready); |
| 3063 | } | 3062 | } |
| 3064 | } | 3063 | } |
| 3065 | | 3064 | |
| @@ -4273,7 +4272,6 @@ static int ublk_init_queues(struct ublk_device *ub) · 1207 unmodified lines |
| 4273 | goto fail; | 4272 | goto fail; |
| 4274 | } | 4273 | } |
| 4275 | | 4274 | |
| 4276 | init_completion(&ub->completion); | | |
| 4277 | return 0; | 4275 | return 0; |
| 4278 | | 4276 | |
| 4279 | fail: | 4277 | fail: |
| @@ -4417,6 +4415,26 @@ static bool ublk_validate_user_pid(struct ublk_device *ub, pid_t ublksrv_pid) · 137 unmodified lines |
| 4417 | return ub->ublksrv_tgid == ublksrv_pid; | 4415 | return ub->ublksrv_tgid == ublksrv_pid; |
| 4418 | } | 4416 | } |
| 4419 | | 4417 | |
| | 4418 | /* |
| | 4419 | * Wait until all queues have fetched their I/O commands, and return with |
| | 4420 | * ub->mutex held and readiness guaranteed: then every queue's ->canceling |
| | 4421 | * is cleared. Ready may regress between wakeup and mutex_lock() (F_BATCH |
| | 4422 | * UNPREP, daemon death), so re-check it under the mutex and wait again. |
| | 4423 | */ |
| | 4424 | static int ublk_wait_dev_ready_and_lock(struct ublk_device *ub) |
| | 4425 | { |
| | 4426 | while (true) { |
| | 4427 | if (wait_var_event_interruptible(&ub->nr_queue_ready, |
| | 4428 | ublk_dev_ready(ub))) |
| | 4429 | return -EINTR; |
| | 4430 | |
| | 4431 | mutex_lock(&ub->mutex); |
| | 4432 | if (ublk_dev_ready(ub)) |
| | 4433 | return 0; |
| | 4434 | mutex_unlock(&ub->mutex); |
| | 4435 | } |
| | 4436 | } |
| | 4437 | |
| 4420 | static int ublk_ctrl_start_dev(struct ublk_device *ub, | 4438 | static int ublk_ctrl_start_dev(struct ublk_device *ub, |
| 4421 | const struct ublksrv_ctrl_cmd *header) | 4439 | const struct ublksrv_ctrl_cmd *header) |
| 4422 | { | 4440 | { |
| @@ -4499,15 +4517,10 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, · 76 unmodified lines |
| 4499 | }; | 4517 | }; |
| 4500 | } | 4518 | } |
| 4501 | | 4519 | |
| 4502 | if (wait_for_completion_interruptible(&ub->completion) != 0) | 4520 | if (ublk_wait_dev_ready_and_lock(ub)) |
| 4503 | return -EINTR; | 4521 | return -EINTR; |
| 4504 | | 4522 | |
| 4505 | if (!ublk_validate_user_pid(ub, ublksrv_pid)) | 4523 | if (!ublk_validate_user_pid(ub, ublksrv_pid)) { |
| 4506 | return -EINVAL; | | |
| 4507 | | | |
| 4508 | mutex_lock(&ub->mutex); | | |
| 4509 | /* device may become not ready in case of F_BATCH */ | | |
| 4510 | if (!ublk_dev_ready(ub)) { | | |
| 4511 | ret = -EINVAL; | 4524 | ret = -EINVAL; |
| 4512 | goto out_unlock; | 4525 | goto out_unlock; |
| 4513 | } | 4526 | } |
| @@ -5071,7 +5084,6 @@ static int ublk_ctrl_start_recovery(struct ublk_device *ub) · 557 unmodified lines |
| 5071 | goto out_unlock; | 5084 | goto out_unlock; |
| 5072 | } | 5085 | } |
| 5073 | pr_devel("%s: start recovery for dev id %d\n", __func__, ub->ub_number); | 5086 | pr_devel("%s: start recovery for dev id %d\n", __func__, ub->ub_number); |
| 5074 | init_completion(&ub->completion); | | |
| 5075 | ret = 0; | 5087 | ret = 0; |
| 5076 | out_unlock: | 5088 | out_unlock: |
| 5077 | mutex_unlock(&ub->mutex); | 5089 | mutex_unlock(&ub->mutex); |
| @@ -5087,16 +5099,17 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub, · 9 unmodified lines |
| 5087 | pr_devel("%s: Waiting for all FETCH_REQs, dev id %d...\n", __func__, | 5099 | pr_devel("%s: Waiting for all FETCH_REQs, dev id %d...\n", __func__, |
| 5088 | header->dev_id); | 5100 | header->dev_id); |
| 5089 | | 5101 | |
| 5090 | if (wait_for_completion_interruptible(&ub->completion)) | 5102 | if (ublk_wait_dev_ready_and_lock(ub)) |
| 5091 | return -EINTR; | 5103 | return -EINTR; |
| 5092 | | 5104 | |
| 5093 | pr_devel("%s: All FETCH_REQs received, dev id %d\n", __func__, | 5105 | pr_devel("%s: All FETCH_REQs received, dev id %d\n", __func__, |
| 5094 | header->dev_id); | 5106 | header->dev_id); |
| 5095 | | 5107 | |
| 5096 | if (!ublk_validate_user_pid(ub, ublksrv_pid)) | 5108 | if (!ublk_validate_user_pid(ub, ublksrv_pid)) { |
| 5097 | return -EINVAL; | 5109 | ret = -EINVAL; |
| | 5110 | goto out_unlock; |
| | 5111 | } |
| 5098 | | 5112 | |
| 5099 | mutex_lock(&ub->mutex); | | |
| 5100 | if (ublk_nosrv_should_stop_dev(ub)) | 5113 | if (ublk_nosrv_should_stop_dev(ub)) |
| 5101 | goto out_unlock; | 5114 | goto out_unlock; |
| 5102 | | 5115 | |