Lines Matching refs:cell

33 static void afs_set_cell_state(struct afs_cell *cell, enum afs_cell_state state)  in afs_set_cell_state()  argument
35 smp_store_release(&cell->state, state); /* Commit cell changes before state */ in afs_set_cell_state()
37 wake_up_var(&cell->state); in afs_set_cell_state()
48 struct afs_cell *cell = NULL; in afs_find_cell_locked() local
60 cell = rcu_dereference_protected(net->ws_cell, in afs_find_cell_locked()
62 if (!cell) in afs_find_cell_locked()
69 cell = rb_entry(p, struct afs_cell, net_node); in afs_find_cell_locked()
71 n = strncasecmp(cell->name, name, in afs_find_cell_locked()
72 min_t(size_t, cell->name_len, namesz)); in afs_find_cell_locked()
74 n = cell->name_len - namesz; in afs_find_cell_locked()
86 return afs_use_cell(cell, reason); in afs_find_cell_locked()
96 struct afs_cell *cell; in afs_find_cell() local
99 cell = afs_find_cell_locked(net, name, namesz, reason); in afs_find_cell()
101 return cell; in afs_find_cell()
113 struct afs_cell *cell; in afs_alloc_cell() local
137 cell = kzalloc(sizeof(struct afs_cell), GFP_KERNEL); in afs_alloc_cell()
138 if (!cell) { in afs_alloc_cell()
144 cell->name = kmalloc(1 + namelen + 1 + in afs_alloc_cell()
146 if (!cell->name) { in afs_alloc_cell()
147 kfree(cell); in afs_alloc_cell()
151 cell->name[0] = '.'; in afs_alloc_cell()
152 cell->name++; in afs_alloc_cell()
153 cell->name_len = namelen; in afs_alloc_cell()
155 cell->name[i] = tolower(name[i]); in afs_alloc_cell()
156 cell->name[i++] = 0; in afs_alloc_cell()
158 cell->key_desc = cell->name + i; in afs_alloc_cell()
159 memcpy(cell->key_desc, "afs@", 4); in afs_alloc_cell()
160 memcpy(cell->key_desc + 4, cell->name, cell->name_len + 1); in afs_alloc_cell()
162 cell->net = net; in afs_alloc_cell()
163 refcount_set(&cell->ref, 1); in afs_alloc_cell()
164 atomic_set(&cell->active, 0); in afs_alloc_cell()
165 INIT_WORK(&cell->destroyer, afs_destroy_cell_work); in afs_alloc_cell()
166 INIT_WORK(&cell->manager, afs_manage_cell_work); in afs_alloc_cell()
167 timer_setup(&cell->management_timer, afs_cell_timer, 0); in afs_alloc_cell()
168 init_rwsem(&cell->vs_lock); in afs_alloc_cell()
169 cell->volumes = RB_ROOT; in afs_alloc_cell()
170 INIT_HLIST_HEAD(&cell->proc_volumes); in afs_alloc_cell()
171 seqlock_init(&cell->volume_lock); in afs_alloc_cell()
172 cell->fs_servers = RB_ROOT; in afs_alloc_cell()
173 init_rwsem(&cell->fs_lock); in afs_alloc_cell()
174 rwlock_init(&cell->vl_servers_lock); in afs_alloc_cell()
175 cell->flags = (1 << AFS_CELL_FL_CHECK_ALIAS); in afs_alloc_cell()
192 cell->dns_expiry = TIME64_MAX; in afs_alloc_cell()
200 cell->dns_expiry = ktime_get_real_seconds(); in afs_alloc_cell()
203 rcu_assign_pointer(cell->vl_servers, vllist); in afs_alloc_cell()
205 cell->dns_source = vllist->source; in afs_alloc_cell()
206 cell->dns_status = vllist->status; in afs_alloc_cell()
207 smp_store_release(&cell->dns_lookup_count, 1); /* vs source/status */ in afs_alloc_cell()
209 ret = idr_alloc_cyclic(&net->cells_dyn_ino, cell, in afs_alloc_cell()
213 cell->dynroot_ino = ret; in afs_alloc_cell()
214 cell->debug_id = atomic_inc_return(&cell_debug_id); in afs_alloc_cell()
216 trace_afs_cell(cell->debug_id, 1, 0, afs_cell_trace_alloc); in afs_alloc_cell()
218 _leave(" = %p", cell); in afs_alloc_cell()
219 return cell; in afs_alloc_cell()
225 afs_put_vlserverlist(cell->net, vllist); in afs_alloc_cell()
226 kfree(cell->name - 1); in afs_alloc_cell()
227 kfree(cell); in afs_alloc_cell()
252 struct afs_cell *cell, *candidate, *cursor; in afs_lookup_cell() local
260 cell = afs_find_cell(net, name, namesz, trace); in afs_lookup_cell()
261 if (!IS_ERR(cell)) { in afs_lookup_cell()
264 if (cell->state == AFS_CELL_SETTING_UP || in afs_lookup_cell()
265 cell->state == AFS_CELL_UNLOOKED) in afs_lookup_cell()
307 cell = candidate; in afs_lookup_cell()
309 afs_use_cell(cell, trace); in afs_lookup_cell()
310 rb_link_node_rcu(&cell->net_node, parent, pp); in afs_lookup_cell()
311 rb_insert_color(&cell->net_node, &net->cells); in afs_lookup_cell()
317 set_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags); in afs_lookup_cell()
318 afs_queue_cell(cell, afs_cell_trace_queue_new); in afs_lookup_cell()
322 state = smp_load_acquire(&cell->state); /* vs error */ in afs_lookup_cell()
333 afs_see_cell(cell, afs_cell_trace_wait); in afs_lookup_cell()
334 wait_var_event(&cell->state, in afs_lookup_cell()
336 state = smp_load_acquire(&cell->state); /* vs error */ in afs_lookup_cell()
339 _debug("waited_for_cell %d %d", cell->state, cell->error); in afs_lookup_cell()
344 state = smp_load_acquire(&cell->state); /* vs error */ in afs_lookup_cell()
346 ret = cell->error; in afs_lookup_cell()
350 switch (cell->dns_status) { in afs_lookup_cell()
352 if (cell->dns_source == DNS_RECORD_FROM_CONFIG) { in afs_lookup_cell()
378 _leave(" = %p [cell]", cell); in afs_lookup_cell()
379 return cell; in afs_lookup_cell()
383 cell = cursor; in afs_lookup_cell()
397 afs_unuse_cell(cell, afs_cell_trace_unuse_lookup_error); in afs_lookup_cell()
468 static int afs_update_cell(struct afs_cell *cell) in afs_update_cell() argument
476 _enter("%s", cell->name); in afs_update_cell()
478 vllist = afs_dns_query(cell, &expiry); in afs_update_cell()
482 _debug("%s: fail %d", cell->name, ret); in afs_update_cell()
508 _debug("%s: got list %d %d", cell->name, vllist->source, vllist->status); in afs_update_cell()
509 cell->dns_status = vllist->status; in afs_update_cell()
519 _debug("%s: status %d", cell->name, vllist->status); in afs_update_cell()
526 cell->dns_expiry = expiry; in afs_update_cell()
534 cell->dns_expiry = now + 10; in afs_update_cell()
538 cell->dns_expiry = expiry; in afs_update_cell()
544 write_lock(&cell->vl_servers_lock); in afs_update_cell()
545 p = rcu_dereference_protected(cell->vl_servers, true); in afs_update_cell()
547 rcu_assign_pointer(cell->vl_servers, vllist); in afs_update_cell()
548 cell->dns_source = vllist->source; in afs_update_cell()
551 write_unlock(&cell->vl_servers_lock); in afs_update_cell()
552 afs_put_vlserverlist(cell->net, old); in afs_update_cell()
555 smp_store_release(&cell->dns_lookup_count, in afs_update_cell()
556 cell->dns_lookup_count + 1); /* vs source/status */ in afs_update_cell()
557 wake_up_var(&cell->dns_lookup_count); in afs_update_cell()
567 struct afs_cell *cell = container_of(rcu, struct afs_cell, rcu); in afs_cell_destroy() local
568 struct afs_net *net = cell->net; in afs_cell_destroy()
571 _enter("%p{%s}", cell, cell->name); in afs_cell_destroy()
573 r = refcount_read(&cell->ref); in afs_cell_destroy()
575 trace_afs_cell(cell->debug_id, r, atomic_read(&cell->active), afs_cell_trace_free); in afs_cell_destroy()
577 afs_put_vlserverlist(net, rcu_access_pointer(cell->vl_servers)); in afs_cell_destroy()
578 afs_unuse_cell(cell->alias_of, afs_cell_trace_unuse_alias); in afs_cell_destroy()
579 key_put(cell->anonymous_key); in afs_cell_destroy()
580 idr_remove(&net->cells_dyn_ino, cell->dynroot_ino); in afs_cell_destroy()
581 kfree(cell->name - 1); in afs_cell_destroy()
582 kfree(cell); in afs_cell_destroy()
590 struct afs_cell *cell = container_of(work, struct afs_cell, destroyer); in afs_destroy_cell_work() local
592 afs_see_cell(cell, afs_cell_trace_destroy); in afs_destroy_cell_work()
593 timer_delete_sync(&cell->management_timer); in afs_destroy_cell_work()
594 cancel_work_sync(&cell->manager); in afs_destroy_cell_work()
595 call_rcu(&cell->rcu, afs_cell_destroy); in afs_destroy_cell_work()
601 struct afs_cell *afs_get_cell(struct afs_cell *cell, enum afs_cell_trace reason) in afs_get_cell() argument
605 __refcount_inc(&cell->ref, &r); in afs_get_cell()
606 trace_afs_cell(cell->debug_id, r + 1, atomic_read(&cell->active), reason); in afs_get_cell()
607 return cell; in afs_get_cell()
613 void afs_put_cell(struct afs_cell *cell, enum afs_cell_trace reason) in afs_put_cell() argument
615 if (cell) { in afs_put_cell()
616 unsigned int debug_id = cell->debug_id; in afs_put_cell()
621 a = atomic_read(&cell->active); in afs_put_cell()
622 zero = __refcount_dec_and_test(&cell->ref, &r); in afs_put_cell()
625 a = atomic_read(&cell->active); in afs_put_cell()
627 WARN_ON(!queue_work(afs_wq, &cell->destroyer)); in afs_put_cell()
635 struct afs_cell *afs_use_cell(struct afs_cell *cell, enum afs_cell_trace reason) in afs_use_cell() argument
639 __refcount_inc(&cell->ref, &r); in afs_use_cell()
640 a = atomic_inc_return(&cell->active); in afs_use_cell()
641 trace_afs_cell(cell->debug_id, r + 1, a, reason); in afs_use_cell()
642 return cell; in afs_use_cell()
649 void afs_unuse_cell(struct afs_cell *cell, enum afs_cell_trace reason) in afs_unuse_cell() argument
656 if (!cell) in afs_unuse_cell()
659 _enter("%s", cell->name); in afs_unuse_cell()
662 cell->last_inactive = now; in afs_unuse_cell()
664 if (cell->vl_servers->nr_servers) in afs_unuse_cell()
667 debug_id = cell->debug_id; in afs_unuse_cell()
668 a = atomic_dec_return(&cell->active); in afs_unuse_cell()
671 afs_set_cell_timer(cell, expire_delay); in afs_unuse_cell()
673 zero = __refcount_dec_and_test(&cell->ref, &r); in afs_unuse_cell()
676 WARN_ON(!queue_work(afs_wq, &cell->destroyer)); in afs_unuse_cell()
682 void afs_see_cell(struct afs_cell *cell, enum afs_cell_trace reason) in afs_see_cell() argument
686 r = refcount_read(&cell->ref); in afs_see_cell()
687 a = atomic_read(&cell->active); in afs_see_cell()
688 trace_afs_cell(cell->debug_id, r, a, reason); in afs_see_cell()
694 void afs_queue_cell(struct afs_cell *cell, enum afs_cell_trace reason) in afs_queue_cell() argument
696 queue_work(afs_wq, &cell->manager); in afs_queue_cell()
704 struct afs_cell *cell = container_of(timer, struct afs_cell, management_timer); in afs_cell_timer() local
706 afs_see_cell(cell, afs_cell_trace_see_mgmt_timer); in afs_cell_timer()
707 if (refcount_read(&cell->ref) > 0 && cell->net->live) in afs_cell_timer()
708 queue_work(afs_wq, &cell->manager); in afs_cell_timer()
714 void afs_set_cell_timer(struct afs_cell *cell, unsigned int delay_secs) in afs_set_cell_timer() argument
716 timer_reduce(&cell->management_timer, jiffies + delay_secs * HZ); in afs_set_cell_timer()
722 static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell) in afs_activate_cell() argument
728 ret = afs_proc_cell_setup(cell); in afs_activate_cell()
735 if (strcmp(cell->name, pcell->name) < 0) in afs_activate_cell()
739 cell->proc_link.pprev = p; in afs_activate_cell()
740 cell->proc_link.next = *p; in afs_activate_cell()
741 rcu_assign_pointer(*p, &cell->proc_link.next); in afs_activate_cell()
742 if (cell->proc_link.next) in afs_activate_cell()
743 cell->proc_link.next->pprev = &cell->proc_link.next; in afs_activate_cell()
752 static void afs_deactivate_cell(struct afs_net *net, struct afs_cell *cell) in afs_deactivate_cell() argument
754 _enter("%s", cell->name); in afs_deactivate_cell()
756 afs_proc_cell_remove(cell); in afs_deactivate_cell()
759 if (!hlist_unhashed(&cell->proc_link)) in afs_deactivate_cell()
760 hlist_del_rcu(&cell->proc_link); in afs_deactivate_cell()
766 static bool afs_has_cell_expired(struct afs_cell *cell, time64_t *_next_manage) in afs_has_cell_expired() argument
769 time64_t expire_at = cell->last_inactive; in afs_has_cell_expired()
772 if (atomic_read(&cell->active)) in afs_has_cell_expired()
774 if (!cell->net->live) in afs_has_cell_expired()
777 vllist = rcu_dereference_protected(cell->vl_servers, true); in afs_has_cell_expired()
792 static bool afs_manage_cell(struct afs_cell *cell) in afs_manage_cell() argument
794 struct afs_net *net = cell->net; in afs_manage_cell()
798 _enter("%s", cell->name); in afs_manage_cell()
800 _debug("state %u", cell->state); in afs_manage_cell()
801 switch (cell->state) { in afs_manage_cell()
813 _debug("bad state %u", cell->state); in afs_manage_cell()
819 ret = afs_activate_cell(net, cell); in afs_manage_cell()
821 cell->error = ret; in afs_manage_cell()
825 afs_set_cell_state(cell, AFS_CELL_UNLOOKED); in afs_manage_cell()
828 if (afs_has_cell_expired(cell, &next_manage)) in afs_manage_cell()
831 if (test_and_clear_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags)) { in afs_manage_cell()
832 ret = afs_update_cell(cell); in afs_manage_cell()
834 cell->error = ret; in afs_manage_cell()
835 if (cell->state == AFS_CELL_UNLOOKED) in afs_manage_cell()
836 afs_set_cell_state(cell, AFS_CELL_ACTIVE); in afs_manage_cell()
839 if (next_manage < TIME64_MAX && cell->net->live) { in afs_manage_cell()
843 afs_queue_cell(cell, afs_cell_trace_queue_again); in afs_manage_cell()
845 afs_set_cell_timer(cell, next_manage - now); in afs_manage_cell()
847 _leave(" [done %u]", cell->state); in afs_manage_cell()
853 if (atomic_read(&cell->active)) { in afs_manage_cell()
861 afs_set_cell_state(cell, AFS_CELL_REMOVING); in afs_manage_cell()
863 afs_deactivate_cell(net, cell); in afs_manage_cell()
864 afs_purge_servers(cell); in afs_manage_cell()
866 rb_erase(&cell->net_node, &net->cells); in afs_manage_cell()
867 afs_see_cell(cell, afs_cell_trace_unuse_delete); in afs_manage_cell()
871 afs_put_volume(cell->root_volume, afs_volume_trace_put_cell_root); in afs_manage_cell()
872 cell->root_volume = NULL; in afs_manage_cell()
874 afs_set_cell_state(cell, AFS_CELL_DEAD); in afs_manage_cell()
880 struct afs_cell *cell = container_of(work, struct afs_cell, manager); in afs_manage_cell_work() local
883 afs_see_cell(cell, afs_cell_trace_manage); in afs_manage_cell_work()
884 final_put = afs_manage_cell(cell); in afs_manage_cell_work()
885 afs_see_cell(cell, afs_cell_trace_managed); in afs_manage_cell_work()
887 afs_put_cell(cell, afs_cell_trace_put_final); in afs_manage_cell_work()
909 struct afs_cell *cell = rb_entry(cursor, struct afs_cell, net_node); in afs_cell_purge() local
911 afs_see_cell(cell, afs_cell_trace_purge); in afs_cell_purge()
913 if (test_and_clear_bit(AFS_CELL_FL_NO_GC, &cell->flags)) in afs_cell_purge()
914 afs_unuse_cell(cell, afs_cell_trace_unuse_pin); in afs_cell_purge()
916 afs_queue_cell(cell, afs_cell_trace_queue_purge); in afs_cell_purge()