0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/sched.h>
0009 #include <linux/slab.h>
0010 #include "afs_fs.h"
0011 #include "internal.h"
0012 #include "protocol_yfs.h"
0013
0014 static unsigned afs_server_gc_delay = 10;
0015 static atomic_t afs_server_debug_id;
0016
0017 static struct afs_server *afs_maybe_use_server(struct afs_server *,
0018 enum afs_server_trace);
0019 static void __afs_put_server(struct afs_net *, struct afs_server *);
0020
0021
0022
0023
0024 struct afs_server *afs_find_server(struct afs_net *net,
0025 const struct sockaddr_rxrpc *srx)
0026 {
0027 const struct afs_addr_list *alist;
0028 struct afs_server *server = NULL;
0029 unsigned int i;
0030 int seq = 0, diff;
0031
0032 rcu_read_lock();
0033
0034 do {
0035 if (server)
0036 afs_unuse_server_notime(net, server, afs_server_trace_put_find_rsq);
0037 server = NULL;
0038 read_seqbegin_or_lock(&net->fs_addr_lock, &seq);
0039
0040 if (srx->transport.family == AF_INET6) {
0041 const struct sockaddr_in6 *a = &srx->transport.sin6, *b;
0042 hlist_for_each_entry_rcu(server, &net->fs_addresses6, addr6_link) {
0043 alist = rcu_dereference(server->addresses);
0044 for (i = alist->nr_ipv4; i < alist->nr_addrs; i++) {
0045 b = &alist->addrs[i].transport.sin6;
0046 diff = ((u16 __force)a->sin6_port -
0047 (u16 __force)b->sin6_port);
0048 if (diff == 0)
0049 diff = memcmp(&a->sin6_addr,
0050 &b->sin6_addr,
0051 sizeof(struct in6_addr));
0052 if (diff == 0)
0053 goto found;
0054 }
0055 }
0056 } else {
0057 const struct sockaddr_in *a = &srx->transport.sin, *b;
0058 hlist_for_each_entry_rcu(server, &net->fs_addresses4, addr4_link) {
0059 alist = rcu_dereference(server->addresses);
0060 for (i = 0; i < alist->nr_ipv4; i++) {
0061 b = &alist->addrs[i].transport.sin;
0062 diff = ((u16 __force)a->sin_port -
0063 (u16 __force)b->sin_port);
0064 if (diff == 0)
0065 diff = ((u32 __force)a->sin_addr.s_addr -
0066 (u32 __force)b->sin_addr.s_addr);
0067 if (diff == 0)
0068 goto found;
0069 }
0070 }
0071 }
0072
0073 server = NULL;
0074 continue;
0075 found:
0076 server = afs_maybe_use_server(server, afs_server_trace_get_by_addr);
0077
0078 } while (need_seqretry(&net->fs_addr_lock, seq));
0079
0080 done_seqretry(&net->fs_addr_lock, seq);
0081
0082 rcu_read_unlock();
0083 return server;
0084 }
0085
0086
0087
0088
0089 struct afs_server *afs_find_server_by_uuid(struct afs_net *net, const uuid_t *uuid)
0090 {
0091 struct afs_server *server = NULL;
0092 struct rb_node *p;
0093 int diff, seq = 0;
0094
0095 _enter("%pU", uuid);
0096
0097 do {
0098
0099
0100
0101
0102 if (server)
0103 afs_unuse_server(net, server, afs_server_trace_put_uuid_rsq);
0104 server = NULL;
0105
0106 read_seqbegin_or_lock(&net->fs_lock, &seq);
0107
0108 p = net->fs_servers.rb_node;
0109 while (p) {
0110 server = rb_entry(p, struct afs_server, uuid_rb);
0111
0112 diff = memcmp(uuid, &server->uuid, sizeof(*uuid));
0113 if (diff < 0) {
0114 p = p->rb_left;
0115 } else if (diff > 0) {
0116 p = p->rb_right;
0117 } else {
0118 afs_use_server(server, afs_server_trace_get_by_uuid);
0119 break;
0120 }
0121
0122 server = NULL;
0123 }
0124 } while (need_seqretry(&net->fs_lock, seq));
0125
0126 done_seqretry(&net->fs_lock, seq);
0127
0128 _leave(" = %p", server);
0129 return server;
0130 }
0131
0132
0133
0134
0135
0136
0137 static struct afs_server *afs_install_server(struct afs_cell *cell,
0138 struct afs_server *candidate)
0139 {
0140 const struct afs_addr_list *alist;
0141 struct afs_server *server, *next;
0142 struct afs_net *net = cell->net;
0143 struct rb_node **pp, *p;
0144 int diff;
0145
0146 _enter("%p", candidate);
0147
0148 write_seqlock(&net->fs_lock);
0149
0150
0151 pp = &net->fs_servers.rb_node;
0152 p = NULL;
0153 while (*pp) {
0154 p = *pp;
0155 _debug("- consider %p", p);
0156 server = rb_entry(p, struct afs_server, uuid_rb);
0157 diff = memcmp(&candidate->uuid, &server->uuid, sizeof(uuid_t));
0158 if (diff < 0) {
0159 pp = &(*pp)->rb_left;
0160 } else if (diff > 0) {
0161 pp = &(*pp)->rb_right;
0162 } else {
0163 if (server->cell == cell)
0164 goto exists;
0165
0166
0167
0168
0169 for (;;) {
0170 next = rcu_dereference_protected(
0171 server->uuid_next,
0172 lockdep_is_held(&net->fs_lock.lock));
0173 if (!next)
0174 break;
0175 server = next;
0176 }
0177 rcu_assign_pointer(server->uuid_next, candidate);
0178 candidate->uuid_prev = server;
0179 server = candidate;
0180 goto added_dup;
0181 }
0182 }
0183
0184 server = candidate;
0185 rb_link_node(&server->uuid_rb, p, pp);
0186 rb_insert_color(&server->uuid_rb, &net->fs_servers);
0187 hlist_add_head_rcu(&server->proc_link, &net->fs_proc);
0188
0189 added_dup:
0190 write_seqlock(&net->fs_addr_lock);
0191 alist = rcu_dereference_protected(server->addresses,
0192 lockdep_is_held(&net->fs_addr_lock.lock));
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202 if (alist->nr_ipv4 > 0)
0203 hlist_add_head_rcu(&server->addr4_link, &net->fs_addresses4);
0204 if (alist->nr_addrs > alist->nr_ipv4)
0205 hlist_add_head_rcu(&server->addr6_link, &net->fs_addresses6);
0206
0207 write_sequnlock(&net->fs_addr_lock);
0208
0209 exists:
0210 afs_get_server(server, afs_server_trace_get_install);
0211 write_sequnlock(&net->fs_lock);
0212 return server;
0213 }
0214
0215
0216
0217
0218 static struct afs_server *afs_alloc_server(struct afs_cell *cell,
0219 const uuid_t *uuid,
0220 struct afs_addr_list *alist)
0221 {
0222 struct afs_server *server;
0223 struct afs_net *net = cell->net;
0224
0225 _enter("");
0226
0227 server = kzalloc(sizeof(struct afs_server), GFP_KERNEL);
0228 if (!server)
0229 goto enomem;
0230
0231 refcount_set(&server->ref, 1);
0232 atomic_set(&server->active, 1);
0233 server->debug_id = atomic_inc_return(&afs_server_debug_id);
0234 RCU_INIT_POINTER(server->addresses, alist);
0235 server->addr_version = alist->version;
0236 server->uuid = *uuid;
0237 rwlock_init(&server->fs_lock);
0238 INIT_WORK(&server->initcb_work, afs_server_init_callback_work);
0239 init_waitqueue_head(&server->probe_wq);
0240 INIT_LIST_HEAD(&server->probe_link);
0241 spin_lock_init(&server->probe_lock);
0242 server->cell = cell;
0243 server->rtt = UINT_MAX;
0244
0245 afs_inc_servers_outstanding(net);
0246 trace_afs_server(server->debug_id, 1, 1, afs_server_trace_alloc);
0247 _leave(" = %p", server);
0248 return server;
0249
0250 enomem:
0251 _leave(" = NULL [nomem]");
0252 return NULL;
0253 }
0254
0255
0256
0257
0258 static struct afs_addr_list *afs_vl_lookup_addrs(struct afs_cell *cell,
0259 struct key *key, const uuid_t *uuid)
0260 {
0261 struct afs_vl_cursor vc;
0262 struct afs_addr_list *alist = NULL;
0263 int ret;
0264
0265 ret = -ERESTARTSYS;
0266 if (afs_begin_vlserver_operation(&vc, cell, key)) {
0267 while (afs_select_vlserver(&vc)) {
0268 if (test_bit(AFS_VLSERVER_FL_IS_YFS, &vc.server->flags))
0269 alist = afs_yfsvl_get_endpoints(&vc, uuid);
0270 else
0271 alist = afs_vl_get_addrs_u(&vc, uuid);
0272 }
0273
0274 ret = afs_end_vlserver_operation(&vc);
0275 }
0276
0277 return ret < 0 ? ERR_PTR(ret) : alist;
0278 }
0279
0280
0281
0282
0283 struct afs_server *afs_lookup_server(struct afs_cell *cell, struct key *key,
0284 const uuid_t *uuid, u32 addr_version)
0285 {
0286 struct afs_addr_list *alist;
0287 struct afs_server *server, *candidate;
0288
0289 _enter("%p,%pU", cell->net, uuid);
0290
0291 server = afs_find_server_by_uuid(cell->net, uuid);
0292 if (server) {
0293 if (server->addr_version != addr_version)
0294 set_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags);
0295 return server;
0296 }
0297
0298 alist = afs_vl_lookup_addrs(cell, key, uuid);
0299 if (IS_ERR(alist))
0300 return ERR_CAST(alist);
0301
0302 candidate = afs_alloc_server(cell, uuid, alist);
0303 if (!candidate) {
0304 afs_put_addrlist(alist);
0305 return ERR_PTR(-ENOMEM);
0306 }
0307
0308 server = afs_install_server(cell, candidate);
0309 if (server != candidate) {
0310 afs_put_addrlist(alist);
0311 kfree(candidate);
0312 } else {
0313
0314
0315
0316
0317 afs_fs_probe_fileserver(cell->net, server, key, true);
0318 }
0319
0320 return server;
0321 }
0322
0323
0324
0325
0326
0327 static void afs_set_server_timer(struct afs_net *net, time64_t delay)
0328 {
0329 if (net->live) {
0330 afs_inc_servers_outstanding(net);
0331 if (timer_reduce(&net->fs_timer, jiffies + delay * HZ))
0332 afs_dec_servers_outstanding(net);
0333 }
0334 }
0335
0336
0337
0338
0339
0340 void afs_servers_timer(struct timer_list *timer)
0341 {
0342 struct afs_net *net = container_of(timer, struct afs_net, fs_timer);
0343
0344 _enter("");
0345 if (!queue_work(afs_wq, &net->fs_manager))
0346 afs_dec_servers_outstanding(net);
0347 }
0348
0349
0350
0351
0352 struct afs_server *afs_get_server(struct afs_server *server,
0353 enum afs_server_trace reason)
0354 {
0355 unsigned int a;
0356 int r;
0357
0358 __refcount_inc(&server->ref, &r);
0359 a = atomic_read(&server->active);
0360 trace_afs_server(server->debug_id, r + 1, a, reason);
0361 return server;
0362 }
0363
0364
0365
0366
0367 static struct afs_server *afs_maybe_use_server(struct afs_server *server,
0368 enum afs_server_trace reason)
0369 {
0370 unsigned int a;
0371 int r;
0372
0373 if (!__refcount_inc_not_zero(&server->ref, &r))
0374 return NULL;
0375
0376 a = atomic_inc_return(&server->active);
0377 trace_afs_server(server->debug_id, r + 1, a, reason);
0378 return server;
0379 }
0380
0381
0382
0383
0384 struct afs_server *afs_use_server(struct afs_server *server, enum afs_server_trace reason)
0385 {
0386 unsigned int a;
0387 int r;
0388
0389 __refcount_inc(&server->ref, &r);
0390 a = atomic_inc_return(&server->active);
0391
0392 trace_afs_server(server->debug_id, r + 1, a, reason);
0393 return server;
0394 }
0395
0396
0397
0398
0399 void afs_put_server(struct afs_net *net, struct afs_server *server,
0400 enum afs_server_trace reason)
0401 {
0402 unsigned int a, debug_id = server->debug_id;
0403 bool zero;
0404 int r;
0405
0406 if (!server)
0407 return;
0408
0409 a = atomic_inc_return(&server->active);
0410 zero = __refcount_dec_and_test(&server->ref, &r);
0411 trace_afs_server(debug_id, r - 1, a, reason);
0412 if (unlikely(zero))
0413 __afs_put_server(net, server);
0414 }
0415
0416
0417
0418
0419
0420 void afs_unuse_server_notime(struct afs_net *net, struct afs_server *server,
0421 enum afs_server_trace reason)
0422 {
0423 if (server) {
0424 unsigned int active = atomic_dec_return(&server->active);
0425
0426 if (active == 0)
0427 afs_set_server_timer(net, afs_server_gc_delay);
0428 afs_put_server(net, server, reason);
0429 }
0430 }
0431
0432
0433
0434
0435 void afs_unuse_server(struct afs_net *net, struct afs_server *server,
0436 enum afs_server_trace reason)
0437 {
0438 if (server) {
0439 server->unuse_time = ktime_get_real_seconds();
0440 afs_unuse_server_notime(net, server, reason);
0441 }
0442 }
0443
0444 static void afs_server_rcu(struct rcu_head *rcu)
0445 {
0446 struct afs_server *server = container_of(rcu, struct afs_server, rcu);
0447
0448 trace_afs_server(server->debug_id, refcount_read(&server->ref),
0449 atomic_read(&server->active), afs_server_trace_free);
0450 afs_put_addrlist(rcu_access_pointer(server->addresses));
0451 kfree(server);
0452 }
0453
0454 static void __afs_put_server(struct afs_net *net, struct afs_server *server)
0455 {
0456 call_rcu(&server->rcu, afs_server_rcu);
0457 afs_dec_servers_outstanding(net);
0458 }
0459
0460 static void afs_give_up_callbacks(struct afs_net *net, struct afs_server *server)
0461 {
0462 struct afs_addr_list *alist = rcu_access_pointer(server->addresses);
0463 struct afs_addr_cursor ac = {
0464 .alist = alist,
0465 .index = alist->preferred,
0466 .error = 0,
0467 };
0468
0469 afs_fs_give_up_all_callbacks(net, server, &ac, NULL);
0470 }
0471
0472
0473
0474
0475 static void afs_destroy_server(struct afs_net *net, struct afs_server *server)
0476 {
0477 if (test_bit(AFS_SERVER_FL_MAY_HAVE_CB, &server->flags))
0478 afs_give_up_callbacks(net, server);
0479
0480 flush_work(&server->initcb_work);
0481 afs_put_server(net, server, afs_server_trace_destroy);
0482 }
0483
0484
0485
0486
0487 static void afs_gc_servers(struct afs_net *net, struct afs_server *gc_list)
0488 {
0489 struct afs_server *server, *next, *prev;
0490 int active;
0491
0492 while ((server = gc_list)) {
0493 gc_list = server->gc_next;
0494
0495 write_seqlock(&net->fs_lock);
0496
0497 active = atomic_read(&server->active);
0498 if (active == 0) {
0499 trace_afs_server(server->debug_id, refcount_read(&server->ref),
0500 active, afs_server_trace_gc);
0501 next = rcu_dereference_protected(
0502 server->uuid_next, lockdep_is_held(&net->fs_lock.lock));
0503 prev = server->uuid_prev;
0504 if (!prev) {
0505
0506 if (!next) {
0507 rb_erase(&server->uuid_rb, &net->fs_servers);
0508 } else {
0509 rb_replace_node_rcu(&server->uuid_rb,
0510 &next->uuid_rb,
0511 &net->fs_servers);
0512 next->uuid_prev = NULL;
0513 }
0514 } else {
0515
0516 rcu_assign_pointer(prev->uuid_next, next);
0517 if (next)
0518 next->uuid_prev = prev;
0519 }
0520
0521 list_del(&server->probe_link);
0522 hlist_del_rcu(&server->proc_link);
0523 if (!hlist_unhashed(&server->addr4_link))
0524 hlist_del_rcu(&server->addr4_link);
0525 if (!hlist_unhashed(&server->addr6_link))
0526 hlist_del_rcu(&server->addr6_link);
0527 }
0528 write_sequnlock(&net->fs_lock);
0529
0530 if (active == 0)
0531 afs_destroy_server(net, server);
0532 }
0533 }
0534
0535
0536
0537
0538
0539
0540
0541
0542 void afs_manage_servers(struct work_struct *work)
0543 {
0544 struct afs_net *net = container_of(work, struct afs_net, fs_manager);
0545 struct afs_server *gc_list = NULL;
0546 struct rb_node *cursor;
0547 time64_t now = ktime_get_real_seconds(), next_manage = TIME64_MAX;
0548 bool purging = !net->live;
0549
0550 _enter("");
0551
0552
0553
0554
0555 read_seqlock_excl(&net->fs_lock);
0556
0557 for (cursor = rb_first(&net->fs_servers); cursor; cursor = rb_next(cursor)) {
0558 struct afs_server *server =
0559 rb_entry(cursor, struct afs_server, uuid_rb);
0560 int active = atomic_read(&server->active);
0561
0562 _debug("manage %pU %u", &server->uuid, active);
0563
0564 if (purging) {
0565 trace_afs_server(server->debug_id, refcount_read(&server->ref),
0566 active, afs_server_trace_purging);
0567 if (active != 0)
0568 pr_notice("Can't purge s=%08x\n", server->debug_id);
0569 }
0570
0571 if (active == 0) {
0572 time64_t expire_at = server->unuse_time;
0573
0574 if (!test_bit(AFS_SERVER_FL_VL_FAIL, &server->flags) &&
0575 !test_bit(AFS_SERVER_FL_NOT_FOUND, &server->flags))
0576 expire_at += afs_server_gc_delay;
0577 if (purging || expire_at <= now) {
0578 server->gc_next = gc_list;
0579 gc_list = server;
0580 } else if (expire_at < next_manage) {
0581 next_manage = expire_at;
0582 }
0583 }
0584 }
0585
0586 read_sequnlock_excl(&net->fs_lock);
0587
0588
0589
0590
0591
0592 if (!purging && next_manage < TIME64_MAX) {
0593 now = ktime_get_real_seconds();
0594
0595 if (next_manage - now <= 0) {
0596 if (queue_work(afs_wq, &net->fs_manager))
0597 afs_inc_servers_outstanding(net);
0598 } else {
0599 afs_set_server_timer(net, next_manage - now);
0600 }
0601 }
0602
0603 afs_gc_servers(net, gc_list);
0604
0605 afs_dec_servers_outstanding(net);
0606 _leave(" [%d]", atomic_read(&net->servers_outstanding));
0607 }
0608
0609 static void afs_queue_server_manager(struct afs_net *net)
0610 {
0611 afs_inc_servers_outstanding(net);
0612 if (!queue_work(afs_wq, &net->fs_manager))
0613 afs_dec_servers_outstanding(net);
0614 }
0615
0616
0617
0618
0619 void afs_purge_servers(struct afs_net *net)
0620 {
0621 _enter("");
0622
0623 if (del_timer_sync(&net->fs_timer))
0624 afs_dec_servers_outstanding(net);
0625
0626 afs_queue_server_manager(net);
0627
0628 _debug("wait");
0629 atomic_dec(&net->servers_outstanding);
0630 wait_var_event(&net->servers_outstanding,
0631 !atomic_read(&net->servers_outstanding));
0632 _leave("");
0633 }
0634
0635
0636
0637
0638 static noinline bool afs_update_server_record(struct afs_operation *op,
0639 struct afs_server *server)
0640 {
0641 struct afs_addr_list *alist, *discard;
0642
0643 _enter("");
0644
0645 trace_afs_server(server->debug_id, refcount_read(&server->ref),
0646 atomic_read(&server->active),
0647 afs_server_trace_update);
0648
0649 alist = afs_vl_lookup_addrs(op->volume->cell, op->key, &server->uuid);
0650 if (IS_ERR(alist)) {
0651 if ((PTR_ERR(alist) == -ERESTARTSYS ||
0652 PTR_ERR(alist) == -EINTR) &&
0653 (op->flags & AFS_OPERATION_UNINTR) &&
0654 server->addresses) {
0655 _leave(" = t [intr]");
0656 return true;
0657 }
0658 op->error = PTR_ERR(alist);
0659 _leave(" = f [%d]", op->error);
0660 return false;
0661 }
0662
0663 discard = alist;
0664 if (server->addr_version != alist->version) {
0665 write_lock(&server->fs_lock);
0666 discard = rcu_dereference_protected(server->addresses,
0667 lockdep_is_held(&server->fs_lock));
0668 rcu_assign_pointer(server->addresses, alist);
0669 server->addr_version = alist->version;
0670 write_unlock(&server->fs_lock);
0671 }
0672
0673 afs_put_addrlist(discard);
0674 _leave(" = t");
0675 return true;
0676 }
0677
0678
0679
0680
0681 bool afs_check_server_record(struct afs_operation *op, struct afs_server *server)
0682 {
0683 bool success;
0684 int ret, retries = 0;
0685
0686 _enter("");
0687
0688 ASSERT(server);
0689
0690 retry:
0691 if (test_bit(AFS_SERVER_FL_UPDATING, &server->flags))
0692 goto wait;
0693 if (test_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags))
0694 goto update;
0695 _leave(" = t [good]");
0696 return true;
0697
0698 update:
0699 if (!test_and_set_bit_lock(AFS_SERVER_FL_UPDATING, &server->flags)) {
0700 clear_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags);
0701 success = afs_update_server_record(op, server);
0702 clear_bit_unlock(AFS_SERVER_FL_UPDATING, &server->flags);
0703 wake_up_bit(&server->flags, AFS_SERVER_FL_UPDATING);
0704 _leave(" = %d", success);
0705 return success;
0706 }
0707
0708 wait:
0709 ret = wait_on_bit(&server->flags, AFS_SERVER_FL_UPDATING,
0710 (op->flags & AFS_OPERATION_UNINTR) ?
0711 TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE);
0712 if (ret == -ERESTARTSYS) {
0713 op->error = ret;
0714 _leave(" = f [intr]");
0715 return false;
0716 }
0717
0718 retries++;
0719 if (retries == 4) {
0720 _leave(" = f [stale]");
0721 ret = -ESTALE;
0722 return false;
0723 }
0724 goto retry;
0725 }