Commit 1f0fc337 authored by David Howells's avatar David Howells Committed by Jakub Kicinski
Browse files

afs: Give an afs_server object a ref on the afs_cell object it points to



Give an afs_server object a ref on the afs_cell object it points to so that
the cell doesn't get deleted before the server record.

Whilst this is circular (cell -> vol -> server_list -> server -> cell), the
ref only pins the memory, not the lifetime as that's controlled by the
activity counter.  When the volume's activity counter reaches 0, it
detaches from the cell and discards its server list; when a cell's activity
counter reaches 0, it discards its root volume.  At that point, the
circularity is cut.

Fixes: d2ddc776 ("afs: Overhaul volume and server record caching and fileserver rotation")
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/20250218192250.296870-6-dhowells@redhat.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent add117e4
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -163,6 +163,8 @@ static struct afs_server *afs_install_server(struct afs_cell *cell,
	rb_insert_color(&server->uuid_rb, &net->fs_servers);
	hlist_add_head_rcu(&server->proc_link, &net->fs_proc);

	afs_get_cell(cell, afs_cell_trace_get_server);

added_dup:
	write_seqlock(&net->fs_addr_lock);
	estate = rcu_dereference_protected(server->endpoint_state,
@@ -442,6 +444,7 @@ static void afs_server_rcu(struct rcu_head *rcu)
			 atomic_read(&server->active), afs_server_trace_free);
	afs_put_endpoint_state(rcu_access_pointer(server->endpoint_state),
			       afs_estate_trace_put_server);
	afs_put_cell(server->cell, afs_cell_trace_put_server);
	kfree(server);
}

+2 −0
Original line number Diff line number Diff line
@@ -174,6 +174,7 @@ enum yfs_cm_operation {
	EM(afs_cell_trace_get_queue_dns,	"GET q-dns ") \
	EM(afs_cell_trace_get_queue_manage,	"GET q-mng ") \
	EM(afs_cell_trace_get_queue_new,	"GET q-new ") \
	EM(afs_cell_trace_get_server,		"GET server") \
	EM(afs_cell_trace_get_vol,		"GET vol   ") \
	EM(afs_cell_trace_insert,		"INSERT    ") \
	EM(afs_cell_trace_manage,		"MANAGE    ") \
@@ -182,6 +183,7 @@ enum yfs_cm_operation {
	EM(afs_cell_trace_put_destroy,		"PUT destry") \
	EM(afs_cell_trace_put_queue_work,	"PUT q-work") \
	EM(afs_cell_trace_put_queue_fail,	"PUT q-fail") \
	EM(afs_cell_trace_put_server,		"PUT server") \
	EM(afs_cell_trace_put_vol,		"PUT vol   ") \
	EM(afs_cell_trace_see_source,		"SEE source") \
	EM(afs_cell_trace_see_ws,		"SEE ws    ") \