server.c (c56f9ec8b20f931014574b943590c4d830109380) server.c (2757a4dc184997c66ef1de32636f73b9f21aac14)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/* AFS server record management
3 *
4 * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
6 */
7
8#include <linux/sched.h>

--- 229 unchanged lines hidden (view full) ---

238 INIT_WORK(&server->initcb_work, afs_server_init_callback_work);
239 init_waitqueue_head(&server->probe_wq);
240 INIT_LIST_HEAD(&server->probe_link);
241 spin_lock_init(&server->probe_lock);
242 server->cell = cell;
243 server->rtt = UINT_MAX;
244
245 afs_inc_servers_outstanding(net);
1// SPDX-License-Identifier: GPL-2.0-or-later
2/* AFS server record management
3 *
4 * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
6 */
7
8#include <linux/sched.h>

--- 229 unchanged lines hidden (view full) ---

238 INIT_WORK(&server->initcb_work, afs_server_init_callback_work);
239 init_waitqueue_head(&server->probe_wq);
240 INIT_LIST_HEAD(&server->probe_link);
241 spin_lock_init(&server->probe_lock);
242 server->cell = cell;
243 server->rtt = UINT_MAX;
244
245 afs_inc_servers_outstanding(net);
246 trace_afs_server(server, 1, 1, afs_server_trace_alloc);
246 trace_afs_server(server->debug_id, 1, 1, afs_server_trace_alloc);
247 _leave(" = %p", server);
248 return server;
249
250enomem:
251 _leave(" = NULL [nomem]");
252 return NULL;
253}
254

--- 92 unchanged lines hidden (view full) ---

347}
348
349/*
350 * Get a reference on a server object.
351 */
352struct afs_server *afs_get_server(struct afs_server *server,
353 enum afs_server_trace reason)
354{
247 _leave(" = %p", server);
248 return server;
249
250enomem:
251 _leave(" = NULL [nomem]");
252 return NULL;
253}
254

--- 92 unchanged lines hidden (view full) ---

347}
348
349/*
350 * Get a reference on a server object.
351 */
352struct afs_server *afs_get_server(struct afs_server *server,
353 enum afs_server_trace reason)
354{
355 unsigned int a;
355 int r;
356
357 __refcount_inc(&server->ref, &r);
356 int r;
357
358 __refcount_inc(&server->ref, &r);
358 trace_afs_server(server, r + 1, atomic_read(&server->active), reason);
359 a = atomic_read(&server->active);
360 trace_afs_server(server->debug_id, r + 1, a, reason);
359 return server;
360}
361
362/*
363 * Try to get a reference on a server object.
364 */
365static struct afs_server *afs_maybe_use_server(struct afs_server *server,
366 enum afs_server_trace reason)
367{
368 unsigned int a;
369 int r;
370
371 if (!__refcount_inc_not_zero(&server->ref, &r))
372 return NULL;
373
374 a = atomic_inc_return(&server->active);
361 return server;
362}
363
364/*
365 * Try to get a reference on a server object.
366 */
367static struct afs_server *afs_maybe_use_server(struct afs_server *server,
368 enum afs_server_trace reason)
369{
370 unsigned int a;
371 int r;
372
373 if (!__refcount_inc_not_zero(&server->ref, &r))
374 return NULL;
375
376 a = atomic_inc_return(&server->active);
375 trace_afs_server(server, r + 1, a, reason);
377 trace_afs_server(server->debug_id, r + 1, a, reason);
376 return server;
377}
378
379/*
380 * Get an active count on a server object.
381 */
382struct afs_server *afs_use_server(struct afs_server *server, enum afs_server_trace reason)
383{
384 unsigned int a;
385 int r;
386
387 __refcount_inc(&server->ref, &r);
388 a = atomic_inc_return(&server->active);
389
378 return server;
379}
380
381/*
382 * Get an active count on a server object.
383 */
384struct afs_server *afs_use_server(struct afs_server *server, enum afs_server_trace reason)
385{
386 unsigned int a;
387 int r;
388
389 __refcount_inc(&server->ref, &r);
390 a = atomic_inc_return(&server->active);
391
390 trace_afs_server(server, r + 1, a, reason);
392 trace_afs_server(server->debug_id, r + 1, a, reason);
391 return server;
392}
393
394/*
395 * Release a reference on a server record.
396 */
397void afs_put_server(struct afs_net *net, struct afs_server *server,
398 enum afs_server_trace reason)
399{
393 return server;
394}
395
396/*
397 * Release a reference on a server record.
398 */
399void afs_put_server(struct afs_net *net, struct afs_server *server,
400 enum afs_server_trace reason)
401{
402 unsigned int a, debug_id = server->debug_id;
400 bool zero;
401 int r;
402
403 if (!server)
404 return;
405
403 bool zero;
404 int r;
405
406 if (!server)
407 return;
408
409 a = atomic_inc_return(&server->active);
406 zero = __refcount_dec_and_test(&server->ref, &r);
410 zero = __refcount_dec_and_test(&server->ref, &r);
407 trace_afs_server(server, r - 1, atomic_read(&server->active), reason);
411 trace_afs_server(debug_id, r - 1, a, reason);
408 if (unlikely(zero))
409 __afs_put_server(net, server);
410}
411
412/*
413 * Drop an active count on a server object without updating the last-unused
414 * time.
415 */

--- 20 unchanged lines hidden (view full) ---

436 afs_unuse_server_notime(net, server, reason);
437 }
438}
439
440static void afs_server_rcu(struct rcu_head *rcu)
441{
442 struct afs_server *server = container_of(rcu, struct afs_server, rcu);
443
412 if (unlikely(zero))
413 __afs_put_server(net, server);
414}
415
416/*
417 * Drop an active count on a server object without updating the last-unused
418 * time.
419 */

--- 20 unchanged lines hidden (view full) ---

440 afs_unuse_server_notime(net, server, reason);
441 }
442}
443
444static void afs_server_rcu(struct rcu_head *rcu)
445{
446 struct afs_server *server = container_of(rcu, struct afs_server, rcu);
447
444 trace_afs_server(server, refcount_read(&server->ref),
448 trace_afs_server(server->debug_id, refcount_read(&server->ref),
445 atomic_read(&server->active), afs_server_trace_free);
446 afs_put_addrlist(rcu_access_pointer(server->addresses));
447 kfree(server);
448}
449
450static void __afs_put_server(struct afs_net *net, struct afs_server *server)
451{
452 call_rcu(&server->rcu, afs_server_rcu);

--- 34 unchanged lines hidden (view full) ---

487
488 while ((server = gc_list)) {
489 gc_list = server->gc_next;
490
491 write_seqlock(&net->fs_lock);
492
493 active = atomic_read(&server->active);
494 if (active == 0) {
449 atomic_read(&server->active), afs_server_trace_free);
450 afs_put_addrlist(rcu_access_pointer(server->addresses));
451 kfree(server);
452}
453
454static void __afs_put_server(struct afs_net *net, struct afs_server *server)
455{
456 call_rcu(&server->rcu, afs_server_rcu);

--- 34 unchanged lines hidden (view full) ---

491
492 while ((server = gc_list)) {
493 gc_list = server->gc_next;
494
495 write_seqlock(&net->fs_lock);
496
497 active = atomic_read(&server->active);
498 if (active == 0) {
495 trace_afs_server(server, refcount_read(&server->ref),
499 trace_afs_server(server->debug_id, refcount_read(&server->ref),
496 active, afs_server_trace_gc);
497 next = rcu_dereference_protected(
498 server->uuid_next, lockdep_is_held(&net->fs_lock.lock));
499 prev = server->uuid_prev;
500 if (!prev) {
501 /* The one at the front is in the tree */
502 if (!next) {
503 rb_erase(&server->uuid_rb, &net->fs_servers);

--- 49 unchanged lines hidden (view full) ---

553 for (cursor = rb_first(&net->fs_servers); cursor; cursor = rb_next(cursor)) {
554 struct afs_server *server =
555 rb_entry(cursor, struct afs_server, uuid_rb);
556 int active = atomic_read(&server->active);
557
558 _debug("manage %pU %u", &server->uuid, active);
559
560 if (purging) {
500 active, afs_server_trace_gc);
501 next = rcu_dereference_protected(
502 server->uuid_next, lockdep_is_held(&net->fs_lock.lock));
503 prev = server->uuid_prev;
504 if (!prev) {
505 /* The one at the front is in the tree */
506 if (!next) {
507 rb_erase(&server->uuid_rb, &net->fs_servers);

--- 49 unchanged lines hidden (view full) ---

557 for (cursor = rb_first(&net->fs_servers); cursor; cursor = rb_next(cursor)) {
558 struct afs_server *server =
559 rb_entry(cursor, struct afs_server, uuid_rb);
560 int active = atomic_read(&server->active);
561
562 _debug("manage %pU %u", &server->uuid, active);
563
564 if (purging) {
561 trace_afs_server(server, refcount_read(&server->ref),
565 trace_afs_server(server->debug_id, refcount_read(&server->ref),
562 active, afs_server_trace_purging);
563 if (active != 0)
564 pr_notice("Can't purge s=%08x\n", server->debug_id);
565 }
566
567 if (active == 0) {
568 time64_t expire_at = server->unuse_time;
569

--- 63 unchanged lines hidden (view full) ---

633 */
634static noinline bool afs_update_server_record(struct afs_operation *op,
635 struct afs_server *server)
636{
637 struct afs_addr_list *alist, *discard;
638
639 _enter("");
640
566 active, afs_server_trace_purging);
567 if (active != 0)
568 pr_notice("Can't purge s=%08x\n", server->debug_id);
569 }
570
571 if (active == 0) {
572 time64_t expire_at = server->unuse_time;
573

--- 63 unchanged lines hidden (view full) ---

637 */
638static noinline bool afs_update_server_record(struct afs_operation *op,
639 struct afs_server *server)
640{
641 struct afs_addr_list *alist, *discard;
642
643 _enter("");
644
641 trace_afs_server(server, refcount_read(&server->ref),
645 trace_afs_server(server->debug_id, refcount_read(&server->ref),
642 atomic_read(&server->active),
643 afs_server_trace_update);
644
645 alist = afs_vl_lookup_addrs(op->volume->cell, op->key, &server->uuid);
646 if (IS_ERR(alist)) {
647 if ((PTR_ERR(alist) == -ERESTARTSYS ||
648 PTR_ERR(alist) == -EINTR) &&
649 (op->flags & AFS_OPERATION_UNINTR) &&

--- 72 unchanged lines hidden ---
646 atomic_read(&server->active),
647 afs_server_trace_update);
648
649 alist = afs_vl_lookup_addrs(op->volume->cell, op->key, &server->uuid);
650 if (IS_ERR(alist)) {
651 if ((PTR_ERR(alist) == -ERESTARTSYS ||
652 PTR_ERR(alist) == -EINTR) &&
653 (op->flags & AFS_OPERATION_UNINTR) &&

--- 72 unchanged lines hidden ---