aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/internal.h
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2020-05-27 15:51:30 +0100
committerDavid Howells <dhowells@redhat.com>2020-06-04 15:37:57 +0100
commit3c4c4075fc61f5c37a0112b1dc8398025dc3e26a (patch)
treee78930a53e08984dc1b0f3519233baabd8a74c81 /fs/afs/internal.h
parentafs: Reorganise volume and server trees to be rooted on the cell (diff)
downloadlinux-dev-3c4c4075fc61f5c37a0112b1dc8398025dc3e26a.tar.xz
linux-dev-3c4c4075fc61f5c37a0112b1dc8398025dc3e26a.zip
afs: Fix the by-UUID server tree to allow servers with the same UUID
Whilst it shouldn't happen, it is possible for multiple fileservers to share a UUID, particularly if an entire cell has been duplicated, UUIDs and all. In such a case, it's not necessarily possible to map the effect of the CB.InitCallBackState3 incoming RPC to a specific server unambiguously by UUID and thus to a specific cell. Indeed, there's a problem whereby multiple server records may need to occupy the same spot in the rb_tree rooted in the afs_net struct. Fix this by allowing servers to form a list, with the head of the list in the tree. When the front entry in the list is removed, the second in the list just replaces it. afs_init_callback_state() then just goes down the line, poking each server in the list. This means that some servers will be unnecessarily poked, unfortunately. An alternative would be to route by call parameters. Reported-by: Jeffrey Altman <jaltman@auristor.com> Signed-off-by: David Howells <dhowells@redhat.com> Fixes: d2ddc776a458 ("afs: Overhaul volume and server record caching and fileserver rotation")
Diffstat (limited to '')
-rw-r--r--fs/afs/internal.h4
1 files changed, 3 insertions, 1 deletions
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index c64c2b47ece7..e0dc14d4d8b9 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -486,7 +486,9 @@ struct afs_server {
struct afs_addr_list __rcu *addresses;
struct afs_cell *cell; /* Cell to which belongs (pins ref) */
- struct rb_node uuid_rb; /* Link in cell->fs_servers */
+ struct rb_node uuid_rb; /* Link in net->fs_servers */
+ struct afs_server __rcu *uuid_next; /* Next server with same UUID */
+ struct afs_server *uuid_prev; /* Previous server with same UUID */
struct list_head probe_link; /* Link in net->fs_probe_list */
struct hlist_node addr4_link; /* Link in net->fs_addresses4 */
struct hlist_node addr6_link; /* Link in net->fs_addresses6 */