DECLARE_RWSEM(afs_proc_cells_sem);
LIST_HEAD(afs_proc_cells);
-static struct list_head afs_cells = LIST_HEAD_INIT(afs_cells);
+static LIST_HEAD(afs_cells);
static DEFINE_RWLOCK(afs_cells_lock);
static DECLARE_RWSEM(afs_cells_sem); /* add/remove serialisation */
static DECLARE_WAIT_QUEUE_HEAD(afs_cells_freeable_wq);
static struct afs_cell *afs_cell_alloc(const char *name, char *vllist)
{
struct afs_cell *cell;
+ struct key *key;
size_t namelen;
char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp, *next;
int ret;
do {
*dp++ = toupper(*cp);
} while (*cp++);
- cell->anonymous_key = key_alloc(&key_type_rxrpc, keyname, 0, 0, current,
- KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA);
- if (IS_ERR(cell->anonymous_key)) {
- _debug("no key");
- ret = PTR_ERR(cell->anonymous_key);
- goto error;
- }
- ret = key_instantiate_and_link(cell->anonymous_key, NULL, 0,
- NULL, NULL);
- if (ret < 0) {
- _debug("instantiate failed");
+ key = rxrpc_get_null_key(keyname);
+ if (IS_ERR(key)) {
+ _debug("no key");
+ ret = PTR_ERR(key);
goto error;
}
+ cell->anonymous_key = key;
_debug("anon key %p{%x}",
cell->anonymous_key, key_serial(cell->anonymous_key));
_enter("%s,%s", name, vllist);
+ down_write(&afs_cells_sem);
+ read_lock(&afs_cells_lock);
+ list_for_each_entry(cell, &afs_cells, link) {
+ if (strcasecmp(cell->name, name) == 0)
+ goto duplicate_name;
+ }
+ read_unlock(&afs_cells_lock);
+
cell = afs_cell_alloc(name, vllist);
if (IS_ERR(cell)) {
_leave(" = %ld", PTR_ERR(cell));
+ up_write(&afs_cells_sem);
return cell;
}
- down_write(&afs_cells_sem);
-
/* add a proc directory for this cell */
ret = afs_proc_cell_setup(cell);
if (ret < 0)
kfree(cell);
_leave(" = %d", ret);
return ERR_PTR(ret);
+
+duplicate_name:
+ read_unlock(&afs_cells_lock);
+ up_write(&afs_cells_sem);
+ return ERR_PTR(-EEXIST);
}
/*