|
@@ -31,21 +31,20 @@ static struct afs_cell *afs_cell_root;
|
|
|
* allocate a cell record and fill in its name, VL server address list and
|
|
|
* allocate an anonymous key
|
|
|
*/
|
|
|
-static struct afs_cell *afs_cell_alloc(const char *name, char *vllist)
|
|
|
+static struct afs_cell *afs_cell_alloc(const char *name, unsigned namelen,
|
|
|
+ char *vllist)
|
|
|
{
|
|
|
struct afs_cell *cell;
|
|
|
struct key *key;
|
|
|
- size_t namelen;
|
|
|
char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp, *next;
|
|
|
char *dvllist = NULL, *_vllist = NULL;
|
|
|
char delimiter = ':';
|
|
|
int ret;
|
|
|
|
|
|
- _enter("%s,%s", name, vllist);
|
|
|
+ _enter("%*.*s,%s", namelen, namelen, name ?: "", vllist);
|
|
|
|
|
|
BUG_ON(!name); /* TODO: want to look up "this cell" in the cache */
|
|
|
|
|
|
- namelen = strlen(name);
|
|
|
if (namelen > AFS_MAXCELLNAME) {
|
|
|
_leave(" = -ENAMETOOLONG");
|
|
|
return ERR_PTR(-ENAMETOOLONG);
|
|
@@ -142,26 +141,29 @@ error:
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * create a cell record
|
|
|
- * - "name" is the name of the cell
|
|
|
- * - "vllist" is a colon separated list of IP addresses in "a.b.c.d" format
|
|
|
+ * afs_cell_crate() - create a cell record
|
|
|
+ * @name: is the name of the cell.
|
|
|
+ * @namsesz: is the strlen of the cell name.
|
|
|
+ * @vllist: is a colon separated list of IP addresses in "a.b.c.d" format.
|
|
|
+ * @retref: is T to return the cell reference when the cell exists.
|
|
|
*/
|
|
|
-struct afs_cell *afs_cell_create(const char *name, char *vllist)
|
|
|
+struct afs_cell *afs_cell_create(const char *name, unsigned namesz,
|
|
|
+ char *vllist, bool retref)
|
|
|
{
|
|
|
struct afs_cell *cell;
|
|
|
int ret;
|
|
|
|
|
|
- _enter("%s,%s", name, vllist);
|
|
|
+ _enter("%*.*s,%s", namesz, namesz, 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)
|
|
|
+ if (strncasecmp(cell->name, name, namesz) == 0)
|
|
|
goto duplicate_name;
|
|
|
}
|
|
|
read_unlock(&afs_cells_lock);
|
|
|
|
|
|
- cell = afs_cell_alloc(name, vllist);
|
|
|
+ cell = afs_cell_alloc(name, namesz, vllist);
|
|
|
if (IS_ERR(cell)) {
|
|
|
_leave(" = %ld", PTR_ERR(cell));
|
|
|
up_write(&afs_cells_sem);
|
|
@@ -201,8 +203,18 @@ error:
|
|
|
return ERR_PTR(ret);
|
|
|
|
|
|
duplicate_name:
|
|
|
+ if (retref && !IS_ERR(cell))
|
|
|
+ afs_get_cell(cell);
|
|
|
+
|
|
|
read_unlock(&afs_cells_lock);
|
|
|
up_write(&afs_cells_sem);
|
|
|
+
|
|
|
+ if (retref) {
|
|
|
+ _leave(" = %p", cell);
|
|
|
+ return cell;
|
|
|
+ }
|
|
|
+
|
|
|
+ _leave(" = -EEXIST");
|
|
|
return ERR_PTR(-EEXIST);
|
|
|
}
|
|
|
|
|
@@ -233,7 +245,7 @@ int afs_cell_init(char *rootcell)
|
|
|
*cp++ = 0;
|
|
|
|
|
|
/* allocate a cell record for the root cell */
|
|
|
- new_root = afs_cell_create(rootcell, cp);
|
|
|
+ new_root = afs_cell_create(rootcell, strlen(rootcell), cp, false);
|
|
|
if (IS_ERR(new_root)) {
|
|
|
_leave(" = %ld", PTR_ERR(new_root));
|
|
|
return PTR_ERR(new_root);
|
|
@@ -253,11 +265,12 @@ int afs_cell_init(char *rootcell)
|
|
|
/*
|
|
|
* lookup a cell record
|
|
|
*/
|
|
|
-struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz)
|
|
|
+struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz,
|
|
|
+ bool dns_cell)
|
|
|
{
|
|
|
struct afs_cell *cell;
|
|
|
|
|
|
- _enter("\"%*.*s\",", namesz, namesz, name ? name : "");
|
|
|
+ _enter("\"%*.*s\",", namesz, namesz, name ?: "");
|
|
|
|
|
|
down_read(&afs_cells_sem);
|
|
|
read_lock(&afs_cells_lock);
|
|
@@ -271,6 +284,8 @@ struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz)
|
|
|
}
|
|
|
}
|
|
|
cell = ERR_PTR(-ENOENT);
|
|
|
+ if (dns_cell)
|
|
|
+ goto create_cell;
|
|
|
found:
|
|
|
;
|
|
|
} else {
|
|
@@ -293,6 +308,15 @@ struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz)
|
|
|
up_read(&afs_cells_sem);
|
|
|
_leave(" = %p", cell);
|
|
|
return cell;
|
|
|
+
|
|
|
+create_cell:
|
|
|
+ read_unlock(&afs_cells_lock);
|
|
|
+ up_read(&afs_cells_sem);
|
|
|
+
|
|
|
+ cell = afs_cell_create(name, namesz, NULL, true);
|
|
|
+
|
|
|
+ _leave(" = %p", cell);
|
|
|
+ return cell;
|
|
|
}
|
|
|
|
|
|
#if 0
|