aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/cell.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/afs/cell.c')
-rw-r--r--fs/afs/cell.c52
1 files changed, 38 insertions, 14 deletions
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index d0765883430e..0d5eeadf6121 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -31,21 +31,20 @@ static struct afs_cell *afs_cell_root;
31 * allocate a cell record and fill in its name, VL server address list and 31 * allocate a cell record and fill in its name, VL server address list and
32 * allocate an anonymous key 32 * allocate an anonymous key
33 */ 33 */
34static struct afs_cell *afs_cell_alloc(const char *name, char *vllist) 34static struct afs_cell *afs_cell_alloc(const char *name, unsigned namelen,
35 char *vllist)
35{ 36{
36 struct afs_cell *cell; 37 struct afs_cell *cell;
37 struct key *key; 38 struct key *key;
38 size_t namelen;
39 char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp, *next; 39 char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp, *next;
40 char *dvllist = NULL, *_vllist = NULL; 40 char *dvllist = NULL, *_vllist = NULL;
41 char delimiter = ':'; 41 char delimiter = ':';
42 int ret; 42 int ret;
43 43
44 _enter("%s,%s", name, vllist); 44 _enter("%*.*s,%s", namelen, namelen, name ?: "", vllist);
45 45
46 BUG_ON(!name); /* TODO: want to look up "this cell" in the cache */ 46 BUG_ON(!name); /* TODO: want to look up "this cell" in the cache */
47 47
48 namelen = strlen(name);
49 if (namelen > AFS_MAXCELLNAME) { 48 if (namelen > AFS_MAXCELLNAME) {
50 _leave(" = -ENAMETOOLONG"); 49 _leave(" = -ENAMETOOLONG");
51 return ERR_PTR(-ENAMETOOLONG); 50 return ERR_PTR(-ENAMETOOLONG);
@@ -142,26 +141,29 @@ error:
142} 141}
143 142
144/* 143/*
145 * create a cell record 144 * afs_cell_crate() - create a cell record
146 * - "name" is the name of the cell 145 * @name: is the name of the cell.
147 * - "vllist" is a colon separated list of IP addresses in "a.b.c.d" format 146 * @namsesz: is the strlen of the cell name.
147 * @vllist: is a colon separated list of IP addresses in "a.b.c.d" format.
148 * @retref: is T to return the cell reference when the cell exists.
148 */ 149 */
149struct afs_cell *afs_cell_create(const char *name, char *vllist) 150struct afs_cell *afs_cell_create(const char *name, unsigned namesz,
151 char *vllist, bool retref)
150{ 152{
151 struct afs_cell *cell; 153 struct afs_cell *cell;
152 int ret; 154 int ret;
153 155
154 _enter("%s,%s", name, vllist); 156 _enter("%*.*s,%s", namesz, namesz, name ?: "", vllist);
155 157
156 down_write(&afs_cells_sem); 158 down_write(&afs_cells_sem);
157 read_lock(&afs_cells_lock); 159 read_lock(&afs_cells_lock);
158 list_for_each_entry(cell, &afs_cells, link) { 160 list_for_each_entry(cell, &afs_cells, link) {
159 if (strcasecmp(cell->name, name) == 0) 161 if (strncasecmp(cell->name, name, namesz) == 0)
160 goto duplicate_name; 162 goto duplicate_name;
161 } 163 }
162 read_unlock(&afs_cells_lock); 164 read_unlock(&afs_cells_lock);
163 165
164 cell = afs_cell_alloc(name, vllist); 166 cell = afs_cell_alloc(name, namesz, vllist);
165 if (IS_ERR(cell)) { 167 if (IS_ERR(cell)) {
166 _leave(" = %ld", PTR_ERR(cell)); 168 _leave(" = %ld", PTR_ERR(cell));
167 up_write(&afs_cells_sem); 169 up_write(&afs_cells_sem);
@@ -201,8 +203,18 @@ error:
201 return ERR_PTR(ret); 203 return ERR_PTR(ret);
202 204
203duplicate_name: 205duplicate_name:
206 if (retref && !IS_ERR(cell))
207 afs_get_cell(cell);
208
204 read_unlock(&afs_cells_lock); 209 read_unlock(&afs_cells_lock);
205 up_write(&afs_cells_sem); 210 up_write(&afs_cells_sem);
211
212 if (retref) {
213 _leave(" = %p", cell);
214 return cell;
215 }
216
217 _leave(" = -EEXIST");
206 return ERR_PTR(-EEXIST); 218 return ERR_PTR(-EEXIST);
207} 219}
208 220
@@ -233,7 +245,7 @@ int afs_cell_init(char *rootcell)
233 *cp++ = 0; 245 *cp++ = 0;
234 246
235 /* allocate a cell record for the root cell */ 247 /* allocate a cell record for the root cell */
236 new_root = afs_cell_create(rootcell, cp); 248 new_root = afs_cell_create(rootcell, strlen(rootcell), cp, false);
237 if (IS_ERR(new_root)) { 249 if (IS_ERR(new_root)) {
238 _leave(" = %ld", PTR_ERR(new_root)); 250 _leave(" = %ld", PTR_ERR(new_root));
239 return PTR_ERR(new_root); 251 return PTR_ERR(new_root);
@@ -253,11 +265,12 @@ int afs_cell_init(char *rootcell)
253/* 265/*
254 * lookup a cell record 266 * lookup a cell record
255 */ 267 */
256struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz) 268struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz,
269 bool dns_cell)
257{ 270{
258 struct afs_cell *cell; 271 struct afs_cell *cell;
259 272
260 _enter("\"%*.*s\",", namesz, namesz, name ? name : ""); 273 _enter("\"%*.*s\",", namesz, namesz, name ?: "");
261 274
262 down_read(&afs_cells_sem); 275 down_read(&afs_cells_sem);
263 read_lock(&afs_cells_lock); 276 read_lock(&afs_cells_lock);
@@ -271,6 +284,8 @@ struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz)
271 } 284 }
272 } 285 }
273 cell = ERR_PTR(-ENOENT); 286 cell = ERR_PTR(-ENOENT);
287 if (dns_cell)
288 goto create_cell;
274 found: 289 found:
275 ; 290 ;
276 } else { 291 } else {
@@ -293,6 +308,15 @@ struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz)
293 up_read(&afs_cells_sem); 308 up_read(&afs_cells_sem);
294 _leave(" = %p", cell); 309 _leave(" = %p", cell);
295 return cell; 310 return cell;
311
312create_cell:
313 read_unlock(&afs_cells_lock);
314 up_read(&afs_cells_sem);
315
316 cell = afs_cell_create(name, namesz, NULL, true);
317
318 _leave(" = %p", cell);
319 return cell;
296} 320}
297 321
298#if 0 322#if 0