diff options
author | David Howells <dhowells@redhat.com> | 2019-05-07 10:30:34 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2019-05-15 12:35:53 -0400 |
commit | ca1cbbdce92bc2bfdc17e4f70ad41f6e6af2d03f (patch) | |
tree | 2229083e8e8186749c7de607d5d53da169270a17 /fs/afs | |
parent | 6b8812fc8ec28c13c09c89f88ce3958f19238838 (diff) |
afs: Fix afs_cell records to always have a VL server list record
Fix it such that afs_cell records always have a VL server list record
attached, even if it's a dummy one, so that various checks can be removed.
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs')
-rw-r--r-- | fs/afs/cell.c | 19 | ||||
-rw-r--r-- | fs/afs/proc.c | 8 | ||||
-rw-r--r-- | fs/afs/vl_list.c | 20 | ||||
-rw-r--r-- | fs/afs/vl_rotate.c | 2 |
4 files changed, 25 insertions, 24 deletions
diff --git a/fs/afs/cell.c b/fs/afs/cell.c index 9ca075e11239..47f96be05163 100644 --- a/fs/afs/cell.c +++ b/fs/afs/cell.c | |||
@@ -123,6 +123,7 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net, | |||
123 | const char *name, unsigned int namelen, | 123 | const char *name, unsigned int namelen, |
124 | const char *addresses) | 124 | const char *addresses) |
125 | { | 125 | { |
126 | struct afs_vlserver_list *vllist; | ||
126 | struct afs_cell *cell; | 127 | struct afs_cell *cell; |
127 | int i, ret; | 128 | int i, ret; |
128 | 129 | ||
@@ -157,12 +158,10 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net, | |||
157 | rwlock_init(&cell->proc_lock); | 158 | rwlock_init(&cell->proc_lock); |
158 | rwlock_init(&cell->vl_servers_lock); | 159 | rwlock_init(&cell->vl_servers_lock); |
159 | 160 | ||
160 | /* Fill in the VL server list if we were given a list of addresses to | 161 | /* Provide a VL server list, filling it in if we were given a list of |
161 | * use. | 162 | * addresses to use. |
162 | */ | 163 | */ |
163 | if (addresses) { | 164 | if (addresses) { |
164 | struct afs_vlserver_list *vllist; | ||
165 | |||
166 | vllist = afs_parse_text_addrs(net, | 165 | vllist = afs_parse_text_addrs(net, |
167 | addresses, strlen(addresses), ':', | 166 | addresses, strlen(addresses), ':', |
168 | VL_SERVICE, AFS_VL_PORT); | 167 | VL_SERVICE, AFS_VL_PORT); |
@@ -171,19 +170,24 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net, | |||
171 | goto parse_failed; | 170 | goto parse_failed; |
172 | } | 171 | } |
173 | 172 | ||
174 | rcu_assign_pointer(cell->vl_servers, vllist); | ||
175 | cell->dns_expiry = TIME64_MAX; | 173 | cell->dns_expiry = TIME64_MAX; |
176 | __clear_bit(AFS_CELL_FL_NO_LOOKUP_YET, &cell->flags); | ||
177 | } else { | 174 | } else { |
175 | ret = -ENOMEM; | ||
176 | vllist = afs_alloc_vlserver_list(0); | ||
177 | if (!vllist) | ||
178 | goto error; | ||
178 | cell->dns_expiry = ktime_get_real_seconds(); | 179 | cell->dns_expiry = ktime_get_real_seconds(); |
179 | } | 180 | } |
180 | 181 | ||
182 | rcu_assign_pointer(cell->vl_servers, vllist); | ||
183 | |||
181 | _leave(" = %p", cell); | 184 | _leave(" = %p", cell); |
182 | return cell; | 185 | return cell; |
183 | 186 | ||
184 | parse_failed: | 187 | parse_failed: |
185 | if (ret == -EINVAL) | 188 | if (ret == -EINVAL) |
186 | printk(KERN_ERR "kAFS: bad VL server IP address\n"); | 189 | printk(KERN_ERR "kAFS: bad VL server IP address\n"); |
190 | error: | ||
187 | kfree(cell); | 191 | kfree(cell); |
188 | _leave(" = %d", ret); | 192 | _leave(" = %d", ret); |
189 | return ERR_PTR(ret); | 193 | return ERR_PTR(ret); |
@@ -410,8 +414,7 @@ static void afs_update_cell(struct afs_cell *cell) | |||
410 | cell->dns_expiry = expiry; | 414 | cell->dns_expiry = expiry; |
411 | write_unlock(&cell->vl_servers_lock); | 415 | write_unlock(&cell->vl_servers_lock); |
412 | 416 | ||
413 | if (old) | 417 | afs_put_vlserverlist(cell->net, old); |
414 | afs_put_vlserverlist(cell->net, old); | ||
415 | } | 418 | } |
416 | 419 | ||
417 | if (test_and_clear_bit(AFS_CELL_FL_NO_LOOKUP_YET, &cell->flags)) | 420 | if (test_and_clear_bit(AFS_CELL_FL_NO_LOOKUP_YET, &cell->flags)) |
diff --git a/fs/afs/proc.c b/fs/afs/proc.c index be2ee3bbd0a9..371501d28e08 100644 --- a/fs/afs/proc.c +++ b/fs/afs/proc.c | |||
@@ -53,7 +53,7 @@ static int afs_proc_cells_show(struct seq_file *m, void *v) | |||
53 | seq_printf(m, "%3u %6lld %2u %s\n", | 53 | seq_printf(m, "%3u %6lld %2u %s\n", |
54 | atomic_read(&cell->usage), | 54 | atomic_read(&cell->usage), |
55 | cell->dns_expiry - ktime_get_real_seconds(), | 55 | cell->dns_expiry - ktime_get_real_seconds(), |
56 | vllist ? vllist->nr_servers : 0, | 56 | vllist->nr_servers, |
57 | cell->name); | 57 | cell->name); |
58 | return 0; | 58 | return 0; |
59 | } | 59 | } |
@@ -296,8 +296,8 @@ static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v) | |||
296 | 296 | ||
297 | if (v == SEQ_START_TOKEN) { | 297 | if (v == SEQ_START_TOKEN) { |
298 | seq_printf(m, "# source %s, status %s\n", | 298 | seq_printf(m, "# source %s, status %s\n", |
299 | dns_record_sources[vllist->source], | 299 | dns_record_sources[vllist ? vllist->source : 0], |
300 | dns_lookup_statuses[vllist->status]); | 300 | dns_lookup_statuses[vllist ? vllist->status : 0]); |
301 | return 0; | 301 | return 0; |
302 | } | 302 | } |
303 | 303 | ||
@@ -336,7 +336,7 @@ static void *afs_proc_cell_vlservers_start(struct seq_file *m, loff_t *_pos) | |||
336 | if (pos == 0) | 336 | if (pos == 0) |
337 | return SEQ_START_TOKEN; | 337 | return SEQ_START_TOKEN; |
338 | 338 | ||
339 | if (!vllist || pos - 1 >= vllist->nr_servers) | 339 | if (pos - 1 >= vllist->nr_servers) |
340 | return NULL; | 340 | return NULL; |
341 | 341 | ||
342 | return &vllist->servers[pos - 1]; | 342 | return &vllist->servers[pos - 1]; |
diff --git a/fs/afs/vl_list.c b/fs/afs/vl_list.c index b4f1a84519b9..61e25010ff33 100644 --- a/fs/afs/vl_list.c +++ b/fs/afs/vl_list.c | |||
@@ -232,18 +232,16 @@ struct afs_vlserver_list *afs_extract_vlserver_list(struct afs_cell *cell, | |||
232 | if (bs.status > NR__dns_lookup_status) | 232 | if (bs.status > NR__dns_lookup_status) |
233 | bs.status = NR__dns_lookup_status; | 233 | bs.status = NR__dns_lookup_status; |
234 | 234 | ||
235 | /* See if we can update an old server record */ | ||
235 | server = NULL; | 236 | server = NULL; |
236 | if (previous) { | 237 | for (i = 0; i < previous->nr_servers; i++) { |
237 | /* See if we can update an old server record */ | 238 | struct afs_vlserver *p = previous->servers[i].server; |
238 | for (i = 0; i < previous->nr_servers; i++) { | 239 | |
239 | struct afs_vlserver *p = previous->servers[i].server; | 240 | if (p->name_len == bs.name_len && |
240 | 241 | p->port == bs.port && | |
241 | if (p->name_len == bs.name_len && | 242 | strncasecmp(b, p->name, bs.name_len) == 0) { |
242 | p->port == bs.port && | 243 | server = afs_get_vlserver(p); |
243 | strncasecmp(b, p->name, bs.name_len) == 0) { | 244 | break; |
244 | server = afs_get_vlserver(p); | ||
245 | break; | ||
246 | } | ||
247 | } | 245 | } |
248 | } | 246 | } |
249 | 247 | ||
diff --git a/fs/afs/vl_rotate.c b/fs/afs/vl_rotate.c index 7adde83a0648..65629d73ad9d 100644 --- a/fs/afs/vl_rotate.c +++ b/fs/afs/vl_rotate.c | |||
@@ -55,7 +55,7 @@ static bool afs_start_vl_iteration(struct afs_vl_cursor *vc) | |||
55 | rcu_dereference_protected(cell->vl_servers, | 55 | rcu_dereference_protected(cell->vl_servers, |
56 | lockdep_is_held(&cell->vl_servers_lock))); | 56 | lockdep_is_held(&cell->vl_servers_lock))); |
57 | read_unlock(&cell->vl_servers_lock); | 57 | read_unlock(&cell->vl_servers_lock); |
58 | if (!vc->server_list || !vc->server_list->nr_servers) | 58 | if (!vc->server_list->nr_servers) |
59 | return false; | 59 | return false; |
60 | 60 | ||
61 | vc->untried = (1UL << vc->server_list->nr_servers) - 1; | 61 | vc->untried = (1UL << vc->server_list->nr_servers) - 1; |