hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/fs/afs/rotate.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* Handle fileserver selection and rotation.
23 *
34 * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
45 * Written by David Howells (dhowells@redhat.com)
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public Licence
8
- * as published by the Free Software Foundation; either version
9
- * 2 of the Licence, or (at your option) any later version.
106 */
117
128 #include <linux/kernel.h>
....@@ -19,58 +15,32 @@
1915 #include "afs_fs.h"
2016
2117 /*
22
- * Initialise a filesystem server cursor for iterating over FS servers.
23
- */
24
-static void afs_init_fs_cursor(struct afs_fs_cursor *fc, struct afs_vnode *vnode)
25
-{
26
- memset(fc, 0, sizeof(*fc));
27
-}
28
-
29
-/*
30
- * Begin an operation on the fileserver.
31
- *
32
- * Fileserver operations are serialised on the server by vnode, so we serialise
33
- * them here also using the io_lock.
34
- */
35
-bool afs_begin_vnode_operation(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
36
- struct key *key)
37
-{
38
- afs_init_fs_cursor(fc, vnode);
39
- fc->vnode = vnode;
40
- fc->key = key;
41
- fc->ac.error = SHRT_MAX;
42
-
43
- if (mutex_lock_interruptible(&vnode->io_lock) < 0) {
44
- fc->ac.error = -EINTR;
45
- fc->flags |= AFS_FS_CURSOR_STOP;
46
- return false;
47
- }
48
-
49
- if (vnode->lock_state != AFS_VNODE_LOCK_NONE)
50
- fc->flags |= AFS_FS_CURSOR_CUR_ONLY;
51
- return true;
52
-}
53
-
54
-/*
5518 * Begin iteration through a server list, starting with the vnode's last used
5619 * server if possible, or the last recorded good server if not.
5720 */
58
-static bool afs_start_fs_iteration(struct afs_fs_cursor *fc,
21
+static bool afs_start_fs_iteration(struct afs_operation *op,
5922 struct afs_vnode *vnode)
6023 {
61
- struct afs_cb_interest *cbi;
24
+ struct afs_server *server;
25
+ void *cb_server;
6226 int i;
6327
64
- read_lock(&vnode->volume->servers_lock);
65
- fc->server_list = afs_get_serverlist(vnode->volume->servers);
66
- read_unlock(&vnode->volume->servers_lock);
28
+ read_lock(&op->volume->servers_lock);
29
+ op->server_list = afs_get_serverlist(
30
+ rcu_dereference_protected(op->volume->servers,
31
+ lockdep_is_held(&op->volume->servers_lock)));
32
+ read_unlock(&op->volume->servers_lock);
6733
68
- cbi = vnode->cb_interest;
69
- if (cbi) {
34
+ op->untried = (1UL << op->server_list->nr_servers) - 1;
35
+ op->index = READ_ONCE(op->server_list->preferred);
36
+
37
+ cb_server = vnode->cb_server;
38
+ if (cb_server) {
7039 /* See if the vnode's preferred record is still available */
71
- for (i = 0; i < fc->server_list->nr_servers; i++) {
72
- if (fc->server_list->servers[i].cb_interest == cbi) {
73
- fc->start = i;
40
+ for (i = 0; i < op->server_list->nr_servers; i++) {
41
+ server = op->server_list->servers[i].server;
42
+ if (server == cb_server) {
43
+ op->index = i;
7444 goto found_interest;
7545 }
7646 }
....@@ -79,27 +49,21 @@
7949 * serving this vnode, then we can't switch to another server
8050 * and have to return an error.
8151 */
82
- if (fc->flags & AFS_FS_CURSOR_CUR_ONLY) {
83
- fc->ac.error = -ESTALE;
52
+ if (op->flags & AFS_OPERATION_CUR_ONLY) {
53
+ op->error = -ESTALE;
8454 return false;
8555 }
8656
8757 /* Note that the callback promise is effectively broken */
8858 write_seqlock(&vnode->cb_lock);
89
- ASSERTCMP(cbi, ==, vnode->cb_interest);
90
- vnode->cb_interest = NULL;
59
+ ASSERTCMP(cb_server, ==, vnode->cb_server);
60
+ vnode->cb_server = NULL;
9161 if (test_and_clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags))
9262 vnode->cb_break++;
9363 write_sequnlock(&vnode->cb_lock);
94
-
95
- afs_put_cb_interest(afs_v2net(vnode), cbi);
96
- cbi = NULL;
97
- } else {
98
- fc->start = READ_ONCE(fc->server_list->index);
9964 }
10065
10166 found_interest:
102
- fc->index = fc->start;
10367 return true;
10468 }
10569
....@@ -117,18 +81,22 @@
11781 default: m = "busy"; break;
11882 }
11983
120
- pr_notice("kAFS: Volume %u '%s' is %s\n", volume->vid, volume->name, m);
84
+ pr_notice("kAFS: Volume %llu '%s' is %s\n", volume->vid, volume->name, m);
12185 }
12286
12387 /*
12488 * Sleep and retry the operation to the same fileserver.
12589 */
126
-static bool afs_sleep_and_retry(struct afs_fs_cursor *fc)
90
+static bool afs_sleep_and_retry(struct afs_operation *op)
12791 {
128
- msleep_interruptible(1000);
129
- if (signal_pending(current)) {
130
- fc->ac.error = -ERESTARTSYS;
131
- return false;
92
+ if (!(op->flags & AFS_OPERATION_UNINTR)) {
93
+ msleep_interruptible(1000);
94
+ if (signal_pending(current)) {
95
+ op->error = -ERESTARTSYS;
96
+ return false;
97
+ }
98
+ } else {
99
+ msleep(1000);
132100 }
133101
134102 return true;
....@@ -138,74 +106,80 @@
138106 * Select the fileserver to use. May be called multiple times to rotate
139107 * through the fileservers.
140108 */
141
-bool afs_select_fileserver(struct afs_fs_cursor *fc)
109
+bool afs_select_fileserver(struct afs_operation *op)
142110 {
143111 struct afs_addr_list *alist;
144112 struct afs_server *server;
145
- struct afs_vnode *vnode = fc->vnode;
113
+ struct afs_vnode *vnode = op->file[0].vnode;
114
+ struct afs_error e;
115
+ u32 rtt;
116
+ int error = op->ac.error, i;
146117
147
- _enter("%u/%u,%u/%u,%d,%d",
148
- fc->index, fc->start,
149
- fc->ac.index, fc->ac.start,
150
- fc->ac.error, fc->ac.abort_code);
118
+ _enter("%lx[%d],%lx[%d],%d,%d",
119
+ op->untried, op->index,
120
+ op->ac.tried, op->ac.index,
121
+ error, op->ac.abort_code);
151122
152
- if (fc->flags & AFS_FS_CURSOR_STOP) {
123
+ if (op->flags & AFS_OPERATION_STOP) {
153124 _leave(" = f [stopped]");
154125 return false;
155126 }
156127
128
+ op->nr_iterations++;
129
+
157130 /* Evaluate the result of the previous operation, if there was one. */
158
- switch (fc->ac.error) {
131
+ switch (error) {
159132 case SHRT_MAX:
160133 goto start;
161134
162135 case 0:
163136 default:
164137 /* Success or local failure. Stop. */
165
- fc->flags |= AFS_FS_CURSOR_STOP;
166
- _leave(" = f [okay/local %d]", fc->ac.error);
138
+ op->error = error;
139
+ op->flags |= AFS_OPERATION_STOP;
140
+ _leave(" = f [okay/local %d]", error);
167141 return false;
168142
169143 case -ECONNABORTED:
170144 /* The far side rejected the operation on some grounds. This
171145 * might involve the server being busy or the volume having been moved.
172146 */
173
- switch (fc->ac.abort_code) {
147
+ switch (op->ac.abort_code) {
174148 case VNOVOL:
175149 /* This fileserver doesn't know about the volume.
176150 * - May indicate that the VL is wrong - retry once and compare
177151 * the results.
178152 * - May indicate that the fileserver couldn't attach to the vol.
179153 */
180
- if (fc->flags & AFS_FS_CURSOR_VNOVOL) {
181
- fc->ac.error = -EREMOTEIO;
154
+ if (op->flags & AFS_OPERATION_VNOVOL) {
155
+ op->error = -EREMOTEIO;
182156 goto next_server;
183157 }
184158
185
- write_lock(&vnode->volume->servers_lock);
186
- fc->server_list->vnovol_mask |= 1 << fc->index;
187
- write_unlock(&vnode->volume->servers_lock);
159
+ write_lock(&op->volume->servers_lock);
160
+ op->server_list->vnovol_mask |= 1 << op->index;
161
+ write_unlock(&op->volume->servers_lock);
188162
189
- set_bit(AFS_VOLUME_NEEDS_UPDATE, &vnode->volume->flags);
190
- fc->ac.error = afs_check_volume_status(vnode->volume, fc->key);
191
- if (fc->ac.error < 0)
192
- goto failed;
163
+ set_bit(AFS_VOLUME_NEEDS_UPDATE, &op->volume->flags);
164
+ error = afs_check_volume_status(op->volume, op);
165
+ if (error < 0)
166
+ goto failed_set_error;
193167
194
- if (test_bit(AFS_VOLUME_DELETED, &vnode->volume->flags)) {
195
- fc->ac.error = -ENOMEDIUM;
168
+ if (test_bit(AFS_VOLUME_DELETED, &op->volume->flags)) {
169
+ op->error = -ENOMEDIUM;
196170 goto failed;
197171 }
198172
199173 /* If the server list didn't change, then assume that
200174 * it's the fileserver having trouble.
201175 */
202
- if (vnode->volume->servers == fc->server_list) {
203
- fc->ac.error = -EREMOTEIO;
176
+ if (rcu_access_pointer(op->volume->servers) == op->server_list) {
177
+ op->error = -EREMOTEIO;
204178 goto next_server;
205179 }
206180
207181 /* Try again */
208
- fc->flags |= AFS_FS_CURSOR_VNOVOL;
182
+ op->flags |= AFS_OPERATION_VNOVOL;
209183 _leave(" = t [vnovol]");
210184 return true;
211185
....@@ -215,20 +189,20 @@
215189 case VONLINE:
216190 case VDISKFULL:
217191 case VOVERQUOTA:
218
- fc->ac.error = afs_abort_to_error(fc->ac.abort_code);
192
+ op->error = afs_abort_to_error(op->ac.abort_code);
219193 goto next_server;
220194
221195 case VOFFLINE:
222
- if (!test_and_set_bit(AFS_VOLUME_OFFLINE, &vnode->volume->flags)) {
223
- afs_busy(vnode->volume, fc->ac.abort_code);
224
- clear_bit(AFS_VOLUME_BUSY, &vnode->volume->flags);
196
+ if (!test_and_set_bit(AFS_VOLUME_OFFLINE, &op->volume->flags)) {
197
+ afs_busy(op->volume, op->ac.abort_code);
198
+ clear_bit(AFS_VOLUME_BUSY, &op->volume->flags);
225199 }
226
- if (fc->flags & AFS_FS_CURSOR_NO_VSLEEP) {
227
- fc->ac.error = -EADV;
200
+ if (op->flags & AFS_OPERATION_NO_VSLEEP) {
201
+ op->error = -EADV;
228202 goto failed;
229203 }
230
- if (fc->flags & AFS_FS_CURSOR_CUR_ONLY) {
231
- fc->ac.error = -ESTALE;
204
+ if (op->flags & AFS_OPERATION_CUR_ONLY) {
205
+ op->error = -ESTALE;
232206 goto failed;
233207 }
234208 goto busy;
....@@ -239,17 +213,17 @@
239213 /* Retry after going round all the servers unless we
240214 * have a file lock we need to maintain.
241215 */
242
- if (fc->flags & AFS_FS_CURSOR_NO_VSLEEP) {
243
- fc->ac.error = -EBUSY;
216
+ if (op->flags & AFS_OPERATION_NO_VSLEEP) {
217
+ op->error = -EBUSY;
244218 goto failed;
245219 }
246
- if (!test_and_set_bit(AFS_VOLUME_BUSY, &vnode->volume->flags)) {
247
- afs_busy(vnode->volume, fc->ac.abort_code);
248
- clear_bit(AFS_VOLUME_OFFLINE, &vnode->volume->flags);
220
+ if (!test_and_set_bit(AFS_VOLUME_BUSY, &op->volume->flags)) {
221
+ afs_busy(op->volume, op->ac.abort_code);
222
+ clear_bit(AFS_VOLUME_OFFLINE, &op->volume->flags);
249223 }
250224 busy:
251
- if (fc->flags & AFS_FS_CURSOR_CUR_ONLY) {
252
- if (!afs_sleep_and_retry(fc))
225
+ if (op->flags & AFS_OPERATION_CUR_ONLY) {
226
+ if (!afs_sleep_and_retry(op))
253227 goto failed;
254228
255229 /* Retry with same server & address */
....@@ -257,7 +231,7 @@
257231 return true;
258232 }
259233
260
- fc->flags |= AFS_FS_CURSOR_VBUSY;
234
+ op->flags |= AFS_OPERATION_VBUSY;
261235 goto next_server;
262236
263237 case VMOVED:
....@@ -268,17 +242,17 @@
268242 * We also limit the number of VMOVED hops we will
269243 * honour, just in case someone sets up a loop.
270244 */
271
- if (fc->flags & AFS_FS_CURSOR_VMOVED) {
272
- fc->ac.error = -EREMOTEIO;
245
+ if (op->flags & AFS_OPERATION_VMOVED) {
246
+ op->error = -EREMOTEIO;
273247 goto failed;
274248 }
275
- fc->flags |= AFS_FS_CURSOR_VMOVED;
249
+ op->flags |= AFS_OPERATION_VMOVED;
276250
277
- set_bit(AFS_VOLUME_WAIT, &vnode->volume->flags);
278
- set_bit(AFS_VOLUME_NEEDS_UPDATE, &vnode->volume->flags);
279
- fc->ac.error = afs_check_volume_status(vnode->volume, fc->key);
280
- if (fc->ac.error < 0)
281
- goto failed;
251
+ set_bit(AFS_VOLUME_WAIT, &op->volume->flags);
252
+ set_bit(AFS_VOLUME_NEEDS_UPDATE, &op->volume->flags);
253
+ error = afs_check_volume_status(op->volume, op);
254
+ if (error < 0)
255
+ goto failed_set_error;
282256
283257 /* If the server list didn't change, then the VLDB is
284258 * out of sync with the fileservers. This is hopefully
....@@ -289,77 +263,120 @@
289263 *
290264 * TODO: Retry a few times with sleeps.
291265 */
292
- if (vnode->volume->servers == fc->server_list) {
293
- fc->ac.error = -ENOMEDIUM;
266
+ if (rcu_access_pointer(op->volume->servers) == op->server_list) {
267
+ op->error = -ENOMEDIUM;
294268 goto failed;
295269 }
296270
297271 goto restart_from_beginning;
298272
299273 default:
300
- clear_bit(AFS_VOLUME_OFFLINE, &vnode->volume->flags);
301
- clear_bit(AFS_VOLUME_BUSY, &vnode->volume->flags);
302
- fc->ac.error = afs_abort_to_error(fc->ac.abort_code);
274
+ clear_bit(AFS_VOLUME_OFFLINE, &op->volume->flags);
275
+ clear_bit(AFS_VOLUME_BUSY, &op->volume->flags);
276
+ op->error = afs_abort_to_error(op->ac.abort_code);
303277 goto failed;
304278 }
305279
306
- case -ENETUNREACH:
307
- case -EHOSTUNREACH:
308
- case -ECONNREFUSED:
309280 case -ETIMEDOUT:
310281 case -ETIME:
282
+ if (op->error != -EDESTADDRREQ)
283
+ goto iterate_address;
284
+ fallthrough;
285
+ case -ERFKILL:
286
+ case -EADDRNOTAVAIL:
287
+ case -ENETUNREACH:
288
+ case -EHOSTUNREACH:
289
+ case -EHOSTDOWN:
290
+ case -ECONNREFUSED:
311291 _debug("no conn");
292
+ op->error = error;
312293 goto iterate_address;
313294
314295 case -ECONNRESET:
315296 _debug("call reset");
297
+ op->error = error;
316298 goto failed;
317299 }
318300
319301 restart_from_beginning:
320302 _debug("restart");
321
- afs_end_cursor(&fc->ac);
322
- afs_put_cb_interest(afs_v2net(vnode), fc->cbi);
323
- fc->cbi = NULL;
324
- afs_put_serverlist(afs_v2net(vnode), fc->server_list);
325
- fc->server_list = NULL;
303
+ afs_end_cursor(&op->ac);
304
+ op->server = NULL;
305
+ afs_put_serverlist(op->net, op->server_list);
306
+ op->server_list = NULL;
326307 start:
327308 _debug("start");
328309 /* See if we need to do an update of the volume record. Note that the
329310 * volume may have moved or even have been deleted.
330311 */
331
- fc->ac.error = afs_check_volume_status(vnode->volume, fc->key);
332
- if (fc->ac.error < 0)
312
+ error = afs_check_volume_status(op->volume, op);
313
+ if (error < 0)
314
+ goto failed_set_error;
315
+
316
+ if (!afs_start_fs_iteration(op, vnode))
333317 goto failed;
334318
335
- if (!afs_start_fs_iteration(fc, vnode))
336
- goto failed;
319
+ _debug("__ VOL %llx __", op->volume->vid);
337320
338
-use_server:
339
- _debug("use");
321
+pick_server:
322
+ _debug("pick [%lx]", op->untried);
323
+
324
+ error = afs_wait_for_fs_probes(op->server_list, op->untried);
325
+ if (error < 0)
326
+ goto failed_set_error;
327
+
328
+ /* Pick the untried server with the lowest RTT. If we have outstanding
329
+ * callbacks, we stick with the server we're already using if we can.
330
+ */
331
+ if (op->server) {
332
+ _debug("server %u", op->index);
333
+ if (test_bit(op->index, &op->untried))
334
+ goto selected_server;
335
+ op->server = NULL;
336
+ _debug("no server");
337
+ }
338
+
339
+ op->index = -1;
340
+ rtt = U32_MAX;
341
+ for (i = 0; i < op->server_list->nr_servers; i++) {
342
+ struct afs_server *s = op->server_list->servers[i].server;
343
+
344
+ if (!test_bit(i, &op->untried) ||
345
+ !test_bit(AFS_SERVER_FL_RESPONDING, &s->flags))
346
+ continue;
347
+ if (s->probe.rtt < rtt) {
348
+ op->index = i;
349
+ rtt = s->probe.rtt;
350
+ }
351
+ }
352
+
353
+ if (op->index == -1)
354
+ goto no_more_servers;
355
+
356
+selected_server:
357
+ _debug("use %d", op->index);
358
+ __clear_bit(op->index, &op->untried);
359
+
340360 /* We're starting on a different fileserver from the list. We need to
341361 * check it, create a callback intercept, find its address list and
342362 * probe its capabilities before we use it.
343363 */
344
- ASSERTCMP(fc->ac.alist, ==, NULL);
345
- server = fc->server_list->servers[fc->index].server;
364
+ ASSERTCMP(op->ac.alist, ==, NULL);
365
+ server = op->server_list->servers[op->index].server;
346366
347
- if (!afs_check_server_record(fc, server))
367
+ if (!afs_check_server_record(op, server))
348368 goto failed;
349369
350370 _debug("USING SERVER: %pU", &server->uuid);
351371
352
- /* Make sure we've got a callback interest record for this server. We
353
- * have to link it in before we send the request as we can be sent a
354
- * break request before we've finished decoding the reply and
355
- * installing the vnode.
356
- */
357
- fc->ac.error = afs_register_server_cb_interest(vnode, fc->server_list,
358
- fc->index);
359
- if (fc->ac.error < 0)
360
- goto failed;
361
-
362
- fc->cbi = afs_get_cb_interest(vnode->cb_interest);
372
+ op->flags |= AFS_OPERATION_RETRY_SERVER;
373
+ op->server = server;
374
+ if (vnode->cb_server != server) {
375
+ vnode->cb_server = server;
376
+ vnode->cb_s_break = server->cb_s_break;
377
+ vnode->cb_v_break = vnode->volume->cb_v_break;
378
+ clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
379
+ }
363380
364381 read_lock(&server->fs_lock);
365382 alist = rcu_dereference_protected(server->addresses,
....@@ -367,162 +384,130 @@
367384 afs_get_addrlist(alist);
368385 read_unlock(&server->fs_lock);
369386
370
- memset(&fc->ac, 0, sizeof(fc->ac));
387
+retry_server:
388
+ memset(&op->ac, 0, sizeof(op->ac));
371389
372
- /* Probe the current fileserver if we haven't done so yet. */
373
- if (!test_bit(AFS_SERVER_FL_PROBED, &server->flags)) {
374
- fc->ac.alist = afs_get_addrlist(alist);
375
-
376
- if (!afs_probe_fileserver(fc)) {
377
- switch (fc->ac.error) {
378
- case -ENOMEM:
379
- case -ERESTARTSYS:
380
- case -EINTR:
381
- goto failed;
382
- default:
383
- goto next_server;
384
- }
385
- }
386
- }
387
-
388
- if (!fc->ac.alist)
389
- fc->ac.alist = alist;
390
+ if (!op->ac.alist)
391
+ op->ac.alist = alist;
390392 else
391393 afs_put_addrlist(alist);
392394
393
- fc->ac.start = READ_ONCE(alist->index);
394
- fc->ac.index = fc->ac.start;
395
+ op->ac.index = -1;
395396
396397 iterate_address:
397
- ASSERT(fc->ac.alist);
398
- _debug("iterate %d/%d", fc->ac.index, fc->ac.alist->nr_addrs);
398
+ ASSERT(op->ac.alist);
399399 /* Iterate over the current server's address list to try and find an
400400 * address on which it will respond to us.
401401 */
402
- if (!afs_iterate_addresses(&fc->ac))
403
- goto next_server;
402
+ if (!afs_iterate_addresses(&op->ac))
403
+ goto out_of_addresses;
404
+
405
+ _debug("address [%u] %u/%u %pISp",
406
+ op->index, op->ac.index, op->ac.alist->nr_addrs,
407
+ &op->ac.alist->addrs[op->ac.index].transport);
404408
405409 _leave(" = t");
406410 return true;
407411
412
+out_of_addresses:
413
+ /* We've now had a failure to respond on all of a server's addresses -
414
+ * immediately probe them again and consider retrying the server.
415
+ */
416
+ afs_probe_fileserver(op->net, op->server);
417
+ if (op->flags & AFS_OPERATION_RETRY_SERVER) {
418
+ alist = op->ac.alist;
419
+ error = afs_wait_for_one_fs_probe(
420
+ op->server, !(op->flags & AFS_OPERATION_UNINTR));
421
+ switch (error) {
422
+ case 0:
423
+ op->flags &= ~AFS_OPERATION_RETRY_SERVER;
424
+ goto retry_server;
425
+ case -ERESTARTSYS:
426
+ goto failed_set_error;
427
+ case -ETIME:
428
+ case -EDESTADDRREQ:
429
+ goto next_server;
430
+ }
431
+ }
432
+
408433 next_server:
409434 _debug("next");
410
- afs_end_cursor(&fc->ac);
411
- afs_put_cb_interest(afs_v2net(vnode), fc->cbi);
412
- fc->cbi = NULL;
413
- fc->index++;
414
- if (fc->index >= fc->server_list->nr_servers)
415
- fc->index = 0;
416
- if (fc->index != fc->start)
417
- goto use_server;
435
+ afs_end_cursor(&op->ac);
436
+ goto pick_server;
418437
438
+no_more_servers:
419439 /* That's all the servers poked to no good effect. Try again if some
420440 * of them were busy.
421441 */
422
- if (fc->flags & AFS_FS_CURSOR_VBUSY)
442
+ if (op->flags & AFS_OPERATION_VBUSY)
423443 goto restart_from_beginning;
424444
425
- fc->ac.error = -EDESTADDRREQ;
426
- goto failed;
445
+ e.error = -EDESTADDRREQ;
446
+ e.responded = false;
447
+ for (i = 0; i < op->server_list->nr_servers; i++) {
448
+ struct afs_server *s = op->server_list->servers[i].server;
427449
450
+ afs_prioritise_error(&e, READ_ONCE(s->probe.error),
451
+ s->probe.abort_code);
452
+ }
453
+
454
+ error = e.error;
455
+
456
+failed_set_error:
457
+ op->error = error;
428458 failed:
429
- fc->flags |= AFS_FS_CURSOR_STOP;
430
- afs_end_cursor(&fc->ac);
431
- _leave(" = f [failed %d]", fc->ac.error);
459
+ op->flags |= AFS_OPERATION_STOP;
460
+ afs_end_cursor(&op->ac);
461
+ _leave(" = f [failed %d]", op->error);
432462 return false;
433463 }
434464
435465 /*
436
- * Select the same fileserver we used for a vnode before and only that
437
- * fileserver. We use this when we have a lock on that file, which is backed
438
- * only by the fileserver we obtained it from.
466
+ * Dump cursor state in the case of the error being EDESTADDRREQ.
439467 */
440
-bool afs_select_current_fileserver(struct afs_fs_cursor *fc)
468
+void afs_dump_edestaddrreq(const struct afs_operation *op)
441469 {
442
- struct afs_vnode *vnode = fc->vnode;
443
- struct afs_cb_interest *cbi = vnode->cb_interest;
444
- struct afs_addr_list *alist;
470
+ static int count;
471
+ int i;
445472
446
- _enter("");
473
+ if (!IS_ENABLED(CONFIG_AFS_DEBUG_CURSOR) || count > 3)
474
+ return;
475
+ count++;
447476
448
- switch (fc->ac.error) {
449
- case SHRT_MAX:
450
- if (!cbi) {
451
- fc->ac.error = -ESTALE;
452
- fc->flags |= AFS_FS_CURSOR_STOP;
453
- return false;
477
+ rcu_read_lock();
478
+
479
+ pr_notice("EDESTADDR occurred\n");
480
+ pr_notice("FC: cbb=%x cbb2=%x fl=%x err=%hd\n",
481
+ op->file[0].cb_break_before,
482
+ op->file[1].cb_break_before, op->flags, op->error);
483
+ pr_notice("FC: ut=%lx ix=%d ni=%u\n",
484
+ op->untried, op->index, op->nr_iterations);
485
+
486
+ if (op->server_list) {
487
+ const struct afs_server_list *sl = op->server_list;
488
+ pr_notice("FC: SL nr=%u pr=%u vnov=%hx\n",
489
+ sl->nr_servers, sl->preferred, sl->vnovol_mask);
490
+ for (i = 0; i < sl->nr_servers; i++) {
491
+ const struct afs_server *s = sl->servers[i].server;
492
+ pr_notice("FC: server fl=%lx av=%u %pU\n",
493
+ s->flags, s->addr_version, &s->uuid);
494
+ if (s->addresses) {
495
+ const struct afs_addr_list *a =
496
+ rcu_dereference(s->addresses);
497
+ pr_notice("FC: - av=%u nr=%u/%u/%u pr=%u\n",
498
+ a->version,
499
+ a->nr_ipv4, a->nr_addrs, a->max_addrs,
500
+ a->preferred);
501
+ pr_notice("FC: - R=%lx F=%lx\n",
502
+ a->responded, a->failed);
503
+ if (a == op->ac.alist)
504
+ pr_notice("FC: - current\n");
505
+ }
454506 }
455
-
456
- fc->cbi = afs_get_cb_interest(vnode->cb_interest);
457
-
458
- read_lock(&cbi->server->fs_lock);
459
- alist = rcu_dereference_protected(cbi->server->addresses,
460
- lockdep_is_held(&cbi->server->fs_lock));
461
- afs_get_addrlist(alist);
462
- read_unlock(&cbi->server->fs_lock);
463
- if (!alist) {
464
- fc->ac.error = -ESTALE;
465
- fc->flags |= AFS_FS_CURSOR_STOP;
466
- return false;
467
- }
468
-
469
- memset(&fc->ac, 0, sizeof(fc->ac));
470
- fc->ac.alist = alist;
471
- fc->ac.start = READ_ONCE(alist->index);
472
- fc->ac.index = fc->ac.start;
473
- goto iterate_address;
474
-
475
- case 0:
476
- default:
477
- /* Success or local failure. Stop. */
478
- fc->flags |= AFS_FS_CURSOR_STOP;
479
- _leave(" = f [okay/local %d]", fc->ac.error);
480
- return false;
481
-
482
- case -ECONNABORTED:
483
- fc->flags |= AFS_FS_CURSOR_STOP;
484
- _leave(" = f [abort]");
485
- return false;
486
-
487
- case -ENETUNREACH:
488
- case -EHOSTUNREACH:
489
- case -ECONNREFUSED:
490
- case -ETIMEDOUT:
491
- case -ETIME:
492
- _debug("no conn");
493
- goto iterate_address;
494507 }
495508
496
-iterate_address:
497
- /* Iterate over the current server's address list to try and find an
498
- * address on which it will respond to us.
499
- */
500
- if (afs_iterate_addresses(&fc->ac)) {
501
- _leave(" = t");
502
- return true;
503
- }
504
-
505
- afs_end_cursor(&fc->ac);
506
- return false;
507
-}
508
-
509
-/*
510
- * Tidy up a filesystem cursor and unlock the vnode.
511
- */
512
-int afs_end_vnode_operation(struct afs_fs_cursor *fc)
513
-{
514
- struct afs_net *net = afs_v2net(fc->vnode);
515
- int ret;
516
-
517
- mutex_unlock(&fc->vnode->io_lock);
518
-
519
- afs_end_cursor(&fc->ac);
520
- afs_put_cb_interest(net, fc->cbi);
521
- afs_put_serverlist(net, fc->server_list);
522
-
523
- ret = fc->ac.error;
524
- if (ret == -ECONNABORTED)
525
- afs_abort_to_error(fc->ac.abort_code);
526
-
527
- return fc->ac.error;
509
+ pr_notice("AC: t=%lx ax=%u ac=%d er=%d r=%u ni=%u\n",
510
+ op->ac.tried, op->ac.index, op->ac.abort_code, op->ac.error,
511
+ op->ac.responded, op->ac.nr_iterations);
512
+ rcu_read_unlock();
528513 }