diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-02-13 16:38:23 +0100 |
---|---|---|
committer | Mike Marshall <hubcap@omnibond.com> | 2016-02-19 19:45:53 +0100 |
commit | 98815ade9eaca3c4729710129a651aa0b43d007a (patch) | |
tree | 456464c4342123ba153ac0f7eae959d0b973592f /fs/orangefs/waitqueue.c | |
parent | orangefs: get rid of loop in wait_for_matching_downcall() (diff) | |
download | linux-98815ade9eaca3c4729710129a651aa0b43d007a.tar.xz linux-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.c | 68 |
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, |