aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2019-05-07 10:30:34 -0400
committerDavid Howells <dhowells@redhat.com>2019-05-15 12:35:53 -0400
commitca1cbbdce92bc2bfdc17e4f70ad41f6e6af2d03f (patch)
tree2229083e8e8186749c7de607d5d53da169270a17 /fs/afs
parent6b8812fc8ec28c13c09c89f88ce3958f19238838 (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.c19
-rw-r--r--fs/afs/proc.c8
-rw-r--r--fs/afs/vl_list.c20
-rw-r--r--fs/afs/vl_rotate.c2
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
184parse_failed: 187parse_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");
190error:
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;