diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-02-13 10:38:23 -0500 |
---|---|---|
committer | Mike Marshall <hubcap@omnibond.com> | 2016-02-19 13:45:53 -0500 |
commit | 98815ade9eaca3c4729710129a651aa0b43d007a (patch) | |
tree | 456464c4342123ba153ac0f7eae959d0b973592f /fs/orangefs | |
parent | d2d87a3b6df3088a991e277d42cd6a549ff2bc66 (diff) |
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')
-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) | |||
41 | spin_unlock(&orangefs_request_list_lock); | 41 | spin_unlock(&orangefs_request_list_lock); |
42 | } | 42 | } |
43 | 43 | ||
44 | static inline void | ||
45 | __add_op_to_request_list(struct orangefs_kernel_op_s *op) | ||
46 | { | ||
47 | spin_lock(&op->lock); | ||
48 | set_op_state_waiting(op); | ||
49 | list_add_tail(&op->list, &orangefs_request_list); | ||
50 | spin_unlock(&op->lock); | ||
51 | wake_up_interruptible(&orangefs_request_list_waitq); | ||
52 | } | ||
53 | |||
54 | static inline void | ||
55 | add_op_to_request_list(struct orangefs_kernel_op_s *op) | ||
56 | { | ||
57 | spin_lock(&orangefs_request_list_lock); | ||
58 | __add_op_to_request_list(op); | ||
59 | spin_unlock(&orangefs_request_list_lock); | ||
60 | } | ||
61 | |||
62 | static inline | ||
63 | void add_priority_op_to_request_list(struct orangefs_kernel_op_s *op) | ||
64 | { | ||
65 | spin_lock(&orangefs_request_list_lock); | ||
66 | spin_lock(&op->lock); | ||
67 | set_op_state_waiting(op); | ||
68 | |||
69 | list_add(&op->list, &orangefs_request_list); | ||
70 | spin_unlock(&orangefs_request_list_lock); | ||
71 | spin_unlock(&op->lock); | ||
72 | wake_up_interruptible(&orangefs_request_list_waitq); | ||
73 | } | ||
74 | |||
75 | /* | 44 | /* |
76 | * submits a ORANGEFS operation and waits for it to complete | 45 | * submits a ORANGEFS operation and waits for it to complete |
77 | * | 46 | * |
@@ -126,32 +95,28 @@ retry_servicing: | |||
126 | } | 95 | } |
127 | } | 96 | } |
128 | 97 | ||
129 | gossip_debug(GOSSIP_WAIT_DEBUG, | 98 | /* queue up the operation */ |
130 | "%s:About to call is_daemon_in_service().\n", | 99 | spin_lock(&orangefs_request_list_lock); |
131 | __func__); | 100 | spin_lock(&op->lock); |
132 | 101 | set_op_state_waiting(op); | |
133 | if (is_daemon_in_service() < 0) { | 102 | if (flags & ORANGEFS_OP_PRIORITY) |
103 | list_add(&op->list, &orangefs_request_list); | ||
104 | else | ||
105 | list_add_tail(&op->list, &orangefs_request_list); | ||
106 | spin_unlock(&op->lock); | ||
107 | wake_up_interruptible(&orangefs_request_list_waitq); | ||
108 | if (!__is_daemon_in_service()) { | ||
134 | /* | 109 | /* |
135 | * By incrementing the per-operation attempt counter, we | 110 | * By incrementing the per-operation attempt counter, we |
136 | * directly go into the timeout logic while waiting for | 111 | * directly go into the timeout logic while waiting for |
137 | * the matching downcall to be read | 112 | * the matching downcall to be read |
138 | */ | 113 | */ |
139 | gossip_debug(GOSSIP_WAIT_DEBUG, | 114 | gossip_debug(GOSSIP_WAIT_DEBUG, |
140 | "%s:client core is NOT in service(%d).\n", | 115 | "%s:client core is NOT in service.\n", |
141 | __func__, | ||
142 | is_daemon_in_service()); | ||
143 | op->attempts++; | ||
144 | } | ||
145 | |||
146 | /* queue up the operation */ | ||
147 | if (flags & ORANGEFS_OP_PRIORITY) { | ||
148 | add_priority_op_to_request_list(op); | ||
149 | } else { | ||
150 | gossip_debug(GOSSIP_WAIT_DEBUG, | ||
151 | "%s:About to call add_op_to_request_list().\n", | ||
152 | __func__); | 116 | __func__); |
153 | add_op_to_request_list(op); | 117 | op->attempts++; |
154 | } | 118 | } |
119 | spin_unlock(&orangefs_request_list_lock); | ||
155 | 120 | ||
156 | if (!(flags & ORANGEFS_OP_NO_SEMAPHORE)) | 121 | if (!(flags & ORANGEFS_OP_NO_SEMAPHORE)) |
157 | mutex_unlock(&request_mutex); | 122 | mutex_unlock(&request_mutex); |
@@ -292,7 +257,10 @@ bool orangefs_cancel_op_in_progress(struct orangefs_kernel_op_s *op) | |||
292 | spin_unlock(&orangefs_request_list_lock); | 257 | spin_unlock(&orangefs_request_list_lock); |
293 | return false; | 258 | return false; |
294 | } | 259 | } |
295 | __add_op_to_request_list(op); | 260 | spin_lock(&op->lock); |
261 | set_op_state_waiting(op); | ||
262 | list_add(&op->list, &orangefs_request_list); | ||
263 | spin_unlock(&op->lock); | ||
296 | spin_unlock(&orangefs_request_list_lock); | 264 | spin_unlock(&orangefs_request_list_lock); |
297 | 265 | ||
298 | gossip_debug(GOSSIP_UTILS_DEBUG, | 266 | gossip_debug(GOSSIP_UTILS_DEBUG, |