diff options
Diffstat (limited to 'fs/afs/cell.c')
-rw-r--r-- | fs/afs/cell.c | 52 |
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 | */ |
34 | static struct afs_cell *afs_cell_alloc(const char *name, char *vllist) | 34 | static 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 | */ |
149 | struct afs_cell *afs_cell_create(const char *name, char *vllist) | 150 | struct 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 | ||
203 | duplicate_name: | 205 | duplicate_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 | */ |
256 | struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz) | 268 | struct 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 | |||
312 | create_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 |