afs: cell: Remove unnecessary code in afs_lookup_cell
[muen/linux.git] / fs / afs / cell.c
1 /* AFS cell and server record management
2  *
3  * Copyright (C) 2002, 2017 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  */
11
12 #include <linux/slab.h>
13 #include <linux/key.h>
14 #include <linux/ctype.h>
15 #include <linux/dns_resolver.h>
16 #include <linux/sched.h>
17 #include <linux/inet.h>
18 #include <keys/rxrpc-type.h>
19 #include "internal.h"
20
21 unsigned __read_mostly afs_cell_gc_delay = 10;
22
23 static void afs_manage_cell(struct work_struct *);
24
25 static void afs_dec_cells_outstanding(struct afs_net *net)
26 {
27         if (atomic_dec_and_test(&net->cells_outstanding))
28                 wake_up_atomic_t(&net->cells_outstanding);
29 }
30
31 /*
32  * Set the cell timer to fire after a given delay, assuming it's not already
33  * set for an earlier time.
34  */
35 static void afs_set_cell_timer(struct afs_net *net, time64_t delay)
36 {
37         if (net->live) {
38                 atomic_inc(&net->cells_outstanding);
39                 if (timer_reduce(&net->cells_timer, jiffies + delay * HZ))
40                         afs_dec_cells_outstanding(net);
41         }
42 }
43
44 /*
45  * Look up and get an activation reference on a cell record under RCU
46  * conditions.  The caller must hold the RCU read lock.
47  */
48 struct afs_cell *afs_lookup_cell_rcu(struct afs_net *net,
49                                      const char *name, unsigned int namesz)
50 {
51         struct afs_cell *cell = NULL;
52         struct rb_node *p;
53         int n, seq = 0, ret = 0;
54
55         _enter("%*.*s", namesz, namesz, name);
56
57         if (name && namesz == 0)
58                 return ERR_PTR(-EINVAL);
59         if (namesz > AFS_MAXCELLNAME)
60                 return ERR_PTR(-ENAMETOOLONG);
61
62         do {
63                 /* Unfortunately, rbtree walking doesn't give reliable results
64                  * under just the RCU read lock, so we have to check for
65                  * changes.
66                  */
67                 if (cell)
68                         afs_put_cell(net, cell);
69                 cell = NULL;
70                 ret = -ENOENT;
71
72                 read_seqbegin_or_lock(&net->cells_lock, &seq);
73
74                 if (!name) {
75                         cell = rcu_dereference_raw(net->ws_cell);
76                         if (cell) {
77                                 afs_get_cell(cell);
78                                 continue;
79                         }
80                         ret = -EDESTADDRREQ;
81                         continue;
82                 }
83
84                 p = rcu_dereference_raw(net->cells.rb_node);
85                 while (p) {
86                         cell = rb_entry(p, struct afs_cell, net_node);
87
88                         n = strncasecmp(cell->name, name,
89                                         min_t(size_t, cell->name_len, namesz));
90                         if (n == 0)
91                                 n = cell->name_len - namesz;
92                         if (n < 0) {
93                                 p = rcu_dereference_raw(p->rb_left);
94                         } else if (n > 0) {
95                                 p = rcu_dereference_raw(p->rb_right);
96                         } else {
97                                 if (atomic_inc_not_zero(&cell->usage)) {
98                                         ret = 0;
99                                         break;
100                                 }
101                                 /* We want to repeat the search, this time with
102                                  * the lock properly locked.
103                                  */
104                         }
105                         cell = NULL;
106                 }
107
108         } while (need_seqretry(&net->cells_lock, seq));
109
110         done_seqretry(&net->cells_lock, seq);
111
112         return ret == 0 ? cell : ERR_PTR(ret);
113 }
114
115 /*
116  * Set up a cell record and fill in its name, VL server address list and
117  * allocate an anonymous key
118  */
119 static struct afs_cell *afs_alloc_cell(struct afs_net *net,
120                                        const char *name, unsigned int namelen,
121                                        const char *vllist)
122 {
123         struct afs_cell *cell;
124         int i, ret;
125
126         ASSERT(name);
127         if (namelen == 0)
128                 return ERR_PTR(-EINVAL);
129         if (namelen > AFS_MAXCELLNAME) {
130                 _leave(" = -ENAMETOOLONG");
131                 return ERR_PTR(-ENAMETOOLONG);
132         }
133
134         _enter("%*.*s,%s", namelen, namelen, name, vllist);
135
136         cell = kzalloc(sizeof(struct afs_cell), GFP_KERNEL);
137         if (!cell) {
138                 _leave(" = -ENOMEM");
139                 return ERR_PTR(-ENOMEM);
140         }
141
142         cell->net = net;
143         cell->name_len = namelen;
144         for (i = 0; i < namelen; i++)
145                 cell->name[i] = tolower(name[i]);
146
147         atomic_set(&cell->usage, 2);
148         INIT_WORK(&cell->manager, afs_manage_cell);
149         cell->flags = ((1 << AFS_CELL_FL_NOT_READY) |
150                        (1 << AFS_CELL_FL_NO_LOOKUP_YET));
151         INIT_LIST_HEAD(&cell->proc_volumes);
152         rwlock_init(&cell->proc_lock);
153         rwlock_init(&cell->vl_addrs_lock);
154
155         /* Fill in the VL server list if we were given a list of addresses to
156          * use.
157          */
158         if (vllist) {
159                 struct afs_addr_list *alist;
160
161                 alist = afs_parse_text_addrs(vllist, strlen(vllist), ':',
162                                              VL_SERVICE, AFS_VL_PORT);
163                 if (IS_ERR(alist)) {
164                         ret = PTR_ERR(alist);
165                         goto parse_failed;
166                 }
167
168                 rcu_assign_pointer(cell->vl_addrs, alist);
169                 cell->dns_expiry = TIME64_MAX;
170         }
171
172         _leave(" = %p", cell);
173         return cell;
174
175 parse_failed:
176         if (ret == -EINVAL)
177                 printk(KERN_ERR "kAFS: bad VL server IP address\n");
178         kfree(cell);
179         _leave(" = %d", ret);
180         return ERR_PTR(ret);
181 }
182
183 /*
184  * afs_lookup_cell - Look up or create a cell record.
185  * @net:        The network namespace
186  * @name:       The name of the cell.
187  * @namesz:     The strlen of the cell name.
188  * @vllist:     A colon/comma separated list of numeric IP addresses or NULL.
189  * @excl:       T if an error should be given if the cell name already exists.
190  *
191  * Look up a cell record by name and query the DNS for VL server addresses if
192  * needed.  Note that that actual DNS query is punted off to the manager thread
193  * so that this function can return immediately if interrupted whilst allowing
194  * cell records to be shared even if not yet fully constructed.
195  */
196 struct afs_cell *afs_lookup_cell(struct afs_net *net,
197                                  const char *name, unsigned int namesz,
198                                  const char *vllist, bool excl)
199 {
200         struct afs_cell *cell, *candidate, *cursor;
201         struct rb_node *parent, **pp;
202         int ret, n;
203
204         _enter("%s,%s", name, vllist);
205
206         if (!excl) {
207                 rcu_read_lock();
208                 cell = afs_lookup_cell_rcu(net, name, namesz);
209                 rcu_read_unlock();
210                 if (!IS_ERR(cell))
211                         goto wait_for_cell;
212         }
213
214         /* Assume we're probably going to create a cell and preallocate and
215          * mostly set up a candidate record.  We can then use this to stash the
216          * name, the net namespace and VL server addresses.
217          *
218          * We also want to do this before we hold any locks as it may involve
219          * upcalling to userspace to make DNS queries.
220          */
221         candidate = afs_alloc_cell(net, name, namesz, vllist);
222         if (IS_ERR(candidate)) {
223                 _leave(" = %ld", PTR_ERR(candidate));
224                 return candidate;
225         }
226
227         /* Find the insertion point and check to see if someone else added a
228          * cell whilst we were allocating.
229          */
230         write_seqlock(&net->cells_lock);
231
232         pp = &net->cells.rb_node;
233         parent = NULL;
234         while (*pp) {
235                 parent = *pp;
236                 cursor = rb_entry(parent, struct afs_cell, net_node);
237
238                 n = strncasecmp(cursor->name, name,
239                                 min_t(size_t, cursor->name_len, namesz));
240                 if (n == 0)
241                         n = cursor->name_len - namesz;
242                 if (n < 0)
243                         pp = &(*pp)->rb_left;
244                 else if (n > 0)
245                         pp = &(*pp)->rb_right;
246                 else
247                         goto cell_already_exists;
248         }
249
250         cell = candidate;
251         candidate = NULL;
252         rb_link_node_rcu(&cell->net_node, parent, pp);
253         rb_insert_color(&cell->net_node, &net->cells);
254         atomic_inc(&net->cells_outstanding);
255         write_sequnlock(&net->cells_lock);
256
257         queue_work(afs_wq, &cell->manager);
258
259 wait_for_cell:
260         _debug("wait_for_cell");
261         ret = wait_on_bit(&cell->flags, AFS_CELL_FL_NOT_READY, TASK_INTERRUPTIBLE);
262         smp_rmb();
263
264         switch (READ_ONCE(cell->state)) {
265         case AFS_CELL_FAILED:
266                 ret = cell->error;
267                 goto error;
268         default:
269                 _debug("weird %u %d", cell->state, cell->error);
270                 goto error;
271         case AFS_CELL_ACTIVE:
272                 break;
273         }
274
275         _leave(" = %p [cell]", cell);
276         return cell;
277
278 cell_already_exists:
279         _debug("cell exists");
280         cell = cursor;
281         if (excl) {
282                 ret = -EEXIST;
283         } else {
284                 afs_get_cell(cursor);
285                 ret = 0;
286         }
287         write_sequnlock(&net->cells_lock);
288         kfree(candidate);
289         if (ret == 0)
290                 goto wait_for_cell;
291         goto error_noput;
292 error:
293         afs_put_cell(net, cell);
294 error_noput:
295         _leave(" = %d [error]", ret);
296         return ERR_PTR(ret);
297 }
298
299 /*
300  * set the root cell information
301  * - can be called with a module parameter string
302  * - can be called from a write to /proc/fs/afs/rootcell
303  */
304 int afs_cell_init(struct afs_net *net, const char *rootcell)
305 {
306         struct afs_cell *old_root, *new_root;
307         const char *cp, *vllist;
308         size_t len;
309
310         _enter("");
311
312         if (!rootcell) {
313                 /* module is loaded with no parameters, or built statically.
314                  * - in the future we might initialize cell DB here.
315                  */
316                 _leave(" = 0 [no root]");
317                 return 0;
318         }
319
320         cp = strchr(rootcell, ':');
321         if (!cp) {
322                 _debug("kAFS: no VL server IP addresses specified");
323                 vllist = NULL;
324                 len = strlen(rootcell);
325         } else {
326                 vllist = cp + 1;
327                 len = cp - rootcell;
328         }
329
330         /* allocate a cell record for the root cell */
331         new_root = afs_lookup_cell(net, rootcell, len, vllist, false);
332         if (IS_ERR(new_root)) {
333                 _leave(" = %ld", PTR_ERR(new_root));
334                 return PTR_ERR(new_root);
335         }
336
337         set_bit(AFS_CELL_FL_NO_GC, &new_root->flags);
338         afs_get_cell(new_root);
339
340         /* install the new cell */
341         write_seqlock(&net->cells_lock);
342         old_root = net->ws_cell;
343         net->ws_cell = new_root;
344         write_sequnlock(&net->cells_lock);
345
346         afs_put_cell(net, old_root);
347         _leave(" = 0");
348         return 0;
349 }
350
351 /*
352  * Update a cell's VL server address list from the DNS.
353  */
354 static void afs_update_cell(struct afs_cell *cell)
355 {
356         struct afs_addr_list *alist, *old;
357         time64_t now, expiry;
358
359         _enter("%s", cell->name);
360
361         alist = afs_dns_query(cell, &expiry);
362         if (IS_ERR(alist)) {
363                 switch (PTR_ERR(alist)) {
364                 case -ENODATA:
365                         /* The DNS said that the cell does not exist */
366                         set_bit(AFS_CELL_FL_NOT_FOUND, &cell->flags);
367                         clear_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags);
368                         cell->dns_expiry = ktime_get_real_seconds() + 61;
369                         break;
370
371                 case -EAGAIN:
372                 case -ECONNREFUSED:
373                 default:
374                         set_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags);
375                         cell->dns_expiry = ktime_get_real_seconds() + 10;
376                         break;
377                 }
378
379                 cell->error = -EDESTADDRREQ;
380         } else {
381                 clear_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags);
382                 clear_bit(AFS_CELL_FL_NOT_FOUND, &cell->flags);
383
384                 /* Exclusion on changing vl_addrs is achieved by a
385                  * non-reentrant work item.
386                  */
387                 old = rcu_dereference_protected(cell->vl_addrs, true);
388                 rcu_assign_pointer(cell->vl_addrs, alist);
389                 cell->dns_expiry = expiry;
390
391                 if (old)
392                         afs_put_addrlist(old);
393         }
394
395         if (test_and_clear_bit(AFS_CELL_FL_NO_LOOKUP_YET, &cell->flags))
396                 wake_up_bit(&cell->flags, AFS_CELL_FL_NO_LOOKUP_YET);
397
398         now = ktime_get_real_seconds();
399         afs_set_cell_timer(cell->net, cell->dns_expiry - now);
400         _leave("");
401 }
402
403 /*
404  * Destroy a cell record
405  */
406 static void afs_cell_destroy(struct rcu_head *rcu)
407 {
408         struct afs_cell *cell = container_of(rcu, struct afs_cell, rcu);
409
410         _enter("%p{%s}", cell, cell->name);
411
412         ASSERTCMP(atomic_read(&cell->usage), ==, 0);
413
414         afs_put_addrlist(cell->vl_addrs);
415         key_put(cell->anonymous_key);
416         kfree(cell);
417
418         _leave(" [destroyed]");
419 }
420
421 /*
422  * Queue the cell manager.
423  */
424 static void afs_queue_cell_manager(struct afs_net *net)
425 {
426         int outstanding = atomic_inc_return(&net->cells_outstanding);
427
428         _enter("%d", outstanding);
429
430         if (!queue_work(afs_wq, &net->cells_manager))
431                 afs_dec_cells_outstanding(net);
432 }
433
434 /*
435  * Cell management timer.  We have an increment on cells_outstanding that we
436  * need to pass along to the work item.
437  */
438 void afs_cells_timer(struct timer_list *timer)
439 {
440         struct afs_net *net = container_of(timer, struct afs_net, cells_timer);
441
442         _enter("");
443         if (!queue_work(afs_wq, &net->cells_manager))
444                 afs_dec_cells_outstanding(net);
445 }
446
447 /*
448  * Get a reference on a cell record.
449  */
450 struct afs_cell *afs_get_cell(struct afs_cell *cell)
451 {
452         atomic_inc(&cell->usage);
453         return cell;
454 }
455
456 /*
457  * Drop a reference on a cell record.
458  */
459 void afs_put_cell(struct afs_net *net, struct afs_cell *cell)
460 {
461         time64_t now, expire_delay;
462
463         if (!cell)
464                 return;
465
466         _enter("%s", cell->name);
467
468         now = ktime_get_real_seconds();
469         cell->last_inactive = now;
470         expire_delay = 0;
471         if (!test_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags) &&
472             !test_bit(AFS_CELL_FL_NOT_FOUND, &cell->flags))
473                 expire_delay = afs_cell_gc_delay;
474
475         if (atomic_dec_return(&cell->usage) > 1)
476                 return;
477
478         /* 'cell' may now be garbage collected. */
479         afs_set_cell_timer(net, expire_delay);
480 }
481
482 /*
483  * Allocate a key to use as a placeholder for anonymous user security.
484  */
485 static int afs_alloc_anon_key(struct afs_cell *cell)
486 {
487         struct key *key;
488         char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp;
489
490         /* Create a key to represent an anonymous user. */
491         memcpy(keyname, "afs@", 4);
492         dp = keyname + 4;
493         cp = cell->name;
494         do {
495                 *dp++ = tolower(*cp);
496         } while (*cp++);
497
498         key = rxrpc_get_null_key(keyname);
499         if (IS_ERR(key))
500                 return PTR_ERR(key);
501
502         cell->anonymous_key = key;
503
504         _debug("anon key %p{%x}",
505                cell->anonymous_key, key_serial(cell->anonymous_key));
506         return 0;
507 }
508
509 /*
510  * Activate a cell.
511  */
512 static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell)
513 {
514         int ret;
515
516         if (!cell->anonymous_key) {
517                 ret = afs_alloc_anon_key(cell);
518                 if (ret < 0)
519                         return ret;
520         }
521
522 #ifdef CONFIG_AFS_FSCACHE
523         cell->cache = fscache_acquire_cookie(afs_cache_netfs.primary_index,
524                                              &afs_cell_cache_index_def,
525                                              cell, true);
526 #endif
527         ret = afs_proc_cell_setup(net, cell);
528         if (ret < 0)
529                 return ret;
530         spin_lock(&net->proc_cells_lock);
531         list_add_tail(&cell->proc_link, &net->proc_cells);
532         spin_unlock(&net->proc_cells_lock);
533         return 0;
534 }
535
536 /*
537  * Deactivate a cell.
538  */
539 static void afs_deactivate_cell(struct afs_net *net, struct afs_cell *cell)
540 {
541         _enter("%s", cell->name);
542
543         afs_proc_cell_remove(net, cell);
544
545         spin_lock(&net->proc_cells_lock);
546         list_del_init(&cell->proc_link);
547         spin_unlock(&net->proc_cells_lock);
548
549 #ifdef CONFIG_AFS_FSCACHE
550         fscache_relinquish_cookie(cell->cache, 0);
551         cell->cache = NULL;
552 #endif
553
554         _leave("");
555 }
556
557 /*
558  * Manage a cell record, initialising and destroying it, maintaining its DNS
559  * records.
560  */
561 static void afs_manage_cell(struct work_struct *work)
562 {
563         struct afs_cell *cell = container_of(work, struct afs_cell, manager);
564         struct afs_net *net = cell->net;
565         bool deleted;
566         int ret, usage;
567
568         _enter("%s", cell->name);
569
570 again:
571         _debug("state %u", cell->state);
572         switch (cell->state) {
573         case AFS_CELL_INACTIVE:
574         case AFS_CELL_FAILED:
575                 write_seqlock(&net->cells_lock);
576                 usage = 1;
577                 deleted = atomic_try_cmpxchg_relaxed(&cell->usage, &usage, 0);
578                 if (deleted)
579                         rb_erase(&cell->net_node, &net->cells);
580                 write_sequnlock(&net->cells_lock);
581                 if (deleted)
582                         goto final_destruction;
583                 if (cell->state == AFS_CELL_FAILED)
584                         goto done;
585                 cell->state = AFS_CELL_UNSET;
586                 goto again;
587
588         case AFS_CELL_UNSET:
589                 cell->state = AFS_CELL_ACTIVATING;
590                 goto again;
591
592         case AFS_CELL_ACTIVATING:
593                 ret = afs_activate_cell(net, cell);
594                 if (ret < 0)
595                         goto activation_failed;
596
597                 cell->state = AFS_CELL_ACTIVE;
598                 smp_wmb();
599                 clear_bit(AFS_CELL_FL_NOT_READY, &cell->flags);
600                 wake_up_bit(&cell->flags, AFS_CELL_FL_NOT_READY);
601                 goto again;
602
603         case AFS_CELL_ACTIVE:
604                 if (atomic_read(&cell->usage) > 1) {
605                         time64_t now = ktime_get_real_seconds();
606                         if (cell->dns_expiry <= now && net->live)
607                                 afs_update_cell(cell);
608                         goto done;
609                 }
610                 cell->state = AFS_CELL_DEACTIVATING;
611                 goto again;
612
613         case AFS_CELL_DEACTIVATING:
614                 set_bit(AFS_CELL_FL_NOT_READY, &cell->flags);
615                 if (atomic_read(&cell->usage) > 1)
616                         goto reverse_deactivation;
617                 afs_deactivate_cell(net, cell);
618                 cell->state = AFS_CELL_INACTIVE;
619                 goto again;
620
621         default:
622                 break;
623         }
624         _debug("bad state %u", cell->state);
625         BUG(); /* Unhandled state */
626
627 activation_failed:
628         cell->error = ret;
629         afs_deactivate_cell(net, cell);
630
631         cell->state = AFS_CELL_FAILED;
632         smp_wmb();
633         if (test_and_clear_bit(AFS_CELL_FL_NOT_READY, &cell->flags))
634                 wake_up_bit(&cell->flags, AFS_CELL_FL_NOT_READY);
635         goto again;
636
637 reverse_deactivation:
638         cell->state = AFS_CELL_ACTIVE;
639         smp_wmb();
640         clear_bit(AFS_CELL_FL_NOT_READY, &cell->flags);
641         wake_up_bit(&cell->flags, AFS_CELL_FL_NOT_READY);
642         _leave(" [deact->act]");
643         return;
644
645 done:
646         _leave(" [done %u]", cell->state);
647         return;
648
649 final_destruction:
650         call_rcu(&cell->rcu, afs_cell_destroy);
651         afs_dec_cells_outstanding(net);
652         _leave(" [destruct %d]", atomic_read(&net->cells_outstanding));
653 }
654
655 /*
656  * Manage the records of cells known to a network namespace.  This includes
657  * updating the DNS records and garbage collecting unused cells that were
658  * automatically added.
659  *
660  * Note that constructed cell records may only be removed from net->cells by
661  * this work item, so it is safe for this work item to stash a cursor pointing
662  * into the tree and then return to caller (provided it skips cells that are
663  * still under construction).
664  *
665  * Note also that we were given an increment on net->cells_outstanding by
666  * whoever queued us that we need to deal with before returning.
667  */
668 void afs_manage_cells(struct work_struct *work)
669 {
670         struct afs_net *net = container_of(work, struct afs_net, cells_manager);
671         struct rb_node *cursor;
672         time64_t now = ktime_get_real_seconds(), next_manage = TIME64_MAX;
673         bool purging = !net->live;
674
675         _enter("");
676
677         /* Trawl the cell database looking for cells that have expired from
678          * lack of use and cells whose DNS results have expired and dispatch
679          * their managers.
680          */
681         read_seqlock_excl(&net->cells_lock);
682
683         for (cursor = rb_first(&net->cells); cursor; cursor = rb_next(cursor)) {
684                 struct afs_cell *cell =
685                         rb_entry(cursor, struct afs_cell, net_node);
686                 unsigned usage;
687                 bool sched_cell = false;
688
689                 usage = atomic_read(&cell->usage);
690                 _debug("manage %s %u", cell->name, usage);
691
692                 ASSERTCMP(usage, >=, 1);
693
694                 if (purging) {
695                         if (test_and_clear_bit(AFS_CELL_FL_NO_GC, &cell->flags))
696                                 usage = atomic_dec_return(&cell->usage);
697                         ASSERTCMP(usage, ==, 1);
698                 }
699
700                 if (usage == 1) {
701                         time64_t expire_at = cell->last_inactive;
702
703                         if (!test_bit(AFS_CELL_FL_DNS_FAIL, &cell->flags) &&
704                             !test_bit(AFS_CELL_FL_NOT_FOUND, &cell->flags))
705                                 expire_at += afs_cell_gc_delay;
706                         if (purging || expire_at <= now)
707                                 sched_cell = true;
708                         else if (expire_at < next_manage)
709                                 next_manage = expire_at;
710                 }
711
712                 if (!purging) {
713                         if (cell->dns_expiry <= now)
714                                 sched_cell = true;
715                         else if (cell->dns_expiry <= next_manage)
716                                 next_manage = cell->dns_expiry;
717                 }
718
719                 if (sched_cell)
720                         queue_work(afs_wq, &cell->manager);
721         }
722
723         read_sequnlock_excl(&net->cells_lock);
724
725         /* Update the timer on the way out.  We have to pass an increment on
726          * cells_outstanding in the namespace that we are in to the timer or
727          * the work scheduler.
728          */
729         if (!purging && next_manage < TIME64_MAX) {
730                 now = ktime_get_real_seconds();
731
732                 if (next_manage - now <= 0) {
733                         if (queue_work(afs_wq, &net->cells_manager))
734                                 atomic_inc(&net->cells_outstanding);
735                 } else {
736                         afs_set_cell_timer(net, next_manage - now);
737                 }
738         }
739
740         afs_dec_cells_outstanding(net);
741         _leave(" [%d]", atomic_read(&net->cells_outstanding));
742 }
743
744 /*
745  * Purge in-memory cell database.
746  */
747 void afs_cell_purge(struct afs_net *net)
748 {
749         struct afs_cell *ws;
750
751         _enter("");
752
753         write_seqlock(&net->cells_lock);
754         ws = net->ws_cell;
755         net->ws_cell = NULL;
756         write_sequnlock(&net->cells_lock);
757         afs_put_cell(net, ws);
758
759         _debug("del timer");
760         if (del_timer_sync(&net->cells_timer))
761                 atomic_dec(&net->cells_outstanding);
762
763         _debug("kick mgr");
764         afs_queue_cell_manager(net);
765
766         _debug("wait");
767         wait_on_atomic_t(&net->cells_outstanding, atomic_t_wait,
768                          TASK_UNINTERRUPTIBLE);
769         _leave("");
770 }