|
@@ -398,6 +398,17 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
|
|
|
}
|
|
|
|
|
|
wakeup:
|
|
|
+ /*
|
|
|
+ * tell the vfs op waiting on a waitqueue
|
|
|
+ * that this op is done
|
|
|
+ */
|
|
|
+ spin_lock(&op->lock);
|
|
|
+ if (unlikely(op_state_given_up(op))) {
|
|
|
+ spin_unlock(&op->lock);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ set_op_state_serviced(op);
|
|
|
+ spin_unlock(&op->lock);
|
|
|
|
|
|
/*
|
|
|
* If this operation is an I/O operation we need to wait
|
|
@@ -411,61 +422,17 @@ wakeup:
|
|
|
* the buffers are done being used.
|
|
|
*/
|
|
|
if (op->downcall.type == ORANGEFS_VFS_OP_FILE_IO) {
|
|
|
- DEFINE_WAIT(wait_entry);
|
|
|
-
|
|
|
- /*
|
|
|
- * tell the vfs op waiting on a waitqueue
|
|
|
- * that this op is done
|
|
|
- */
|
|
|
- spin_lock(&op->lock);
|
|
|
- if (unlikely(op_state_given_up(op))) {
|
|
|
- spin_unlock(&op->lock);
|
|
|
- goto out;
|
|
|
- }
|
|
|
- set_op_state_serviced(op);
|
|
|
- spin_unlock(&op->lock);
|
|
|
-
|
|
|
- while (1) {
|
|
|
- spin_lock(&op->lock);
|
|
|
- prepare_to_wait_exclusive(
|
|
|
- &op->io_completion_waitq,
|
|
|
- &wait_entry,
|
|
|
- TASK_INTERRUPTIBLE);
|
|
|
- if (op->io_completed) {
|
|
|
- spin_unlock(&op->lock);
|
|
|
- break;
|
|
|
- }
|
|
|
- spin_unlock(&op->lock);
|
|
|
- if (unlikely(signal_pending(current))) {
|
|
|
- gossip_debug(GOSSIP_DEV_DEBUG,
|
|
|
- "%s: signal on I/O wait, aborting\n",
|
|
|
- __func__);
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- if (!schedule_timeout(op_timeout_secs * HZ)) {
|
|
|
- gossip_debug(GOSSIP_DEV_DEBUG,
|
|
|
- "%s: timed out.\n",
|
|
|
- __func__);
|
|
|
- break;
|
|
|
- }
|
|
|
+ long n = wait_for_completion_interruptible_timeout(&op->done,
|
|
|
+ op_timeout_secs * HZ);
|
|
|
+ if (unlikely(n < 0)) {
|
|
|
+ gossip_debug(GOSSIP_DEV_DEBUG,
|
|
|
+ "%s: signal on I/O wait, aborting\n",
|
|
|
+ __func__);
|
|
|
+ } else if (unlikely(n == 0)) {
|
|
|
+ gossip_debug(GOSSIP_DEV_DEBUG,
|
|
|
+ "%s: timed out.\n",
|
|
|
+ __func__);
|
|
|
}
|
|
|
-
|
|
|
- spin_lock(&op->lock);
|
|
|
- finish_wait(&op->io_completion_waitq, &wait_entry);
|
|
|
- spin_unlock(&op->lock);
|
|
|
- } else {
|
|
|
- /*
|
|
|
- * tell the vfs op waiting on a waitqueue that
|
|
|
- * this op is done -
|
|
|
- * for every other operation (i.e. non-I/O), we need to
|
|
|
- * wake up the callers for downcall completion
|
|
|
- * notification
|
|
|
- */
|
|
|
- spin_lock(&op->lock);
|
|
|
- if (!op_state_given_up(op))
|
|
|
- set_op_state_serviced(op);
|
|
|
- spin_unlock(&op->lock);
|
|
|
}
|
|
|
out:
|
|
|
op_release(op);
|