Skip to content

Commit 977e5f8

Browse files
committed
afs: Split the usage count on struct afs_server
Split the usage count on the afs_server struct to have an active count that registers who's actually using it separately from the reference count on the object. This allows a future patch to dispatch polling probes without advancing the "unuse" time into the future each time we emit a probe, which would otherwise prevent unused server records from expiring. Included in this: (1) The latter part of afs_destroy_server() in which the RCU destruction of afs_server objects is invoked and the outstanding server count is decremented is split out into __afs_put_server(). (2) afs_put_server() now calls __afs_put_server() rather then setting the management timer. (3) The calls begun by afs_fs_give_up_all_callbacks() and afs_fs_get_capabilities() can now take a ref on the server record, so afs_destroy_server() can just drop its ref and needn't wait for the completion of these calls. They'll put the ref when they're done. (4) Because of (3), afs_fs_probe_done() no longer needs to wake up afs_destroy_server() with server->probe_outstanding. (5) afs_gc_servers can be simplified. It only needs to check if server->active is 0 rather than playing games with the refcount. (6) afs_manage_servers() can propose a server for gc if usage == 0 rather than if ref == 1. The gc is effected by (5). Signed-off-by: David Howells <[email protected]>
1 parent 8100680 commit 977e5f8

File tree

9 files changed

+131
-71
lines changed

9 files changed

+131
-71
lines changed

fs/afs/cmservice.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,9 @@ static void SRXAFSCB_CallBack(struct work_struct *work)
268268
* to maintain cache coherency.
269269
*/
270270
if (call->server) {
271-
trace_afs_server(call->server, atomic_read(&call->server->usage),
271+
trace_afs_server(call->server,
272+
atomic_read(&call->server->ref),
273+
atomic_read(&call->server->active),
272274
afs_server_trace_callback);
273275
afs_break_callbacks(call->server, call->count, call->request);
274276
}

fs/afs/fs_probe.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ static bool afs_fs_probe_done(struct afs_server *server)
1616
if (!atomic_dec_and_test(&server->probe_outstanding))
1717
return false;
1818

19-
wake_up_var(&server->probe_outstanding);
2019
clear_bit_unlock(AFS_SERVER_FL_PROBING, &server->flags);
2120
wake_up_bit(&server->flags, AFS_SERVER_FL_PROBING);
2221
return true;

fs/afs/fsclient.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1842,7 +1842,7 @@ int afs_fs_give_up_all_callbacks(struct afs_net *net,
18421842
bp = call->request;
18431843
*bp++ = htonl(FSGIVEUPALLCALLBACKS);
18441844

1845-
/* Can't take a ref on server */
1845+
call->server = afs_use_server(server, afs_server_trace_give_up_cb);
18461846
afs_make_call(ac, call, GFP_NOFS);
18471847
return afs_wait_for_call_to_complete(call, ac);
18481848
}
@@ -1924,7 +1924,7 @@ struct afs_call *afs_fs_get_capabilities(struct afs_net *net,
19241924
return ERR_PTR(-ENOMEM);
19251925

19261926
call->key = key;
1927-
call->server = afs_get_server(server, afs_server_trace_get_caps);
1927+
call->server = afs_use_server(server, afs_server_trace_get_caps);
19281928
call->server_index = server_index;
19291929
call->upgrade = true;
19301930
call->async = true;
@@ -1934,7 +1934,6 @@ struct afs_call *afs_fs_get_capabilities(struct afs_net *net,
19341934
bp = call->request;
19351935
*bp++ = htonl(FSGETCAPABILITIES);
19361936

1937-
/* Can't take a ref on server */
19381937
trace_afs_make_fs_call(call, NULL);
19391938
afs_make_call(ac, call, GFP_NOFS);
19401939
return call;

fs/afs/internal.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ struct afs_server {
498498
struct hlist_node addr6_link; /* Link in net->fs_addresses6 */
499499
struct hlist_node proc_link; /* Link in net->fs_proc */
500500
struct afs_server *gc_next; /* Next server in manager's list */
501-
time64_t put_time; /* Time at which last put */
501+
time64_t unuse_time; /* Time at which last unused */
502502
unsigned long flags;
503503
#define AFS_SERVER_FL_NOT_READY 1 /* The record is not ready for use */
504504
#define AFS_SERVER_FL_NOT_FOUND 2 /* VL server says no such server */
@@ -512,7 +512,8 @@ struct afs_server {
512512
#define AFS_SERVER_FL_NO_RM2 10 /* Fileserver doesn't support YFS.RemoveFile2 */
513513
#define AFS_SERVER_FL_HAVE_EPOCH 11 /* ->epoch is valid */
514514
#define AFS_SERVER_FL_NEEDS_UPDATE 12 /* Fileserver address list is out of date */
515-
atomic_t usage;
515+
atomic_t ref; /* Object refcount */
516+
atomic_t active; /* Active user count */
516517
u32 addr_version; /* Address list version */
517518
u32 cm_epoch; /* Server RxRPC epoch */
518519
unsigned int debug_id; /* Debugging ID for traces */
@@ -1244,6 +1245,9 @@ extern struct afs_server *afs_find_server(struct afs_net *,
12441245
extern struct afs_server *afs_find_server_by_uuid(struct afs_net *, const uuid_t *);
12451246
extern struct afs_server *afs_lookup_server(struct afs_cell *, struct key *, const uuid_t *, u32);
12461247
extern struct afs_server *afs_get_server(struct afs_server *, enum afs_server_trace);
1248+
extern struct afs_server *afs_use_server(struct afs_server *, enum afs_server_trace);
1249+
extern void afs_unuse_server(struct afs_net *, struct afs_server *, enum afs_server_trace);
1250+
extern void afs_unuse_server_notime(struct afs_net *, struct afs_server *, enum afs_server_trace);
12471251
extern void afs_put_server(struct afs_net *, struct afs_server *, enum afs_server_trace);
12481252
extern void afs_manage_servers(struct work_struct *);
12491253
extern void afs_servers_timer(struct timer_list *);

fs/afs/proc.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -378,19 +378,20 @@ static int afs_proc_servers_show(struct seq_file *m, void *v)
378378
int i;
379379

380380
if (v == SEQ_START_TOKEN) {
381-
seq_puts(m, "UUID USE ADDR\n");
381+
seq_puts(m, "UUID REF ACT ADDR\n");
382382
return 0;
383383
}
384384

385385
server = list_entry(v, struct afs_server, proc_link);
386386
alist = rcu_dereference(server->addresses);
387-
seq_printf(m, "%pU %3d %pISpc%s\n",
387+
seq_printf(m, "%pU %3d %3d %pISpc%s\n",
388388
&server->uuid,
389-
atomic_read(&server->usage),
389+
atomic_read(&server->ref),
390+
atomic_read(&server->active),
390391
&alist->addrs[0].transport,
391392
alist->preferred == 0 ? "*" : "");
392393
for (i = 1; i < alist->nr_addrs; i++)
393-
seq_printf(m, " %pISpc%s\n",
394+
seq_printf(m, " %pISpc%s\n",
394395
&alist->addrs[i].transport,
395396
alist->preferred == i ? "*" : "");
396397
return 0;

fs/afs/rxrpc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ void afs_put_call(struct afs_call *call)
183183
if (call->type->destructor)
184184
call->type->destructor(call);
185185

186-
afs_put_server(call->net, call->server, afs_server_trace_put_call);
186+
afs_unuse_server_notime(call->net, call->server, afs_server_trace_put_call);
187187
afs_put_cb_interest(call->net, call->cbi);
188188
afs_put_addrlist(call->alist);
189189
kfree(call->request);

0 commit comments

Comments
 (0)