Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ed900b1 authored by David Howells's avatar David Howells
Browse files

afs: Push the net ns pointer to more places



Push the network namespace pointer to more places in AFS, including the
afs_server structure (which doesn't hold a ref on the netns).

In particular, afs_put_cell() now takes requires a net ns parameter so that
it can safely alter the netns after decrementing the cell usage count - the
cell will be deallocated by a background thread after being cached for a
period, which means that it's not safe to access it after reducing its
usage count.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent 49566f6f
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -251,7 +251,7 @@ int afs_cell_init(struct afs_net *net, char *rootcell)
	old_root = net->ws_cell;
	net->ws_cell = new_root;
	write_unlock(&net->cells_lock);
	afs_put_cell(old_root);
	afs_put_cell(net, old_root);

	_leave(" = 0");
	return 0;
@@ -336,7 +336,7 @@ struct afs_cell *afs_get_cell_maybe(struct afs_cell *cell)
/*
 * destroy a cell record
 */
void afs_put_cell(struct afs_cell *cell)
void afs_put_cell(struct afs_net *net, struct afs_cell *cell)
{
	if (!cell)
		return;
@@ -347,10 +347,10 @@ void afs_put_cell(struct afs_cell *cell)

	/* to prevent a race, the decrement and the dequeue must be effectively
	 * atomic */
	write_lock(&cell->net->cells_lock);
	write_lock(&net->cells_lock);

	if (likely(!atomic_dec_and_test(&cell->usage))) {
		write_unlock(&cell->net->cells_lock);
		write_unlock(&net->cells_lock);
		_leave("");
		return;
	}
@@ -358,9 +358,9 @@ void afs_put_cell(struct afs_cell *cell)
	ASSERT(list_empty(&cell->servers));
	ASSERT(list_empty(&cell->vl_list));

	wake_up(&cell->net->cells_freeable_wq);
	wake_up(&net->cells_freeable_wq);

	write_unlock(&cell->net->cells_lock);
	write_unlock(&net->cells_lock);

	_leave(" [unused]");
}
@@ -424,7 +424,7 @@ void afs_cell_purge(struct afs_net *net)

	_enter("");

	afs_put_cell(net->ws_cell);
	afs_put_cell(net, net->ws_cell);

	down_write(&net->cells_sem);

+1 −1
Original line number Diff line number Diff line
@@ -151,7 +151,7 @@ static void afs_cm_destructor(struct afs_call *call)
		afs_break_callbacks(call->server, call->count, call->request);
	}

	afs_put_server(call->server);
	afs_put_server(call->net, call->server);
	call->server = NULL;
	kfree(call->buffer);
	call->buffer = NULL;
+6 −6
Original line number Diff line number Diff line
@@ -771,7 +771,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
	vnode->update_cnt++;
	spin_unlock(&vnode->lock);
	afs_vnode_finalise_status_update(vnode, server);
	afs_put_server(server);
	afs_put_server(afs_i2net(dir), server);

	d_instantiate(dentry, inode);
	if (d_unhashed(dentry)) {
@@ -783,7 +783,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
	return 0;

iget_error:
	afs_put_server(server);
	afs_put_server(afs_i2net(dir), server);
mkdir_error:
	key_put(key);
error:
@@ -948,7 +948,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
	vnode->update_cnt++;
	spin_unlock(&vnode->lock);
	afs_vnode_finalise_status_update(vnode, server);
	afs_put_server(server);
	afs_put_server(afs_i2net(dir), server);

	d_instantiate(dentry, inode);
	if (d_unhashed(dentry)) {
@@ -960,7 +960,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
	return 0;

iget_error:
	afs_put_server(server);
	afs_put_server(afs_i2net(dir), server);
create_error:
	key_put(key);
error:
@@ -1060,7 +1060,7 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,
	vnode->update_cnt++;
	spin_unlock(&vnode->lock);
	afs_vnode_finalise_status_update(vnode, server);
	afs_put_server(server);
	afs_put_server(afs_i2net(dir), server);

	d_instantiate(dentry, inode);
	if (d_unhashed(dentry)) {
@@ -1072,7 +1072,7 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,
	return 0;

iget_error:
	afs_put_server(server);
	afs_put_server(afs_i2net(dir), server);
create_error:
	key_put(key);
error:
+1 −1
Original line number Diff line number Diff line
@@ -437,7 +437,7 @@ void afs_evict_inode(struct inode *inode)
		spin_lock(&vnode->server->fs_lock);
		rb_erase(&vnode->server_rb, &vnode->server->fs_vnodes);
		spin_unlock(&vnode->server->fs_lock);
		afs_put_server(vnode->server);
		afs_put_server(afs_i2net(inode), vnode->server);
		vnode->server = NULL;
	}

+4 −3
Original line number Diff line number Diff line
@@ -335,6 +335,7 @@ struct afs_server {
	atomic_t		usage;
	time64_t		time_of_death;	/* time at which put reduced usage to 0 */
	struct in_addr		addr;		/* server address */
	struct afs_net		*net;		/* Network namespace in which the server resides */
	struct afs_cell		*cell;		/* cell in which server resides */
	struct list_head	link;		/* link in cell's server list */
	struct list_head	grave;		/* link in master graveyard list */
@@ -513,7 +514,7 @@ extern int afs_cell_init(struct afs_net *, char *);
extern struct afs_cell *afs_cell_create(struct afs_net *, const char *, unsigned, char *, bool);
extern struct afs_cell *afs_cell_lookup(struct afs_net *, const char *, unsigned, bool);
extern struct afs_cell *afs_grab_cell(struct afs_cell *);
extern void afs_put_cell(struct afs_cell *);
extern void afs_put_cell(struct afs_net *, struct afs_cell *);
extern void __net_exit afs_cell_purge(struct afs_net *);

/*
@@ -713,7 +714,7 @@ extern struct afs_server *afs_lookup_server(struct afs_cell *,
					    const struct in_addr *);
extern struct afs_server *afs_find_server(struct afs_net *,
					  const struct sockaddr_rxrpc *);
extern void afs_put_server(struct afs_server *);
extern void afs_put_server(struct afs_net *, struct afs_server *);
extern void afs_reap_server(struct work_struct *);
extern void __net_exit afs_purge_servers(struct afs_net *);

@@ -802,7 +803,7 @@ static inline struct afs_volume *afs_get_volume(struct afs_volume *volume)
	return volume;
}

extern void afs_put_volume(struct afs_net *, struct afs_volume *);
extern void afs_put_volume(struct afs_cell *, struct afs_volume *);
extern struct afs_volume *afs_volume_lookup(struct afs_mount_params *);
extern struct afs_server *afs_volume_pick_fileserver(struct afs_vnode *);
extern int afs_volume_release_fileserver(struct afs_vnode *,
Loading