Lines Matching +full:2 +full:- +full:cell
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* AFS cell and server record management
15 #include <keys/rxrpc-type.h>
28 if (atomic_dec_and_test(&net->cells_outstanding)) in afs_dec_cells_outstanding()
29 wake_up_var(&net->cells_outstanding); in afs_dec_cells_outstanding()
33 * Set the cell timer to fire after a given delay, assuming it's not already
38 if (net->live) { in afs_set_cell_timer()
39 atomic_inc(&net->cells_outstanding); in afs_set_cell_timer()
40 if (timer_reduce(&net->cells_timer, jiffies + delay * HZ)) in afs_set_cell_timer()
48 * Look up and get an activation reference on a cell record. The caller must
49 * hold net->cells_lock at least read-locked.
55 struct afs_cell *cell = NULL; in afs_find_cell_locked() local
62 return ERR_PTR(-EINVAL); in afs_find_cell_locked()
64 return ERR_PTR(-ENAMETOOLONG); in afs_find_cell_locked()
67 cell = net->ws_cell; in afs_find_cell_locked()
68 if (!cell) in afs_find_cell_locked()
69 return ERR_PTR(-EDESTADDRREQ); in afs_find_cell_locked()
73 p = net->cells.rb_node; in afs_find_cell_locked()
75 cell = rb_entry(p, struct afs_cell, net_node); in afs_find_cell_locked()
77 n = strncasecmp(cell->name, name, in afs_find_cell_locked()
78 min_t(size_t, cell->name_len, namesz)); in afs_find_cell_locked()
80 n = cell->name_len - namesz; in afs_find_cell_locked()
82 p = p->rb_left; in afs_find_cell_locked()
84 p = p->rb_right; in afs_find_cell_locked()
89 return ERR_PTR(-ENOENT); in afs_find_cell_locked()
92 return afs_use_cell(cell, reason); in afs_find_cell_locked()
96 * Look up and get an activation reference on a cell record.
102 struct afs_cell *cell; in afs_find_cell() local
104 down_read(&net->cells_lock); in afs_find_cell()
105 cell = afs_find_cell_locked(net, name, namesz, reason); in afs_find_cell()
106 up_read(&net->cells_lock); in afs_find_cell()
107 return cell; in afs_find_cell()
111 * Set up a cell record and fill in its name, VL server address list and
119 struct afs_cell *cell; in afs_alloc_cell() local
124 return ERR_PTR(-EINVAL); in afs_alloc_cell()
126 _leave(" = -ENAMETOOLONG"); in afs_alloc_cell()
127 return ERR_PTR(-ENAMETOOLONG); in afs_alloc_cell()
130 /* Prohibit cell names that contain unprintable chars, '/' and '@' or in afs_alloc_cell()
131 * that begin with a dot. This also precludes "@cell". in afs_alloc_cell()
134 return ERR_PTR(-EINVAL); in afs_alloc_cell()
138 return ERR_PTR(-EINVAL); in afs_alloc_cell()
143 cell = kzalloc(sizeof(struct afs_cell), GFP_KERNEL); in afs_alloc_cell()
144 if (!cell) { in afs_alloc_cell()
145 _leave(" = -ENOMEM"); in afs_alloc_cell()
146 return ERR_PTR(-ENOMEM); in afs_alloc_cell()
149 cell->name = kmalloc(namelen + 1, GFP_KERNEL); in afs_alloc_cell()
150 if (!cell->name) { in afs_alloc_cell()
151 kfree(cell); in afs_alloc_cell()
152 return ERR_PTR(-ENOMEM); in afs_alloc_cell()
155 cell->net = net; in afs_alloc_cell()
156 cell->name_len = namelen; in afs_alloc_cell()
158 cell->name[i] = tolower(name[i]); in afs_alloc_cell()
159 cell->name[i] = 0; in afs_alloc_cell()
161 refcount_set(&cell->ref, 1); in afs_alloc_cell()
162 atomic_set(&cell->active, 0); in afs_alloc_cell()
163 INIT_WORK(&cell->manager, afs_manage_cell_work); in afs_alloc_cell()
164 init_rwsem(&cell->vs_lock); in afs_alloc_cell()
165 cell->volumes = RB_ROOT; in afs_alloc_cell()
166 INIT_HLIST_HEAD(&cell->proc_volumes); in afs_alloc_cell()
167 seqlock_init(&cell->volume_lock); in afs_alloc_cell()
168 cell->fs_servers = RB_ROOT; in afs_alloc_cell()
169 seqlock_init(&cell->fs_lock); in afs_alloc_cell()
170 rwlock_init(&cell->vl_servers_lock); in afs_alloc_cell()
171 cell->flags = (1 << AFS_CELL_FL_CHECK_ALIAS); in afs_alloc_cell()
185 vllist->source = DNS_RECORD_FROM_CONFIG; in afs_alloc_cell()
186 vllist->status = DNS_LOOKUP_NOT_DONE; in afs_alloc_cell()
187 cell->dns_expiry = TIME64_MAX; in afs_alloc_cell()
189 ret = -ENOMEM; in afs_alloc_cell()
193 vllist->source = DNS_RECORD_UNAVAILABLE; in afs_alloc_cell()
194 vllist->status = DNS_LOOKUP_NOT_DONE; in afs_alloc_cell()
195 cell->dns_expiry = ktime_get_real_seconds(); in afs_alloc_cell()
198 rcu_assign_pointer(cell->vl_servers, vllist); in afs_alloc_cell()
200 cell->dns_source = vllist->source; in afs_alloc_cell()
201 cell->dns_status = vllist->status; in afs_alloc_cell()
202 smp_store_release(&cell->dns_lookup_count, 1); /* vs source/status */ in afs_alloc_cell()
203 atomic_inc(&net->cells_outstanding); in afs_alloc_cell()
204 cell->debug_id = atomic_inc_return(&cell_debug_id); in afs_alloc_cell()
205 trace_afs_cell(cell->debug_id, 1, 0, afs_cell_trace_alloc); in afs_alloc_cell()
207 _leave(" = %p", cell); in afs_alloc_cell()
208 return cell; in afs_alloc_cell()
211 if (ret == -EINVAL) in afs_alloc_cell()
214 kfree(cell->name); in afs_alloc_cell()
215 kfree(cell); in afs_alloc_cell()
221 * afs_lookup_cell - Look up or create a cell record.
223 * @name: The name of the cell.
224 * @namesz: The strlen of the cell name.
226 * @excl: T if an error should be given if the cell name already exists.
228 * Look up a cell record by name and query the DNS for VL server addresses if
231 * cell records to be shared even if not yet fully constructed.
237 struct afs_cell *cell, *candidate, *cursor; in afs_lookup_cell() local
245 cell = afs_find_cell(net, name, namesz, afs_cell_trace_use_lookup); in afs_lookup_cell()
246 if (!IS_ERR(cell)) in afs_lookup_cell()
250 /* Assume we're probably going to create a cell and preallocate and in afs_lookup_cell()
264 * cell whilst we were allocating. in afs_lookup_cell()
266 down_write(&net->cells_lock); in afs_lookup_cell()
268 pp = &net->cells.rb_node; in afs_lookup_cell()
274 n = strncasecmp(cursor->name, name, in afs_lookup_cell()
275 min_t(size_t, cursor->name_len, namesz)); in afs_lookup_cell()
277 n = cursor->name_len - namesz; in afs_lookup_cell()
279 pp = &(*pp)->rb_left; in afs_lookup_cell()
281 pp = &(*pp)->rb_right; in afs_lookup_cell()
286 cell = candidate; in afs_lookup_cell()
288 atomic_set(&cell->active, 2); in afs_lookup_cell()
289 trace_afs_cell(cell->debug_id, refcount_read(&cell->ref), 2, afs_cell_trace_insert); in afs_lookup_cell()
290 rb_link_node_rcu(&cell->net_node, parent, pp); in afs_lookup_cell()
291 rb_insert_color(&cell->net_node, &net->cells); in afs_lookup_cell()
292 up_write(&net->cells_lock); in afs_lookup_cell()
294 afs_queue_cell(cell, afs_cell_trace_get_queue_new); in afs_lookup_cell()
297 trace_afs_cell(cell->debug_id, refcount_read(&cell->ref), atomic_read(&cell->active), in afs_lookup_cell()
300 wait_var_event(&cell->state, in afs_lookup_cell()
302 state = smp_load_acquire(&cell->state); /* vs error */ in afs_lookup_cell()
308 ret = cell->error; in afs_lookup_cell()
312 _leave(" = %p [cell]", cell); in afs_lookup_cell()
313 return cell; in afs_lookup_cell()
316 _debug("cell exists"); in afs_lookup_cell()
317 cell = cursor; in afs_lookup_cell()
319 ret = -EEXIST; in afs_lookup_cell()
324 up_write(&net->cells_lock); in afs_lookup_cell()
331 afs_unuse_cell(net, cell, afs_cell_trace_unuse_lookup); in afs_lookup_cell()
338 * set the root cell information
339 * - can be called with a module parameter string
340 * - can be called from a write to /proc/fs/afs/rootcell
352 * - in the future we might initialize cell DB here. in afs_cell_init()
365 len = cp - rootcell; in afs_cell_init()
368 /* allocate a cell record for the root cell */ in afs_cell_init()
375 if (!test_and_set_bit(AFS_CELL_FL_NO_GC, &new_root->flags)) in afs_cell_init()
378 /* install the new cell */ in afs_cell_init()
379 down_write(&net->cells_lock); in afs_cell_init()
381 old_root = net->ws_cell; in afs_cell_init()
382 net->ws_cell = new_root; in afs_cell_init()
383 up_write(&net->cells_lock); in afs_cell_init()
391 * Update a cell's VL server address list from the DNS.
393 static int afs_update_cell(struct afs_cell *cell) in afs_update_cell() argument
401 _enter("%s", cell->name); in afs_update_cell()
403 vllist = afs_dns_query(cell, &expiry); in afs_update_cell()
407 _debug("%s: fail %d", cell->name, ret); in afs_update_cell()
408 if (ret == -ENOMEM) in afs_update_cell()
414 ret = -ENOMEM; in afs_update_cell()
419 case -ENODATA: in afs_update_cell()
420 case -EDESTADDRREQ: in afs_update_cell()
421 vllist->status = DNS_LOOKUP_GOT_NOT_FOUND; in afs_update_cell()
423 case -EAGAIN: in afs_update_cell()
424 case -ECONNREFUSED: in afs_update_cell()
425 vllist->status = DNS_LOOKUP_GOT_TEMP_FAILURE; in afs_update_cell()
428 vllist->status = DNS_LOOKUP_GOT_LOCAL_FAILURE; in afs_update_cell()
433 _debug("%s: got list %d %d", cell->name, vllist->source, vllist->status); in afs_update_cell()
434 cell->dns_status = vllist->status; in afs_update_cell()
444 _debug("%s: status %d", cell->name, vllist->status); in afs_update_cell()
445 if (vllist->source == DNS_RECORD_UNAVAILABLE) { in afs_update_cell()
446 switch (vllist->status) { in afs_update_cell()
448 /* The DNS said that the cell does not exist or there in afs_update_cell()
451 cell->dns_expiry = expiry; in afs_update_cell()
459 cell->dns_expiry = now + 10; in afs_update_cell()
463 cell->dns_expiry = expiry; in afs_update_cell()
469 write_lock(&cell->vl_servers_lock); in afs_update_cell()
470 p = rcu_dereference_protected(cell->vl_servers, true); in afs_update_cell()
471 if (vllist->nr_servers > 0 || p->nr_servers == 0) { in afs_update_cell()
472 rcu_assign_pointer(cell->vl_servers, vllist); in afs_update_cell()
473 cell->dns_source = vllist->source; in afs_update_cell()
476 write_unlock(&cell->vl_servers_lock); in afs_update_cell()
477 afs_put_vlserverlist(cell->net, old); in afs_update_cell()
480 smp_store_release(&cell->dns_lookup_count, in afs_update_cell()
481 cell->dns_lookup_count + 1); /* vs source/status */ in afs_update_cell()
482 wake_up_var(&cell->dns_lookup_count); in afs_update_cell()
488 * Destroy a cell record
492 struct afs_cell *cell = container_of(rcu, struct afs_cell, rcu); in afs_cell_destroy() local
493 struct afs_net *net = cell->net; in afs_cell_destroy()
496 _enter("%p{%s}", cell, cell->name); in afs_cell_destroy()
498 r = refcount_read(&cell->ref); in afs_cell_destroy()
500 trace_afs_cell(cell->debug_id, r, atomic_read(&cell->active), afs_cell_trace_free); in afs_cell_destroy()
502 afs_put_vlserverlist(net, rcu_access_pointer(cell->vl_servers)); in afs_cell_destroy()
503 afs_unuse_cell(net, cell->alias_of, afs_cell_trace_unuse_alias); in afs_cell_destroy()
504 key_put(cell->anonymous_key); in afs_cell_destroy()
505 kfree(cell->name); in afs_cell_destroy()
506 kfree(cell); in afs_cell_destroy()
513 * Queue the cell manager.
517 int outstanding = atomic_inc_return(&net->cells_outstanding); in afs_queue_cell_manager()
521 if (!queue_work(afs_wq, &net->cells_manager)) in afs_queue_cell_manager()
526 * Cell management timer. We have an increment on cells_outstanding that we
534 if (!queue_work(afs_wq, &net->cells_manager)) in afs_cells_timer()
539 * Get a reference on a cell record.
541 struct afs_cell *afs_get_cell(struct afs_cell *cell, enum afs_cell_trace reason) in afs_get_cell() argument
545 __refcount_inc(&cell->ref, &r); in afs_get_cell()
546 trace_afs_cell(cell->debug_id, r + 1, atomic_read(&cell->active), reason); in afs_get_cell()
547 return cell; in afs_get_cell()
551 * Drop a reference on a cell record.
553 void afs_put_cell(struct afs_cell *cell, enum afs_cell_trace reason) in afs_put_cell() argument
555 if (cell) { in afs_put_cell()
556 unsigned int debug_id = cell->debug_id; in afs_put_cell()
561 a = atomic_read(&cell->active); in afs_put_cell()
562 zero = __refcount_dec_and_test(&cell->ref, &r); in afs_put_cell()
563 trace_afs_cell(debug_id, r - 1, a, reason); in afs_put_cell()
565 a = atomic_read(&cell->active); in afs_put_cell()
566 WARN(a != 0, "Cell active count %u > 0\n", a); in afs_put_cell()
567 call_rcu(&cell->rcu, afs_cell_destroy); in afs_put_cell()
573 * Note a cell becoming more active.
575 struct afs_cell *afs_use_cell(struct afs_cell *cell, enum afs_cell_trace reason) in afs_use_cell() argument
579 r = refcount_read(&cell->ref); in afs_use_cell()
581 a = atomic_inc_return(&cell->active); in afs_use_cell()
582 trace_afs_cell(cell->debug_id, r, a, reason); in afs_use_cell()
583 return cell; in afs_use_cell()
587 * Record a cell becoming less active. When the active counter reaches 1, it
590 void afs_unuse_cell(struct afs_net *net, struct afs_cell *cell, enum afs_cell_trace reason) in afs_unuse_cell() argument
596 if (!cell) in afs_unuse_cell()
599 _enter("%s", cell->name); in afs_unuse_cell()
602 cell->last_inactive = now; in afs_unuse_cell()
604 if (cell->vl_servers->nr_servers) in afs_unuse_cell()
607 debug_id = cell->debug_id; in afs_unuse_cell()
608 r = refcount_read(&cell->ref); in afs_unuse_cell()
609 a = atomic_dec_return(&cell->active); in afs_unuse_cell()
613 /* 'cell' may now be garbage collected. */ in afs_unuse_cell()
618 * Note that a cell has been seen.
620 void afs_see_cell(struct afs_cell *cell, enum afs_cell_trace reason) in afs_see_cell() argument
624 r = refcount_read(&cell->ref); in afs_see_cell()
625 a = atomic_read(&cell->active); in afs_see_cell()
626 trace_afs_cell(cell->debug_id, r, a, reason); in afs_see_cell()
630 * Queue a cell for management, giving the workqueue a ref to hold.
632 void afs_queue_cell(struct afs_cell *cell, enum afs_cell_trace reason) in afs_queue_cell() argument
634 afs_get_cell(cell, reason); in afs_queue_cell()
635 if (!queue_work(afs_wq, &cell->manager)) in afs_queue_cell()
636 afs_put_cell(cell, afs_cell_trace_put_queue_fail); in afs_queue_cell()
642 static int afs_alloc_anon_key(struct afs_cell *cell) in afs_alloc_anon_key() argument
650 cp = cell->name; in afs_alloc_anon_key()
659 cell->anonymous_key = key; in afs_alloc_anon_key()
662 cell->anonymous_key, key_serial(cell->anonymous_key)); in afs_alloc_anon_key()
667 * Activate a cell.
669 static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell) in afs_activate_cell() argument
675 if (!cell->anonymous_key) { in afs_activate_cell()
676 ret = afs_alloc_anon_key(cell); in afs_activate_cell()
681 ret = afs_proc_cell_setup(cell); in afs_activate_cell()
685 mutex_lock(&net->proc_cells_lock); in afs_activate_cell()
686 for (p = &net->proc_cells.first; *p; p = &(*p)->next) { in afs_activate_cell()
688 if (strcmp(cell->name, pcell->name) < 0) in afs_activate_cell()
692 cell->proc_link.pprev = p; in afs_activate_cell()
693 cell->proc_link.next = *p; in afs_activate_cell()
694 rcu_assign_pointer(*p, &cell->proc_link.next); in afs_activate_cell()
695 if (cell->proc_link.next) in afs_activate_cell()
696 cell->proc_link.next->pprev = &cell->proc_link.next; in afs_activate_cell()
698 afs_dynroot_mkdir(net, cell); in afs_activate_cell()
699 mutex_unlock(&net->proc_cells_lock); in afs_activate_cell()
704 * Deactivate a cell.
706 static void afs_deactivate_cell(struct afs_net *net, struct afs_cell *cell) in afs_deactivate_cell() argument
708 _enter("%s", cell->name); in afs_deactivate_cell()
710 afs_proc_cell_remove(cell); in afs_deactivate_cell()
712 mutex_lock(&net->proc_cells_lock); in afs_deactivate_cell()
713 hlist_del_rcu(&cell->proc_link); in afs_deactivate_cell()
714 afs_dynroot_rmdir(net, cell); in afs_deactivate_cell()
715 mutex_unlock(&net->proc_cells_lock); in afs_deactivate_cell()
721 * Manage a cell record, initialising and destroying it, maintaining its DNS
724 static void afs_manage_cell(struct afs_cell *cell) in afs_manage_cell() argument
726 struct afs_net *net = cell->net; in afs_manage_cell()
729 _enter("%s", cell->name); in afs_manage_cell()
732 _debug("state %u", cell->state); in afs_manage_cell()
733 switch (cell->state) { in afs_manage_cell()
736 down_write(&net->cells_lock); in afs_manage_cell()
738 if (atomic_try_cmpxchg_relaxed(&cell->active, &active, 0)) { in afs_manage_cell()
739 rb_erase(&cell->net_node, &net->cells); in afs_manage_cell()
740 trace_afs_cell(cell->debug_id, refcount_read(&cell->ref), 0, in afs_manage_cell()
742 smp_store_release(&cell->state, AFS_CELL_REMOVED); in afs_manage_cell()
744 up_write(&net->cells_lock); in afs_manage_cell()
745 if (cell->state == AFS_CELL_REMOVED) { in afs_manage_cell()
746 wake_up_var(&cell->state); in afs_manage_cell()
749 if (cell->state == AFS_CELL_FAILED) in afs_manage_cell()
751 smp_store_release(&cell->state, AFS_CELL_UNSET); in afs_manage_cell()
752 wake_up_var(&cell->state); in afs_manage_cell()
756 smp_store_release(&cell->state, AFS_CELL_ACTIVATING); in afs_manage_cell()
757 wake_up_var(&cell->state); in afs_manage_cell()
761 ret = afs_activate_cell(net, cell); in afs_manage_cell()
765 smp_store_release(&cell->state, AFS_CELL_ACTIVE); in afs_manage_cell()
766 wake_up_var(&cell->state); in afs_manage_cell()
770 if (atomic_read(&cell->active) > 1) { in afs_manage_cell()
771 if (test_and_clear_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags)) { in afs_manage_cell()
772 ret = afs_update_cell(cell); in afs_manage_cell()
774 cell->error = ret; in afs_manage_cell()
778 smp_store_release(&cell->state, AFS_CELL_DEACTIVATING); in afs_manage_cell()
779 wake_up_var(&cell->state); in afs_manage_cell()
783 if (atomic_read(&cell->active) > 1) in afs_manage_cell()
785 afs_deactivate_cell(net, cell); in afs_manage_cell()
786 smp_store_release(&cell->state, AFS_CELL_INACTIVE); in afs_manage_cell()
787 wake_up_var(&cell->state); in afs_manage_cell()
796 _debug("bad state %u", cell->state); in afs_manage_cell()
800 cell->error = ret; in afs_manage_cell()
801 afs_deactivate_cell(net, cell); in afs_manage_cell()
803 smp_store_release(&cell->state, AFS_CELL_FAILED); /* vs error */ in afs_manage_cell()
804 wake_up_var(&cell->state); in afs_manage_cell()
808 smp_store_release(&cell->state, AFS_CELL_ACTIVE); in afs_manage_cell()
809 wake_up_var(&cell->state); in afs_manage_cell()
810 _leave(" [deact->act]"); in afs_manage_cell()
814 _leave(" [done %u]", cell->state); in afs_manage_cell()
818 /* The root volume is pinning the cell */ in afs_manage_cell()
819 afs_put_volume(cell->root_volume, afs_volume_trace_put_cell_root); in afs_manage_cell()
820 cell->root_volume = NULL; in afs_manage_cell()
821 afs_put_cell(cell, afs_cell_trace_put_destroy); in afs_manage_cell()
826 struct afs_cell *cell = container_of(work, struct afs_cell, manager); in afs_manage_cell_work() local
828 afs_manage_cell(cell); in afs_manage_cell_work()
829 afs_put_cell(cell, afs_cell_trace_put_queue_work); in afs_manage_cell_work()
837 * Note that constructed cell records may only be removed from net->cells by
842 * Note also that we were given an increment on net->cells_outstanding by
850 bool purging = !net->live; in afs_manage_cells()
854 /* Trawl the cell database looking for cells that have expired from in afs_manage_cells()
858 down_read(&net->cells_lock); in afs_manage_cells()
860 for (cursor = rb_first(&net->cells); cursor; cursor = rb_next(cursor)) { in afs_manage_cells()
861 struct afs_cell *cell = in afs_manage_cells() local
866 active = atomic_read(&cell->active); in afs_manage_cells()
867 trace_afs_cell(cell->debug_id, refcount_read(&cell->ref), in afs_manage_cells()
873 if (test_and_clear_bit(AFS_CELL_FL_NO_GC, &cell->flags)) { in afs_manage_cells()
874 active = atomic_dec_return(&cell->active); in afs_manage_cells()
875 trace_afs_cell(cell->debug_id, refcount_read(&cell->ref), in afs_manage_cells()
882 time64_t expire_at = cell->last_inactive; in afs_manage_cells()
884 read_lock(&cell->vl_servers_lock); in afs_manage_cells()
886 cell->vl_servers, in afs_manage_cells()
887 lockdep_is_held(&cell->vl_servers_lock)); in afs_manage_cells()
888 if (vllist->nr_servers > 0) in afs_manage_cells()
890 read_unlock(&cell->vl_servers_lock); in afs_manage_cells()
898 if (test_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags)) in afs_manage_cells()
903 afs_queue_cell(cell, afs_cell_trace_get_queue_manage); in afs_manage_cells()
906 up_read(&net->cells_lock); in afs_manage_cells()
915 if (next_manage - now <= 0) { in afs_manage_cells()
916 if (queue_work(afs_wq, &net->cells_manager)) in afs_manage_cells()
917 atomic_inc(&net->cells_outstanding); in afs_manage_cells()
919 afs_set_cell_timer(net, next_manage - now); in afs_manage_cells()
924 _leave(" [%d]", atomic_read(&net->cells_outstanding)); in afs_manage_cells()
928 * Purge in-memory cell database.
936 down_write(&net->cells_lock); in afs_cell_purge()
937 ws = net->ws_cell; in afs_cell_purge()
938 net->ws_cell = NULL; in afs_cell_purge()
939 up_write(&net->cells_lock); in afs_cell_purge()
943 if (del_timer_sync(&net->cells_timer)) in afs_cell_purge()
944 atomic_dec(&net->cells_outstanding); in afs_cell_purge()
950 wait_var_event(&net->cells_outstanding, in afs_cell_purge()
951 !atomic_read(&net->cells_outstanding)); in afs_cell_purge()