Skip to content

Commit 1702e06

Browse files
oleg-nesterovdhowells
authored andcommitted
afs: fix the usage of read_seqbegin_or_lock() in afs_find_server*()
David Howells says: (5) afs_find_server(). There could be a lot of servers in the list and each server can have multiple addresses, so I think this would be better with an exclusive second pass. The server list isn't likely to change all that often, but when it does change, there's a good chance several servers are going to be added/removed one after the other. Further, this is only going to be used for incoming cache management/callback requests from the server, which hopefully aren't going to happen too often - but it is remotely drivable. (6) afs_find_server_by_uuid(). Similarly to (5), there could be a lot of servers to search through, but they are in a tree not a flat list, so it should be faster to process. Again, it's not likely to change that often and, again, when it does change it's likely to involve multiple changes. This can be driven remotely by an incoming cache management request but is mostly going to be driven by setting up or reconfiguring a volume's server list - something that also isn't likely to happen often. Make the "seq" counter odd on the 2nd pass, otherwise read_seqbegin_or_lock() never takes the lock. Signed-off-by: Oleg Nesterov <[email protected]> Signed-off-by: David Howells <[email protected]> cc: Marc Dionne <[email protected]> cc: [email protected] Link: https://lore.kernel.org/r/[email protected]/
1 parent 4121b43 commit 1702e06

File tree

1 file changed

+4
-3
lines changed

1 file changed

+4
-3
lines changed

fs/afs/server.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,15 @@ struct afs_server *afs_find_server(struct afs_net *net,
2727
const struct afs_addr_list *alist;
2828
struct afs_server *server = NULL;
2929
unsigned int i;
30-
int seq = 0, diff;
30+
int seq = 1, diff;
3131

3232
rcu_read_lock();
3333

3434
do {
3535
if (server)
3636
afs_unuse_server_notime(net, server, afs_server_trace_put_find_rsq);
3737
server = NULL;
38+
seq++; /* 2 on the 1st/lockless path, otherwise odd */
3839
read_seqbegin_or_lock(&net->fs_addr_lock, &seq);
3940

4041
if (srx->transport.family == AF_INET6) {
@@ -90,7 +91,7 @@ struct afs_server *afs_find_server_by_uuid(struct afs_net *net, const uuid_t *uu
9091
{
9192
struct afs_server *server = NULL;
9293
struct rb_node *p;
93-
int diff, seq = 0;
94+
int diff, seq = 1;
9495

9596
_enter("%pU", uuid);
9697

@@ -102,7 +103,7 @@ struct afs_server *afs_find_server_by_uuid(struct afs_net *net, const uuid_t *uu
102103
if (server)
103104
afs_unuse_server(net, server, afs_server_trace_put_uuid_rsq);
104105
server = NULL;
105-
106+
seq++; /* 2 on the 1st/lockless path, otherwise odd */
106107
read_seqbegin_or_lock(&net->fs_lock, &seq);
107108

108109
p = net->fs_servers.rb_node;

0 commit comments

Comments
 (0)