diff options
-rw-r--r-- | fs/afs/rxrpc.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index b50642870a43..b4d337ad6e36 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c | |||
@@ -65,6 +65,12 @@ static void afs_async_workfn(struct work_struct *work) | |||
65 | call->async_workfn(call); | 65 | call->async_workfn(call); |
66 | } | 66 | } |
67 | 67 | ||
68 | static int afs_wait_atomic_t(atomic_t *p) | ||
69 | { | ||
70 | schedule(); | ||
71 | return 0; | ||
72 | } | ||
73 | |||
68 | /* | 74 | /* |
69 | * open an RxRPC socket and bind it to be a server for callback notifications | 75 | * open an RxRPC socket and bind it to be a server for callback notifications |
70 | * - the socket is left in blocking mode and non-blocking ops use MSG_DONTWAIT | 76 | * - the socket is left in blocking mode and non-blocking ops use MSG_DONTWAIT |
@@ -126,13 +132,16 @@ void afs_close_socket(void) | |||
126 | { | 132 | { |
127 | _enter(""); | 133 | _enter(""); |
128 | 134 | ||
135 | wait_on_atomic_t(&afs_outstanding_calls, afs_wait_atomic_t, | ||
136 | TASK_UNINTERRUPTIBLE); | ||
137 | _debug("no outstanding calls"); | ||
138 | |||
129 | sock_release(afs_socket); | 139 | sock_release(afs_socket); |
130 | 140 | ||
131 | _debug("dework"); | 141 | _debug("dework"); |
132 | destroy_workqueue(afs_async_calls); | 142 | destroy_workqueue(afs_async_calls); |
133 | 143 | ||
134 | ASSERTCMP(atomic_read(&afs_outstanding_skbs), ==, 0); | 144 | ASSERTCMP(atomic_read(&afs_outstanding_skbs), ==, 0); |
135 | ASSERTCMP(atomic_read(&afs_outstanding_calls), ==, 0); | ||
136 | _leave(""); | 145 | _leave(""); |
137 | } | 146 | } |
138 | 147 | ||
@@ -178,8 +187,6 @@ static void afs_free_call(struct afs_call *call) | |||
178 | { | 187 | { |
179 | _debug("DONE %p{%s} [%d]", | 188 | _debug("DONE %p{%s} [%d]", |
180 | call, call->type->name, atomic_read(&afs_outstanding_calls)); | 189 | call, call->type->name, atomic_read(&afs_outstanding_calls)); |
181 | if (atomic_dec_return(&afs_outstanding_calls) == -1) | ||
182 | BUG(); | ||
183 | 190 | ||
184 | ASSERTCMP(call->rxcall, ==, NULL); | 191 | ASSERTCMP(call->rxcall, ==, NULL); |
185 | ASSERT(!work_pending(&call->async_work)); | 192 | ASSERT(!work_pending(&call->async_work)); |
@@ -188,6 +195,9 @@ static void afs_free_call(struct afs_call *call) | |||
188 | 195 | ||
189 | kfree(call->request); | 196 | kfree(call->request); |
190 | kfree(call); | 197 | kfree(call); |
198 | |||
199 | if (atomic_dec_and_test(&afs_outstanding_calls)) | ||
200 | wake_up_atomic_t(&afs_outstanding_calls); | ||
191 | } | 201 | } |
192 | 202 | ||
193 | /* | 203 | /* |