summaryrefslogtreecommitdiff
path: root/fs/orangefs/waitqueue.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-02-13 10:38:23 -0500
committerMike Marshall <hubcap@omnibond.com>2016-02-19 13:45:53 -0500
commit98815ade9eaca3c4729710129a651aa0b43d007a (patch)
tree456464c4342123ba153ac0f7eae959d0b973592f /fs/orangefs/waitqueue.c
parentd2d87a3b6df3088a991e277d42cd6a549ff2bc66 (diff)
downloadlwn-98815ade9eaca3c4729710129a651aa0b43d007a.tar.gz
lwn-98815ade9eaca3c4729710129a651aa0b43d007a.zip
orangefs: sanitize handling of request list
* checking that daemon is running (to decide whether we want to limit the timeout) should be done *after* the damn thing is included into the list; doing that before means that if the daemon gets shut down in between, we'll end up waiting indefinitely (== up to kill -9). * cancels should go into the head of the queue - the sooner they are picked, the less work daemon has to do and the sooner we get to free the slot held by aborted operation. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Mike Marshall <hubcap@omnibond.com>
Diffstat (limited to 'fs/orangefs/waitqueue.c')
-rw-r--r--fs/orangefs/waitqueue.c68
1 files changed, 18 insertions, 50 deletions
diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c
index 89622717a06d..6cae77400a5b 100644
--- a/fs/orangefs/waitqueue.c
+++ b/fs/orangefs/waitqueue.c
@@ -41,37 +41,6 @@ void purge_waiting_ops(void)
spin_unlock(&orangefs_request_list_lock);
}
-static inline void
-__add_op_to_request_list(struct orangefs_kernel_op_s *op)
-{
- spin_lock(&op->lock);
- set_op_state_waiting(op);
- list_add_tail(&op->list, &orangefs_request_list);
- spin_unlock(&op->lock);
- wake_up_interruptible(&orangefs_request_list_waitq);
-}
-
-static inline void
-add_op_to_request_list(struct orangefs_kernel_op_s *op)
-{
- spin_lock(&orangefs_request_list_lock);
- __add_op_to_request_list(op);
- spin_unlock(&orangefs_request_list_lock);
-}
-
-static inline
-void add_priority_op_to_request_list(struct orangefs_kernel_op_s *op)
-{
- spin_lock(&orangefs_request_list_lock);
- spin_lock(&op->lock);
- set_op_state_waiting(op);
-
- list_add(&op->list, &orangefs_request_list);
- spin_unlock(&orangefs_request_list_lock);
- spin_unlock(&op->lock);
- wake_up_interruptible(&orangefs_request_list_waitq);
-}
-
/*
* submits a ORANGEFS operation and waits for it to complete
*
@@ -126,32 +95,28 @@ retry_servicing:
}
}
- gossip_debug(GOSSIP_WAIT_DEBUG,
- "%s:About to call is_daemon_in_service().\n",
- __func__);
-
- if (is_daemon_in_service() < 0) {
+ /* queue up the operation */
+ spin_lock(&orangefs_request_list_lock);
+ spin_lock(&op->lock);
+ set_op_state_waiting(op);
+ if (flags & ORANGEFS_OP_PRIORITY)
+ list_add(&op->list, &orangefs_request_list);
+ else
+ list_add_tail(&op->list, &orangefs_request_list);
+ spin_unlock(&op->lock);
+ wake_up_interruptible(&orangefs_request_list_waitq);
+ if (!__is_daemon_in_service()) {
/*
* By incrementing the per-operation attempt counter, we
* directly go into the timeout logic while waiting for
* the matching downcall to be read
*/
gossip_debug(GOSSIP_WAIT_DEBUG,
- "%s:client core is NOT in service(%d).\n",
- __func__,
- is_daemon_in_service());
- op->attempts++;
- }
-
- /* queue up the operation */
- if (flags & ORANGEFS_OP_PRIORITY) {
- add_priority_op_to_request_list(op);
- } else {
- gossip_debug(GOSSIP_WAIT_DEBUG,
- "%s:About to call add_op_to_request_list().\n",
+ "%s:client core is NOT in service.\n",
__func__);
- add_op_to_request_list(op);
+ op->attempts++;
}
+ spin_unlock(&orangefs_request_list_lock);
if (!(flags & ORANGEFS_OP_NO_SEMAPHORE))
mutex_unlock(&request_mutex);
@@ -292,7 +257,10 @@ bool orangefs_cancel_op_in_progress(struct orangefs_kernel_op_s *op)
spin_unlock(&orangefs_request_list_lock);
return false;
}
- __add_op_to_request_list(op);
+ spin_lock(&op->lock);
+ set_op_state_waiting(op);
+ list_add(&op->list, &orangefs_request_list);
+ spin_unlock(&op->lock);
spin_unlock(&orangefs_request_list_lock);
gossip_debug(GOSSIP_UTILS_DEBUG,