From 98815ade9eaca3c4729710129a651aa0b43d007a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 13 Feb 2016 10:38:23 -0500 Subject: 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 Signed-off-by: Mike Marshall --- fs/orangefs/waitqueue.c | 68 +++++++++++++------------------------------------ 1 file changed, 18 insertions(+), 50 deletions(-) (limited to 'fs/orangefs/waitqueue.c') 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, -- cgit v1.2.3