Skip to content

Commit 40e8b52

Browse files
committed
afs: Use the per-peer app data provided by rxrpc
Make use of the per-peer application data that rxrpc now allows the application to store on the rxrpc_peer struct to hold a back pointer to the afs_server record that peer represents an endpoint for. Then, when a call comes in to the AFS cache manager, this can be used to map it to the correct server record rather than having to use a UUID-to-server mapping table and having to do an additional lookup. Signed-off-by: David Howells <[email protected]> cc: Marc Dionne <[email protected]> cc: [email protected] cc: [email protected] Link: https://lore.kernel.org/r/[email protected]/ # v1 Link: https://lore.kernel.org/r/[email protected]/ # v4
1 parent f3a123b commit 40e8b52

File tree

9 files changed

+120
-123
lines changed

9 files changed

+120
-123
lines changed

fs/afs/addr_list.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,3 +362,53 @@ int afs_merge_fs_addr6(struct afs_net *net, struct afs_addr_list *alist,
362362
alist->nr_addrs++;
363363
return 0;
364364
}
365+
366+
/*
367+
* Set the app data on the rxrpc peers an address list points to
368+
*/
369+
void afs_set_peer_appdata(struct afs_server *server,
370+
struct afs_addr_list *old_alist,
371+
struct afs_addr_list *new_alist)
372+
{
373+
unsigned long data = (unsigned long)server;
374+
int n = 0, o = 0;
375+
376+
if (!old_alist) {
377+
/* New server. Just set all. */
378+
for (; n < new_alist->nr_addrs; n++)
379+
rxrpc_kernel_set_peer_data(new_alist->addrs[n].peer, data);
380+
return;
381+
}
382+
if (!new_alist) {
383+
/* Dead server. Just remove all. */
384+
for (; o < old_alist->nr_addrs; o++)
385+
rxrpc_kernel_set_peer_data(old_alist->addrs[o].peer, 0);
386+
return;
387+
}
388+
389+
/* Walk through the two lists simultaneously, setting new peers and
390+
* clearing old ones. The two lists are ordered by pointer to peer
391+
* record.
392+
*/
393+
while (n < new_alist->nr_addrs && o < old_alist->nr_addrs) {
394+
struct rxrpc_peer *pn = new_alist->addrs[n].peer;
395+
struct rxrpc_peer *po = old_alist->addrs[o].peer;
396+
397+
if (pn == po)
398+
continue;
399+
if (pn < po) {
400+
rxrpc_kernel_set_peer_data(pn, data);
401+
n++;
402+
} else {
403+
rxrpc_kernel_set_peer_data(po, 0);
404+
o++;
405+
}
406+
}
407+
408+
if (n < new_alist->nr_addrs)
409+
for (; n < new_alist->nr_addrs; n++)
410+
rxrpc_kernel_set_peer_data(new_alist->addrs[n].peer, data);
411+
if (o < old_alist->nr_addrs)
412+
for (; o < old_alist->nr_addrs; o++)
413+
rxrpc_kernel_set_peer_data(old_alist->addrs[o].peer, 0);
414+
}

fs/afs/cmservice.c

Lines changed: 13 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -138,49 +138,6 @@ bool afs_cm_incoming_call(struct afs_call *call)
138138
}
139139
}
140140

141-
/*
142-
* Find the server record by peer address and record a probe to the cache
143-
* manager from a server.
144-
*/
145-
static int afs_find_cm_server_by_peer(struct afs_call *call)
146-
{
147-
struct sockaddr_rxrpc srx;
148-
struct afs_server *server;
149-
struct rxrpc_peer *peer;
150-
151-
peer = rxrpc_kernel_get_call_peer(call->net->socket, call->rxcall);
152-
153-
server = afs_find_server(call->net, peer);
154-
if (!server) {
155-
trace_afs_cm_no_server(call, &srx);
156-
return 0;
157-
}
158-
159-
call->server = server;
160-
return 0;
161-
}
162-
163-
/*
164-
* Find the server record by server UUID and record a probe to the cache
165-
* manager from a server.
166-
*/
167-
static int afs_find_cm_server_by_uuid(struct afs_call *call,
168-
struct afs_uuid *uuid)
169-
{
170-
struct afs_server *server;
171-
172-
rcu_read_lock();
173-
server = afs_find_server_by_uuid(call->net, call->request);
174-
rcu_read_unlock();
175-
if (!server) {
176-
trace_afs_cm_no_server_u(call, call->request);
177-
return 0;
178-
}
179-
180-
call->server = server;
181-
return 0;
182-
}
183-
184141
/*
185142
* Clean up a cache manager call.
186143
*/
@@ -322,10 +279,7 @@ static int afs_deliver_cb_callback(struct afs_call *call)
322279

323280
if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
324281
return afs_io_error(call, afs_io_error_cm_reply);
325-
326-
/* we'll need the file server record as that tells us which set of
327-
* vnodes to operate upon */
328-
return afs_find_cm_server_by_peer(call);
282+
return 0;
329283
}
330284

331285
/*
@@ -349,18 +303,10 @@ static void SRXAFSCB_InitCallBackState(struct work_struct *work)
349303
*/
350304
static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
351305
{
352-
int ret;
353-
354306
_enter("");
355307

356308
afs_extract_discard(call, 0);
357-
ret = afs_extract_data(call, false);
358-
if (ret < 0)
359-
return ret;
360-
361-
/* we'll need the file server record as that tells us which set of
362-
* vnodes to operate upon */
363-
return afs_find_cm_server_by_peer(call);
309+
return afs_extract_data(call, false);
364310
}
365311

366312
/*
@@ -373,8 +319,6 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
373319
__be32 *b;
374320
int ret;
375321

376-
_enter("");
377-
378322
_enter("{%u}", call->unmarshall);
379323

380324
switch (call->unmarshall) {
@@ -421,9 +365,13 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
421365
if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
422366
return afs_io_error(call, afs_io_error_cm_reply);
423367

424-
/* we'll need the file server record as that tells us which set of
425-
* vnodes to operate upon */
426-
return afs_find_cm_server_by_uuid(call, call->request);
368+
if (memcmp(call->request, &call->server->_uuid, sizeof(call->server->_uuid)) != 0) {
369+
pr_notice("Callback UUID does not match fileserver UUID\n");
370+
trace_afs_cm_no_server_u(call, call->request);
371+
return 0;
372+
}
373+
374+
return 0;
427375
}
428376

429377
/*
@@ -455,7 +403,7 @@ static int afs_deliver_cb_probe(struct afs_call *call)
455403

456404
if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
457405
return afs_io_error(call, afs_io_error_cm_reply);
458-
return afs_find_cm_server_by_peer(call);
406+
return 0;
459407
}
460408

461409
/*
@@ -533,7 +481,7 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call)
533481

534482
if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
535483
return afs_io_error(call, afs_io_error_cm_reply);
536-
return afs_find_cm_server_by_peer(call);
484+
return 0;
537485
}
538486

539487
/*
@@ -593,7 +541,7 @@ static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call)
593541

594542
if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
595543
return afs_io_error(call, afs_io_error_cm_reply);
596-
return afs_find_cm_server_by_peer(call);
544+
return 0;
597545
}
598546

599547
/*
@@ -667,9 +615,5 @@ static int afs_deliver_yfs_cb_callback(struct afs_call *call)
667615

668616
if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
669617
return afs_io_error(call, afs_io_error_cm_reply);
670-
671-
/* We'll need the file server record as that tells us which set of
672-
* vnodes to operate upon.
673-
*/
674-
return afs_find_cm_server_by_peer(call);
618+
return 0;
675619
}

fs/afs/fs_probe.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -235,42 +235,52 @@ void afs_fileserver_probe_result(struct afs_call *call)
235235
* Probe all of a fileserver's addresses to find out the best route and to
236236
* query its capabilities.
237237
*/
238-
void afs_fs_probe_fileserver(struct afs_net *net, struct afs_server *server,
239-
struct afs_addr_list *new_alist, struct key *key)
238+
int afs_fs_probe_fileserver(struct afs_net *net, struct afs_server *server,
239+
struct afs_addr_list *new_alist, struct key *key)
240240
{
241241
struct afs_endpoint_state *estate, *old;
242-
struct afs_addr_list *alist;
242+
struct afs_addr_list *old_alist = NULL, *alist;
243243
unsigned long unprobed;
244244

245245
_enter("%pU", &server->uuid);
246246

247247
estate = kzalloc(sizeof(*estate), GFP_KERNEL);
248248
if (!estate)
249-
return;
249+
return -ENOMEM;
250250

251-
refcount_set(&estate->ref, 1);
251+
refcount_set(&estate->ref, 2);
252252
estate->server_id = server->debug_id;
253253
estate->rtt = UINT_MAX;
254254

255255
write_lock(&server->fs_lock);
256256

257257
old = rcu_dereference_protected(server->endpoint_state,
258258
lockdep_is_held(&server->fs_lock));
259-
estate->responsive_set = old->responsive_set;
260-
estate->addresses = afs_get_addrlist(new_alist ?: old->addresses,
261-
afs_alist_trace_get_estate);
259+
if (old) {
260+
estate->responsive_set = old->responsive_set;
261+
if (!new_alist)
262+
new_alist = old->addresses;
263+
}
264+
265+
if (old_alist != new_alist)
266+
afs_set_peer_appdata(server, old_alist, new_alist);
267+
268+
estate->addresses = afs_get_addrlist(new_alist, afs_alist_trace_get_estate);
262269
alist = estate->addresses;
263270
estate->probe_seq = ++server->probe_counter;
264271
atomic_set(&estate->nr_probing, alist->nr_addrs);
265272

273+
if (new_alist)
274+
server->addr_version = new_alist->version;
266275
rcu_assign_pointer(server->endpoint_state, estate);
267-
set_bit(AFS_ESTATE_SUPERSEDED, &old->flags);
268276
write_unlock(&server->fs_lock);
277+
if (old)
278+
set_bit(AFS_ESTATE_SUPERSEDED, &old->flags);
269279

270280
trace_afs_estate(estate->server_id, estate->probe_seq, refcount_read(&estate->ref),
271281
afs_estate_trace_alloc_probe);
272282

273-
afs_get_address_preferences(net, alist);
283+
afs_get_address_preferences(net, new_alist);
274284

275285
server->probed_at = jiffies;
276286
unprobed = (1UL << alist->nr_addrs) - 1;
@@ -293,6 +303,8 @@ void afs_fs_probe_fileserver(struct afs_net *net, struct afs_server *server,
293303
}
294304

295305
afs_put_endpoint_state(old, afs_estate_trace_put_probe);
306+
afs_put_endpoint_state(estate, afs_estate_trace_put_probe);
307+
return 0;
296308
}
297309

298310
/*

fs/afs/internal.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,9 @@ extern int afs_merge_fs_addr4(struct afs_net *net, struct afs_addr_list *addr,
10101010
__be32 xdr, u16 port);
10111011
extern int afs_merge_fs_addr6(struct afs_net *net, struct afs_addr_list *addr,
10121012
__be32 *xdr, u16 port);
1013+
void afs_set_peer_appdata(struct afs_server *server,
1014+
struct afs_addr_list *old_alist,
1015+
struct afs_addr_list *new_alist);
10131016

10141017
/*
10151018
* addr_prefs.c
@@ -1207,8 +1210,8 @@ struct afs_endpoint_state *afs_get_endpoint_state(struct afs_endpoint_state *est
12071210
enum afs_estate_trace where);
12081211
void afs_put_endpoint_state(struct afs_endpoint_state *estate, enum afs_estate_trace where);
12091212
extern void afs_fileserver_probe_result(struct afs_call *);
1210-
void afs_fs_probe_fileserver(struct afs_net *net, struct afs_server *server,
1211-
struct afs_addr_list *new_addrs, struct key *key);
1213+
int afs_fs_probe_fileserver(struct afs_net *net, struct afs_server *server,
1214+
struct afs_addr_list *new_alist, struct key *key);
12121215
int afs_wait_for_fs_probes(struct afs_operation *op, struct afs_server_state *states, bool intr);
12131216
extern void afs_probe_fileserver(struct afs_net *, struct afs_server *);
12141217
extern void afs_fs_probe_dispatcher(struct work_struct *);
@@ -1509,7 +1512,7 @@ extern void __exit afs_clean_up_permit_cache(void);
15091512
*/
15101513
extern spinlock_t afs_server_peer_lock;
15111514

1512-
extern struct afs_server *afs_find_server(struct afs_net *, const struct rxrpc_peer *);
1515+
struct afs_server *afs_find_server(const struct rxrpc_peer *peer);
15131516
extern struct afs_server *afs_find_server_by_uuid(struct afs_net *, const uuid_t *);
15141517
extern struct afs_server *afs_lookup_server(struct afs_cell *, struct key *, const uuid_t *, u32);
15151518
extern struct afs_server *afs_get_server(struct afs_server *, enum afs_server_trace);

fs/afs/proc.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,8 +444,6 @@ static int afs_proc_servers_show(struct seq_file *m, void *v)
444444
}
445445

446446
server = list_entry(v, struct afs_server, proc_link);
447-
estate = rcu_dereference(server->endpoint_state);
448-
alist = estate->addresses;
449447
seq_printf(m, "%pU %3d %3d %s\n",
450448
&server->uuid,
451449
refcount_read(&server->ref),
@@ -455,10 +453,16 @@ static int afs_proc_servers_show(struct seq_file *m, void *v)
455453
server->flags, server->rtt);
456454
seq_printf(m, " - probe: last=%d\n",
457455
(int)(jiffies - server->probed_at) / HZ);
456+
457+
estate = rcu_dereference(server->endpoint_state);
458+
if (!estate)
459+
goto out;
458460
failed = estate->failed_set;
459461
seq_printf(m, " - ESTATE pq=%x np=%u rsp=%lx f=%lx\n",
460462
estate->probe_seq, atomic_read(&estate->nr_probing),
461463
estate->responsive_set, estate->failed_set);
464+
465+
alist = estate->addresses;
462466
seq_printf(m, " - ALIST v=%u ap=%u\n",
463467
alist->version, alist->addr_pref_version);
464468
for (i = 0; i < alist->nr_addrs; i++) {
@@ -471,6 +475,8 @@ static int afs_proc_servers_show(struct seq_file *m, void *v)
471475
rxrpc_kernel_get_srtt(addr->peer),
472476
addr->last_error, addr->prio);
473477
}
478+
479+
out:
474480
return 0;
475481
}
476482

fs/afs/rxrpc.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,8 +766,14 @@ static void afs_rx_discard_new_call(struct rxrpc_call *rxcall,
766766
static void afs_rx_new_call(struct sock *sk, struct rxrpc_call *rxcall,
767767
unsigned long user_call_ID)
768768
{
769+
struct afs_call *call = (struct afs_call *)user_call_ID;
769770
struct afs_net *net = afs_sock2net(sk);
770771

772+
call->peer = rxrpc_kernel_get_call_peer(sk->sk_socket, call->rxcall);
773+
call->server = afs_find_server(call->peer);
774+
if (!call->server)
775+
trace_afs_cm_no_server(call, rxrpc_kernel_remote_srx(call->peer));
776+
771777
queue_work(afs_wq, &net->charge_preallocation_work);
772778
}
773779

0 commit comments

Comments
 (0)