aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/rotate.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-11-13 18:20:28 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2018-11-29 21:08:14 -0500
commit4584ae96ae307613625e80cb9c7d9a981bed47a7 (patch)
tree3afe04fe4a054f74c7cfe1502cbfcee583b0d9ad /fs/afs/rotate.c
parentae3b7361dc0ee9a425bf7d77ce211f533500b39b (diff)
afs: Fix missing net error handling
kAFS can be given certain network errors (EADDRNOTAVAIL, EHOSTDOWN and ERFKILL) that it doesn't handle in its server/address rotation algorithms. They cause the probing and rotation to abort immediately rather than rotating. Fix this by: (1) Abstracting out the error prioritisation from the VL and FS rotation algorithms into a common function and expand usage into the server probing code. When multiple errors are available, this code selects the one we'd prefer to return. (2) Add handling for EADDRNOTAVAIL, EHOSTDOWN and ERFKILL. Fixes: 0fafdc9f888b ("afs: Fix file locking") Fixes: 0338747d8454 ("afs: Probe multiple fileservers simultaneously") Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/afs/rotate.c')
-rw-r--r--fs/afs/rotate.c53
1 files changed, 13 insertions, 40 deletions
diff --git a/fs/afs/rotate.c b/fs/afs/rotate.c
index 00504254c1c2..c3ae324781f8 100644
--- a/fs/afs/rotate.c
+++ b/fs/afs/rotate.c
@@ -136,7 +136,8 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
136 struct afs_addr_list *alist; 136 struct afs_addr_list *alist;
137 struct afs_server *server; 137 struct afs_server *server;
138 struct afs_vnode *vnode = fc->vnode; 138 struct afs_vnode *vnode = fc->vnode;
139 u32 rtt, abort_code; 139 struct afs_error e;
140 u32 rtt;
140 int error = fc->ac.error, i; 141 int error = fc->ac.error, i;
141 142
142 _enter("%lx[%d],%lx[%d],%d,%d", 143 _enter("%lx[%d],%lx[%d],%d,%d",
@@ -306,8 +307,11 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
306 if (fc->error != -EDESTADDRREQ) 307 if (fc->error != -EDESTADDRREQ)
307 goto iterate_address; 308 goto iterate_address;
308 /* Fall through */ 309 /* Fall through */
310 case -ERFKILL:
311 case -EADDRNOTAVAIL:
309 case -ENETUNREACH: 312 case -ENETUNREACH:
310 case -EHOSTUNREACH: 313 case -EHOSTUNREACH:
314 case -EHOSTDOWN:
311 case -ECONNREFUSED: 315 case -ECONNREFUSED:
312 _debug("no conn"); 316 _debug("no conn");
313 fc->error = error; 317 fc->error = error;
@@ -446,50 +450,15 @@ no_more_servers:
446 if (fc->flags & AFS_FS_CURSOR_VBUSY) 450 if (fc->flags & AFS_FS_CURSOR_VBUSY)
447 goto restart_from_beginning; 451 goto restart_from_beginning;
448 452
449 abort_code = 0; 453 e.error = -EDESTADDRREQ;
450 error = -EDESTADDRREQ; 454 e.responded = false;
451 for (i = 0; i < fc->server_list->nr_servers; i++) { 455 for (i = 0; i < fc->server_list->nr_servers; i++) {
452 struct afs_server *s = fc->server_list->servers[i].server; 456 struct afs_server *s = fc->server_list->servers[i].server;
453 int probe_error = READ_ONCE(s->probe.error);
454 457
455 switch (probe_error) { 458 afs_prioritise_error(&e, READ_ONCE(s->probe.error),
456 case 0: 459 s->probe.abort_code);
457 continue;
458 default:
459 if (error == -ETIMEDOUT ||
460 error == -ETIME)
461 continue;
462 case -ETIMEDOUT:
463 case -ETIME:
464 if (error == -ENOMEM ||
465 error == -ENONET)
466 continue;
467 case -ENOMEM:
468 case -ENONET:
469 if (error == -ENETUNREACH)
470 continue;
471 case -ENETUNREACH:
472 if (error == -EHOSTUNREACH)
473 continue;
474 case -EHOSTUNREACH:
475 if (error == -ECONNREFUSED)
476 continue;
477 case -ECONNREFUSED:
478 if (error == -ECONNRESET)
479 continue;
480 case -ECONNRESET: /* Responded, but call expired. */
481 if (error == -ECONNABORTED)
482 continue;
483 case -ECONNABORTED:
484 abort_code = s->probe.abort_code;
485 error = probe_error;
486 continue;
487 }
488 } 460 }
489 461
490 if (error == -ECONNABORTED)
491 error = afs_abort_to_error(abort_code);
492
493failed_set_error: 462failed_set_error:
494 fc->error = error; 463 fc->error = error;
495failed: 464failed:
@@ -553,8 +522,11 @@ bool afs_select_current_fileserver(struct afs_fs_cursor *fc)
553 _leave(" = f [abort]"); 522 _leave(" = f [abort]");
554 return false; 523 return false;
555 524
525 case -ERFKILL:
526 case -EADDRNOTAVAIL:
556 case -ENETUNREACH: 527 case -ENETUNREACH:
557 case -EHOSTUNREACH: 528 case -EHOSTUNREACH:
529 case -EHOSTDOWN:
558 case -ECONNREFUSED: 530 case -ECONNREFUSED:
559 case -ETIMEDOUT: 531 case -ETIMEDOUT:
560 case -ETIME: 532 case -ETIME:
@@ -633,6 +605,7 @@ int afs_end_vnode_operation(struct afs_fs_cursor *fc)
633 struct afs_net *net = afs_v2net(fc->vnode); 605 struct afs_net *net = afs_v2net(fc->vnode);
634 606
635 if (fc->error == -EDESTADDRREQ || 607 if (fc->error == -EDESTADDRREQ ||
608 fc->error == -EADDRNOTAVAIL ||
636 fc->error == -ENETUNREACH || 609 fc->error == -ENETUNREACH ||
637 fc->error == -EHOSTUNREACH) 610 fc->error == -EHOSTUNREACH)
638 afs_dump_edestaddrreq(fc); 611 afs_dump_edestaddrreq(fc);