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;
/*
* 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;
/* 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;
}
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]");
}
_enter("");
- afs_put_cell(net->ws_cell);
+ afs_put_cell(net, net->ws_cell);
down_write(&net->cells_sem);
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;
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)) {
return 0;
iget_error:
- afs_put_server(server);
+ afs_put_server(afs_i2net(dir), server);
mkdir_error:
key_put(key);
error:
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)) {
return 0;
iget_error:
- afs_put_server(server);
+ afs_put_server(afs_i2net(dir), server);
create_error:
key_put(key);
error:
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)) {
return 0;
iget_error:
- afs_put_server(server);
+ afs_put_server(afs_i2net(dir), server);
create_error:
key_put(key);
error:
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;
}
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 */
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 *);
/*
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 *);
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 *,
goto done;
}
- afs_put_cell(cell);
+ afs_put_cell(net, cell);
printk("kAFS: Added new cell '%s'\n", name);
} else {
goto inval;
server = kzalloc(sizeof(struct afs_server), GFP_KERNEL);
if (server) {
atomic_set(&server->usage, 1);
+ server->net = cell->net;
server->cell = cell;
INIT_LIST_HEAD(&server->link);
* destroy a server record
* - removes from the cell list
*/
-void afs_put_server(struct afs_server *server)
+void afs_put_server(struct afs_net *net, struct afs_server *server)
{
- struct afs_net *net = server->cell->net;
-
if (!server)
return;
ASSERTCMP(server->cb_break_head, ==, server->cb_break_tail);
ASSERTCMP(atomic_read(&server->cb_break_n), ==, 0);
- afs_put_cell(server->cell);
+ afs_put_cell(server->net, server->cell);
kfree(server);
afs_dec_servers_outstanding(net);
}
false);
if (IS_ERR(cell))
return PTR_ERR(cell);
- afs_put_cell(params->cell);
+ afs_put_cell(params->net, params->cell);
params->cell = cell;
break;
cellnamesz, cellnamesz, cellname ?: "");
return PTR_ERR(cell);
}
- afs_put_cell(params->cell);
+ afs_put_cell(params->net, params->cell);
params->cell = cell;
}
static void afs_destroy_sbi(struct afs_super_info *as)
{
if (as) {
- afs_put_volume(as->net, as->volume);
- afs_put_cell(as->cell);
+ afs_put_volume(as->cell, as->volume);
+ afs_put_cell(as->net, as->cell);
afs_put_net(as->net);
kfree(as);
}
as = NULL;
}
- afs_put_cell(params.cell);
+ afs_put_cell(params.net, params.cell);
key_put(params.key);
_leave(" = 0 [%p]", sb);
return dget(sb->s_root);
error_as:
afs_destroy_sbi(as);
error:
- afs_put_cell(params.cell);
+ afs_put_cell(params.net, params.cell);
key_put(params.key);
_leave(" = %d", ret);
return ERR_PTR(ret);
/*
* destroy a dead volume location record
*/
-static void afs_vlocation_destroy(struct afs_vlocation *vl)
+static void afs_vlocation_destroy(struct afs_net *net, struct afs_vlocation *vl)
{
_enter("%p", vl);
#ifdef CONFIG_AFS_FSCACHE
fscache_relinquish_cookie(vl->cache, 0);
#endif
- afs_put_cell(vl->cell);
+ afs_put_cell(net, vl->cell);
kfree(vl);
}
while (!list_empty(&corpses)) {
vl = list_entry(corpses.next, struct afs_vlocation, grave);
list_del(&vl->grave);
- afs_vlocation_destroy(vl);
+ afs_vlocation_destroy(net, vl);
}
_leave("");
afs_get_server(server);
vnode->server = server;
- afs_put_server(old_server);
+ afs_put_server(afs_v2net(vnode), old_server);
/* insert into the server's vnode tree in FID order */
spin_lock(&server->fs_lock);
spin_unlock(&server->fs_lock);
vnode->server = NULL;
- afs_put_server(server);
+ afs_put_server(afs_v2net(vnode), server);
} else {
ASSERT(!vnode->cb_promised);
}
spin_unlock(&vnode->lock);
wake_up_all(&vnode->update_waitq);
- afs_put_server(oldserver);
+ afs_put_server(afs_v2net(vnode), oldserver);
_leave("");
}
if (auth_vnode)
afs_cache_permit(vnode, key, acl_order);
afs_vnode_finalise_status_update(vnode, server);
- afs_put_server(server);
+ afs_put_server(afs_v2net(vnode), server);
} else {
_debug("failed [%d]", ret);
afs_vnode_status_update_failed(vnode, ret);
/* adjust the flags */
if (ret == 0) {
afs_vnode_finalise_status_update(vnode, server);
- afs_put_server(server);
+ afs_put_server(afs_v2net(vnode), server);
} else {
afs_vnode_status_update_failed(vnode, ret);
}
/* adjust the flags */
if (ret == 0) {
afs_vnode_finalise_status_update(vnode, server);
- afs_put_server(server);
+ afs_put_server(afs_v2net(vnode), server);
} else {
afs_vnode_status_update_failed(vnode, ret);
}
if (ret == 0) {
afs_vnode_finalise_status_update(vnode, server);
afs_vnode_finalise_status_update(dvnode, server);
- afs_put_server(server);
+ afs_put_server(afs_v2net(dvnode), server);
} else {
afs_vnode_status_update_failed(vnode, ret);
afs_vnode_status_update_failed(dvnode, ret);
afs_vnode_finalise_status_update(orig_dvnode, server);
if (new_dvnode != orig_dvnode)
afs_vnode_finalise_status_update(new_dvnode, server);
- afs_put_server(server);
+ afs_put_server(afs_v2net(orig_dvnode), server);
} else {
afs_vnode_status_update_failed(orig_dvnode, ret);
if (new_dvnode != orig_dvnode)
/* adjust the flags */
if (ret == 0) {
afs_vnode_finalise_status_update(vnode, server);
- afs_put_server(server);
+ afs_put_server(afs_v2net(vnode), server);
} else {
afs_vnode_status_update_failed(vnode, ret);
}
/* adjust the flags */
if (ret == 0) {
afs_vnode_finalise_status_update(vnode, server);
- afs_put_server(server);
+ afs_put_server(afs_v2net(vnode), server);
} else {
afs_vnode_status_update_failed(vnode, ret);
}
/* adjust the flags */
if (ret == 0)
- afs_put_server(server);
+ afs_put_server(afs_v2net(vnode), server);
_leave(" = %d", ret);
return ret;
/* adjust the flags */
if (ret == 0)
- afs_put_server(server);
+ afs_put_server(afs_v2net(vnode), server);
_leave(" = %d", ret);
return ret;
/* adjust the flags */
if (ret == 0)
- afs_put_server(server);
+ afs_put_server(afs_v2net(vnode), server);
_leave(" = %d", ret);
return ret;
/* adjust the flags */
if (ret == 0)
- afs_put_server(server);
+ afs_put_server(afs_v2net(vnode), server);
_leave(" = %d", ret);
return ret;
up_write(¶ms->cell->vl_sem);
for (loop = volume->nservers - 1; loop >= 0; loop--)
- afs_put_server(volume->servers[loop]);
+ afs_put_server(params->net, volume->servers[loop]);
kfree(volume);
goto error;
/*
* destroy a volume record
*/
-void afs_put_volume(struct afs_net *net, struct afs_volume *volume)
+void afs_put_volume(struct afs_cell *cell, struct afs_volume *volume)
{
struct afs_vlocation *vlocation;
int loop;
/* to prevent a race, the decrement and the dequeue must be effectively
* atomic */
- down_write(&vlocation->cell->vl_sem);
+ down_write(&cell->vl_sem);
if (likely(!atomic_dec_and_test(&volume->usage))) {
up_write(&vlocation->cell->vl_sem);
vlocation->vols[volume->type] = NULL;
- up_write(&vlocation->cell->vl_sem);
+ up_write(&cell->vl_sem);
/* finish cleaning up the volume */
#ifdef CONFIG_AFS_FSCACHE
fscache_relinquish_cookie(volume->cache, 0);
#endif
- afs_put_vlocation(net, vlocation);
+ afs_put_vlocation(cell->net, vlocation);
for (loop = volume->nservers - 1; loop >= 0; loop--)
- afs_put_server(volume->servers[loop]);
+ afs_put_server(cell->net, volume->servers[loop]);
kfree(volume);
sizeof(volume->servers[loop]) *
(volume->nservers - loop));
volume->servers[volume->nservers] = NULL;
- afs_put_server(server);
+ afs_put_server(afs_v2net(vnode), server);
volume->rjservers++;
if (volume->nservers > 0)
* no longer registered
*/
up_write(&volume->server_sem);
- afs_put_server(server);
+ afs_put_server(afs_v2net(vnode), server);
_leave(" [completely rejected]");
return 1;
case -ENOMEM:
case -ENONET:
/* tell the caller to accept the result */
- afs_put_server(server);
+ afs_put_server(afs_v2net(vnode), server);
_leave(" [local failure]");
return 1;
}
try_next_server_upw:
up_write(&volume->server_sem);
try_next_server:
- afs_put_server(server);
+ afs_put_server(afs_v2net(vnode), server);
_leave(" [try next server]");
return 0;
}