^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* AFS server record management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "afs_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "protocol_yfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) static unsigned afs_server_gc_delay = 10; /* Server record timeout in seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) static atomic_t afs_server_debug_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) static struct afs_server *afs_maybe_use_server(struct afs_server *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) enum afs_server_trace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static void __afs_put_server(struct afs_net *, struct afs_server *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Find a server by one of its addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct afs_server *afs_find_server(struct afs_net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) const struct sockaddr_rxrpc *srx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) const struct afs_addr_list *alist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct afs_server *server = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) int seq = 0, diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) if (server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) afs_unuse_server_notime(net, server, afs_server_trace_put_find_rsq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) server = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) read_seqbegin_or_lock(&net->fs_addr_lock, &seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (srx->transport.family == AF_INET6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) const struct sockaddr_in6 *a = &srx->transport.sin6, *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) hlist_for_each_entry_rcu(server, &net->fs_addresses6, addr6_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) alist = rcu_dereference(server->addresses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) for (i = alist->nr_ipv4; i < alist->nr_addrs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) b = &alist->addrs[i].transport.sin6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) diff = ((u16 __force)a->sin6_port -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) (u16 __force)b->sin6_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (diff == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) diff = memcmp(&a->sin6_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) &b->sin6_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) sizeof(struct in6_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (diff == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) const struct sockaddr_in *a = &srx->transport.sin, *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) hlist_for_each_entry_rcu(server, &net->fs_addresses4, addr4_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) alist = rcu_dereference(server->addresses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) for (i = 0; i < alist->nr_ipv4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) b = &alist->addrs[i].transport.sin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) diff = ((u16 __force)a->sin_port -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) (u16 __force)b->sin_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (diff == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) diff = ((u32 __force)a->sin_addr.s_addr -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) (u32 __force)b->sin_addr.s_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (diff == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) server = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) server = afs_maybe_use_server(server, afs_server_trace_get_by_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) } while (need_seqretry(&net->fs_addr_lock, seq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) done_seqretry(&net->fs_addr_lock, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * Look up a server by its UUID and mark it active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct afs_server *afs_find_server_by_uuid(struct afs_net *net, const uuid_t *uuid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct afs_server *server = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct rb_node *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int diff, seq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) _enter("%pU", uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* Unfortunately, rbtree walking doesn't give reliable results
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * under just the RCU read lock, so we have to check for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) afs_unuse_server(net, server, afs_server_trace_put_uuid_rsq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) server = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) read_seqbegin_or_lock(&net->fs_lock, &seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) p = net->fs_servers.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) while (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) server = rb_entry(p, struct afs_server, uuid_rb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) diff = memcmp(uuid, &server->uuid, sizeof(*uuid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (diff < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) p = p->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) } else if (diff > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) p = p->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) afs_use_server(server, afs_server_trace_get_by_uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) server = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) } while (need_seqretry(&net->fs_lock, seq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) done_seqretry(&net->fs_lock, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) _leave(" = %p", server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * Install a server record in the namespace tree. If there's a clash, we stick
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * it into a list anchored on whichever afs_server struct is actually in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static struct afs_server *afs_install_server(struct afs_cell *cell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct afs_server *candidate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) const struct afs_addr_list *alist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct afs_server *server, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct afs_net *net = cell->net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct rb_node **pp, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) int diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) _enter("%p", candidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) write_seqlock(&net->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* Firstly install the server in the UUID lookup tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) pp = &net->fs_servers.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) while (*pp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) p = *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) _debug("- consider %p", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) server = rb_entry(p, struct afs_server, uuid_rb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) diff = memcmp(&candidate->uuid, &server->uuid, sizeof(uuid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (diff < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) pp = &(*pp)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) } else if (diff > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) pp = &(*pp)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (server->cell == cell)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) goto exists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* We have the same UUID representing servers in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * different cells. Append the new server to the list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) next = rcu_dereference_protected(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) server->uuid_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) lockdep_is_held(&net->fs_lock.lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (!next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) server = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) rcu_assign_pointer(server->uuid_next, candidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) candidate->uuid_prev = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) server = candidate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) goto added_dup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) server = candidate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) rb_link_node(&server->uuid_rb, p, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) rb_insert_color(&server->uuid_rb, &net->fs_servers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) hlist_add_head_rcu(&server->proc_link, &net->fs_proc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) added_dup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) write_seqlock(&net->fs_addr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) alist = rcu_dereference_protected(server->addresses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) lockdep_is_held(&net->fs_addr_lock.lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* Secondly, if the server has any IPv4 and/or IPv6 addresses, install
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * it in the IPv4 and/or IPv6 reverse-map lists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * TODO: For speed we want to use something other than a flat list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * here; even sorting the list in terms of lowest address would help a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * bit, but anything we might want to do gets messy and memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * intensive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (alist->nr_ipv4 > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) hlist_add_head_rcu(&server->addr4_link, &net->fs_addresses4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (alist->nr_addrs > alist->nr_ipv4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) hlist_add_head_rcu(&server->addr6_link, &net->fs_addresses6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) write_sequnlock(&net->fs_addr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) exists:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) afs_get_server(server, afs_server_trace_get_install);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) write_sequnlock(&net->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * Allocate a new server record and mark it active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static struct afs_server *afs_alloc_server(struct afs_cell *cell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) const uuid_t *uuid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct afs_addr_list *alist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct afs_server *server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct afs_net *net = cell->net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) _enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) server = kzalloc(sizeof(struct afs_server), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (!server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) goto enomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) atomic_set(&server->ref, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) atomic_set(&server->active, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) server->debug_id = atomic_inc_return(&afs_server_debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) RCU_INIT_POINTER(server->addresses, alist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) server->addr_version = alist->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) server->uuid = *uuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) rwlock_init(&server->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) init_waitqueue_head(&server->probe_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) INIT_LIST_HEAD(&server->probe_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) spin_lock_init(&server->probe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) server->cell = cell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) server->rtt = UINT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) afs_inc_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) trace_afs_server(server, 1, 1, afs_server_trace_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) _leave(" = %p", server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) enomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) _leave(" = NULL [nomem]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * Look up an address record for a server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static struct afs_addr_list *afs_vl_lookup_addrs(struct afs_cell *cell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct key *key, const uuid_t *uuid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct afs_vl_cursor vc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct afs_addr_list *alist = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ret = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (afs_begin_vlserver_operation(&vc, cell, key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) while (afs_select_vlserver(&vc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (test_bit(AFS_VLSERVER_FL_IS_YFS, &vc.server->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) alist = afs_yfsvl_get_endpoints(&vc, uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) alist = afs_vl_get_addrs_u(&vc, uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ret = afs_end_vlserver_operation(&vc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return ret < 0 ? ERR_PTR(ret) : alist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * Get or create a fileserver record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct afs_server *afs_lookup_server(struct afs_cell *cell, struct key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) const uuid_t *uuid, u32 addr_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct afs_addr_list *alist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct afs_server *server, *candidate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) _enter("%p,%pU", cell->net, uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) server = afs_find_server_by_uuid(cell->net, uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (server) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (server->addr_version != addr_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) set_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) alist = afs_vl_lookup_addrs(cell, key, uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (IS_ERR(alist))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return ERR_CAST(alist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) candidate = afs_alloc_server(cell, uuid, alist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (!candidate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) afs_put_addrlist(alist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) server = afs_install_server(cell, candidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (server != candidate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) afs_put_addrlist(alist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) kfree(candidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* Immediately dispatch an asynchronous probe to each interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * on the fileserver. This will make sure the repeat-probing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * service is started.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) afs_fs_probe_fileserver(cell->net, server, key, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * Set the server timer to fire after a given delay, assuming it's not already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * set for an earlier time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static void afs_set_server_timer(struct afs_net *net, time64_t delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (net->live) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) afs_inc_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (timer_reduce(&net->fs_timer, jiffies + delay * HZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) afs_dec_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * Server management timer. We have an increment on fs_outstanding that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * need to pass along to the work item.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) void afs_servers_timer(struct timer_list *timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct afs_net *net = container_of(timer, struct afs_net, fs_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) _enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (!queue_work(afs_wq, &net->fs_manager))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) afs_dec_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * Get a reference on a server object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct afs_server *afs_get_server(struct afs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) enum afs_server_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) unsigned int u = atomic_inc_return(&server->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) trace_afs_server(server, u, atomic_read(&server->active), reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * Try to get a reference on a server object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static struct afs_server *afs_maybe_use_server(struct afs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) enum afs_server_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) unsigned int r = atomic_fetch_add_unless(&server->ref, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) unsigned int a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (r == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) a = atomic_inc_return(&server->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) trace_afs_server(server, r, a, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * Get an active count on a server object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct afs_server *afs_use_server(struct afs_server *server, enum afs_server_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) unsigned int r = atomic_inc_return(&server->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) unsigned int a = atomic_inc_return(&server->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) trace_afs_server(server, r, a, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * Release a reference on a server record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) void afs_put_server(struct afs_net *net, struct afs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) enum afs_server_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) unsigned int usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (!server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) usage = atomic_dec_return(&server->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) trace_afs_server(server, usage, atomic_read(&server->active), reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (unlikely(usage == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) __afs_put_server(net, server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * Drop an active count on a server object without updating the last-unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) void afs_unuse_server_notime(struct afs_net *net, struct afs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) enum afs_server_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (server) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) unsigned int active = atomic_dec_return(&server->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (active == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) afs_set_server_timer(net, afs_server_gc_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) afs_put_server(net, server, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * Drop an active count on a server object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) void afs_unuse_server(struct afs_net *net, struct afs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) enum afs_server_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (server) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) server->unuse_time = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) afs_unuse_server_notime(net, server, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static void afs_server_rcu(struct rcu_head *rcu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct afs_server *server = container_of(rcu, struct afs_server, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) trace_afs_server(server, atomic_read(&server->ref),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) atomic_read(&server->active), afs_server_trace_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) afs_put_addrlist(rcu_access_pointer(server->addresses));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) kfree(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static void __afs_put_server(struct afs_net *net, struct afs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) call_rcu(&server->rcu, afs_server_rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) afs_dec_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static void afs_give_up_callbacks(struct afs_net *net, struct afs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct afs_addr_list *alist = rcu_access_pointer(server->addresses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct afs_addr_cursor ac = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) .alist = alist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) .index = alist->preferred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) .error = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) afs_fs_give_up_all_callbacks(net, server, &ac, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * destroy a dead server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static void afs_destroy_server(struct afs_net *net, struct afs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (test_bit(AFS_SERVER_FL_MAY_HAVE_CB, &server->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) afs_give_up_callbacks(net, server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) afs_put_server(net, server, afs_server_trace_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * Garbage collect any expired servers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static void afs_gc_servers(struct afs_net *net, struct afs_server *gc_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct afs_server *server, *next, *prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) int active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) while ((server = gc_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) gc_list = server->gc_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) write_seqlock(&net->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) active = atomic_read(&server->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (active == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) trace_afs_server(server, atomic_read(&server->ref),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) active, afs_server_trace_gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) next = rcu_dereference_protected(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) server->uuid_next, lockdep_is_held(&net->fs_lock.lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) prev = server->uuid_prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (!prev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) /* The one at the front is in the tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (!next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) rb_erase(&server->uuid_rb, &net->fs_servers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) rb_replace_node_rcu(&server->uuid_rb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) &next->uuid_rb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) &net->fs_servers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) next->uuid_prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* This server is not at the front */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) rcu_assign_pointer(prev->uuid_next, next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) next->uuid_prev = prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) list_del(&server->probe_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) hlist_del_rcu(&server->proc_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (!hlist_unhashed(&server->addr4_link))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) hlist_del_rcu(&server->addr4_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (!hlist_unhashed(&server->addr6_link))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) hlist_del_rcu(&server->addr6_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) write_sequnlock(&net->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (active == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) afs_destroy_server(net, server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * Manage the records of servers known to be within a network namespace. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) * includes garbage collecting unused servers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * Note also that we were given an increment on net->servers_outstanding by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * whoever queued us that we need to deal with before returning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) void afs_manage_servers(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct afs_net *net = container_of(work, struct afs_net, fs_manager);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct afs_server *gc_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct rb_node *cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) time64_t now = ktime_get_real_seconds(), next_manage = TIME64_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) bool purging = !net->live;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) _enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* Trawl the server list looking for servers that have expired from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * lack of use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) read_seqlock_excl(&net->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) for (cursor = rb_first(&net->fs_servers); cursor; cursor = rb_next(cursor)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct afs_server *server =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) rb_entry(cursor, struct afs_server, uuid_rb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) int active = atomic_read(&server->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) _debug("manage %pU %u", &server->uuid, active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (purging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) trace_afs_server(server, atomic_read(&server->ref),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) active, afs_server_trace_purging);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (active != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) pr_notice("Can't purge s=%08x\n", server->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (active == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) time64_t expire_at = server->unuse_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (!test_bit(AFS_SERVER_FL_VL_FAIL, &server->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) !test_bit(AFS_SERVER_FL_NOT_FOUND, &server->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) expire_at += afs_server_gc_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (purging || expire_at <= now) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) server->gc_next = gc_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) gc_list = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) } else if (expire_at < next_manage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) next_manage = expire_at;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) read_sequnlock_excl(&net->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /* Update the timer on the way out. We have to pass an increment on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * servers_outstanding in the namespace that we are in to the timer or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * the work scheduler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (!purging && next_manage < TIME64_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) now = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (next_manage - now <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (queue_work(afs_wq, &net->fs_manager))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) afs_inc_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) afs_set_server_timer(net, next_manage - now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) afs_gc_servers(net, gc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) afs_dec_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) _leave(" [%d]", atomic_read(&net->servers_outstanding));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static void afs_queue_server_manager(struct afs_net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) afs_inc_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (!queue_work(afs_wq, &net->fs_manager))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) afs_dec_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * Purge list of servers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) void afs_purge_servers(struct afs_net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) _enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (del_timer_sync(&net->fs_timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) afs_dec_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) afs_queue_server_manager(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) _debug("wait");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) atomic_dec(&net->servers_outstanding);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) wait_var_event(&net->servers_outstanding,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) !atomic_read(&net->servers_outstanding));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) _leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) * Get an update for a server's address list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static noinline bool afs_update_server_record(struct afs_operation *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) struct afs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct afs_addr_list *alist, *discard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) _enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) trace_afs_server(server, atomic_read(&server->ref), atomic_read(&server->active),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) afs_server_trace_update);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) alist = afs_vl_lookup_addrs(op->volume->cell, op->key, &server->uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (IS_ERR(alist)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if ((PTR_ERR(alist) == -ERESTARTSYS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) PTR_ERR(alist) == -EINTR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) (op->flags & AFS_OPERATION_UNINTR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) server->addresses) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) _leave(" = t [intr]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) op->error = PTR_ERR(alist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) _leave(" = f [%d]", op->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) discard = alist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (server->addr_version != alist->version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) write_lock(&server->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) discard = rcu_dereference_protected(server->addresses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) lockdep_is_held(&server->fs_lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) rcu_assign_pointer(server->addresses, alist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) server->addr_version = alist->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) write_unlock(&server->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) afs_put_addrlist(discard);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) _leave(" = t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * See if a server's address list needs updating.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) bool afs_check_server_record(struct afs_operation *op, struct afs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) bool success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) int ret, retries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) _enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) ASSERT(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (test_bit(AFS_SERVER_FL_UPDATING, &server->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) goto wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (test_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) goto update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) _leave(" = t [good]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) update:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (!test_and_set_bit_lock(AFS_SERVER_FL_UPDATING, &server->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) clear_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) success = afs_update_server_record(op, server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) clear_bit_unlock(AFS_SERVER_FL_UPDATING, &server->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) wake_up_bit(&server->flags, AFS_SERVER_FL_UPDATING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) _leave(" = %d", success);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) wait:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) ret = wait_on_bit(&server->flags, AFS_SERVER_FL_UPDATING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) (op->flags & AFS_OPERATION_UNINTR) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (ret == -ERESTARTSYS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) op->error = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) _leave(" = f [intr]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) retries++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (retries == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) _leave(" = f [stale]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) ret = -ESTALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }