0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/kernel.h>
0009 #include <linux/sched.h>
0010 #include <linux/sched/signal.h>
0011 #include "internal.h"
0012 #include "afs_vl.h"
0013
0014
0015
0016
0017 bool afs_begin_vlserver_operation(struct afs_vl_cursor *vc, struct afs_cell *cell,
0018 struct key *key)
0019 {
0020 memset(vc, 0, sizeof(*vc));
0021 vc->cell = cell;
0022 vc->key = key;
0023 vc->error = -EDESTADDRREQ;
0024 vc->ac.error = SHRT_MAX;
0025
0026 if (signal_pending(current)) {
0027 vc->error = -EINTR;
0028 vc->flags |= AFS_VL_CURSOR_STOP;
0029 return false;
0030 }
0031
0032 return true;
0033 }
0034
0035
0036
0037
0038
0039 static bool afs_start_vl_iteration(struct afs_vl_cursor *vc)
0040 {
0041 struct afs_cell *cell = vc->cell;
0042 unsigned int dns_lookup_count;
0043
0044 if (cell->dns_source == DNS_RECORD_UNAVAILABLE ||
0045 cell->dns_expiry <= ktime_get_real_seconds()) {
0046 dns_lookup_count = smp_load_acquire(&cell->dns_lookup_count);
0047 set_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags);
0048 afs_queue_cell(cell, afs_cell_trace_get_queue_dns);
0049
0050 if (cell->dns_source == DNS_RECORD_UNAVAILABLE) {
0051 if (wait_var_event_interruptible(
0052 &cell->dns_lookup_count,
0053 smp_load_acquire(&cell->dns_lookup_count)
0054 != dns_lookup_count) < 0) {
0055 vc->error = -ERESTARTSYS;
0056 return false;
0057 }
0058 }
0059
0060
0061 if (cell->dns_source == DNS_RECORD_UNAVAILABLE) {
0062 vc->error = -EDESTADDRREQ;
0063 return false;
0064 }
0065 }
0066
0067 read_lock(&cell->vl_servers_lock);
0068 vc->server_list = afs_get_vlserverlist(
0069 rcu_dereference_protected(cell->vl_servers,
0070 lockdep_is_held(&cell->vl_servers_lock)));
0071 read_unlock(&cell->vl_servers_lock);
0072 if (!vc->server_list->nr_servers)
0073 return false;
0074
0075 vc->untried = (1UL << vc->server_list->nr_servers) - 1;
0076 vc->index = -1;
0077 return true;
0078 }
0079
0080
0081
0082
0083
0084 bool afs_select_vlserver(struct afs_vl_cursor *vc)
0085 {
0086 struct afs_addr_list *alist;
0087 struct afs_vlserver *vlserver;
0088 struct afs_error e;
0089 u32 rtt;
0090 int error = vc->ac.error, i;
0091
0092 _enter("%lx[%d],%lx[%d],%d,%d",
0093 vc->untried, vc->index,
0094 vc->ac.tried, vc->ac.index,
0095 error, vc->ac.abort_code);
0096
0097 if (vc->flags & AFS_VL_CURSOR_STOP) {
0098 _leave(" = f [stopped]");
0099 return false;
0100 }
0101
0102 vc->nr_iterations++;
0103
0104
0105 switch (error) {
0106 case SHRT_MAX:
0107 goto start;
0108
0109 default:
0110 case 0:
0111
0112 vc->error = error;
0113 vc->flags |= AFS_VL_CURSOR_STOP;
0114 _leave(" = f [okay/local %d]", vc->ac.error);
0115 return false;
0116
0117 case -ECONNABORTED:
0118
0119
0120
0121 switch (vc->ac.abort_code) {
0122 case AFSVL_IO:
0123 case AFSVL_BADVOLOPER:
0124 case AFSVL_NOMEM:
0125
0126 vc->error = -EREMOTEIO;
0127
0128
0129
0130 goto next_server;
0131
0132 default:
0133 vc->error = afs_abort_to_error(vc->ac.abort_code);
0134 goto failed;
0135 }
0136
0137 case -ERFKILL:
0138 case -EADDRNOTAVAIL:
0139 case -ENETUNREACH:
0140 case -EHOSTUNREACH:
0141 case -EHOSTDOWN:
0142 case -ECONNREFUSED:
0143 case -ETIMEDOUT:
0144 case -ETIME:
0145 _debug("no conn %d", error);
0146 vc->error = error;
0147 goto iterate_address;
0148
0149 case -ECONNRESET:
0150 _debug("call reset");
0151 vc->error = error;
0152 vc->flags |= AFS_VL_CURSOR_RETRY;
0153 goto next_server;
0154
0155 case -EOPNOTSUPP:
0156 _debug("notsupp");
0157 goto next_server;
0158 }
0159
0160 restart_from_beginning:
0161 _debug("restart");
0162 afs_end_cursor(&vc->ac);
0163 afs_put_vlserverlist(vc->cell->net, vc->server_list);
0164 vc->server_list = NULL;
0165 if (vc->flags & AFS_VL_CURSOR_RETRIED)
0166 goto failed;
0167 vc->flags |= AFS_VL_CURSOR_RETRIED;
0168 start:
0169 _debug("start");
0170
0171 if (!afs_start_vl_iteration(vc))
0172 goto failed;
0173
0174 error = afs_send_vl_probes(vc->cell->net, vc->key, vc->server_list);
0175 if (error < 0)
0176 goto failed_set_error;
0177
0178 pick_server:
0179 _debug("pick [%lx]", vc->untried);
0180
0181 error = afs_wait_for_vl_probes(vc->server_list, vc->untried);
0182 if (error < 0)
0183 goto failed_set_error;
0184
0185
0186 vc->index = vc->server_list->preferred;
0187 if (test_bit(vc->index, &vc->untried))
0188 goto selected_server;
0189
0190 vc->index = -1;
0191 rtt = U32_MAX;
0192 for (i = 0; i < vc->server_list->nr_servers; i++) {
0193 struct afs_vlserver *s = vc->server_list->servers[i].server;
0194
0195 if (!test_bit(i, &vc->untried) ||
0196 !test_bit(AFS_VLSERVER_FL_RESPONDING, &s->flags))
0197 continue;
0198 if (s->probe.rtt < rtt) {
0199 vc->index = i;
0200 rtt = s->probe.rtt;
0201 }
0202 }
0203
0204 if (vc->index == -1)
0205 goto no_more_servers;
0206
0207 selected_server:
0208 _debug("use %d", vc->index);
0209 __clear_bit(vc->index, &vc->untried);
0210
0211
0212
0213
0214
0215 ASSERTCMP(vc->ac.alist, ==, NULL);
0216 vlserver = vc->server_list->servers[vc->index].server;
0217 vc->server = vlserver;
0218
0219 _debug("USING VLSERVER: %s", vlserver->name);
0220
0221 read_lock(&vlserver->lock);
0222 alist = rcu_dereference_protected(vlserver->addresses,
0223 lockdep_is_held(&vlserver->lock));
0224 afs_get_addrlist(alist);
0225 read_unlock(&vlserver->lock);
0226
0227 memset(&vc->ac, 0, sizeof(vc->ac));
0228
0229 if (!vc->ac.alist)
0230 vc->ac.alist = alist;
0231 else
0232 afs_put_addrlist(alist);
0233
0234 vc->ac.index = -1;
0235
0236 iterate_address:
0237 ASSERT(vc->ac.alist);
0238
0239
0240
0241 if (!afs_iterate_addresses(&vc->ac))
0242 goto next_server;
0243
0244 _debug("VL address %d/%d", vc->ac.index, vc->ac.alist->nr_addrs);
0245
0246 _leave(" = t %pISpc", &vc->ac.alist->addrs[vc->ac.index].transport);
0247 return true;
0248
0249 next_server:
0250 _debug("next");
0251 afs_end_cursor(&vc->ac);
0252 goto pick_server;
0253
0254 no_more_servers:
0255
0256
0257
0258 if (vc->flags & AFS_VL_CURSOR_RETRY)
0259 goto restart_from_beginning;
0260
0261 e.error = -EDESTADDRREQ;
0262 e.responded = false;
0263 for (i = 0; i < vc->server_list->nr_servers; i++) {
0264 struct afs_vlserver *s = vc->server_list->servers[i].server;
0265
0266 if (test_bit(AFS_VLSERVER_FL_RESPONDING, &s->flags))
0267 e.responded = true;
0268 afs_prioritise_error(&e, READ_ONCE(s->probe.error),
0269 s->probe.abort_code);
0270 }
0271
0272 error = e.error;
0273
0274 failed_set_error:
0275 vc->error = error;
0276 failed:
0277 vc->flags |= AFS_VL_CURSOR_STOP;
0278 afs_end_cursor(&vc->ac);
0279 _leave(" = f [failed %d]", vc->error);
0280 return false;
0281 }
0282
0283
0284
0285
0286 static void afs_vl_dump_edestaddrreq(const struct afs_vl_cursor *vc)
0287 {
0288 static int count;
0289 int i;
0290
0291 if (!IS_ENABLED(CONFIG_AFS_DEBUG_CURSOR) || count > 3)
0292 return;
0293 count++;
0294
0295 rcu_read_lock();
0296 pr_notice("EDESTADDR occurred\n");
0297 pr_notice("VC: ut=%lx ix=%u ni=%hu fl=%hx err=%hd\n",
0298 vc->untried, vc->index, vc->nr_iterations, vc->flags, vc->error);
0299
0300 if (vc->server_list) {
0301 const struct afs_vlserver_list *sl = vc->server_list;
0302 pr_notice("VC: SL nr=%u ix=%u\n",
0303 sl->nr_servers, sl->index);
0304 for (i = 0; i < sl->nr_servers; i++) {
0305 const struct afs_vlserver *s = sl->servers[i].server;
0306 pr_notice("VC: server %s+%hu fl=%lx E=%hd\n",
0307 s->name, s->port, s->flags, s->probe.error);
0308 if (s->addresses) {
0309 const struct afs_addr_list *a =
0310 rcu_dereference(s->addresses);
0311 pr_notice("VC: - nr=%u/%u/%u pf=%u\n",
0312 a->nr_ipv4, a->nr_addrs, a->max_addrs,
0313 a->preferred);
0314 pr_notice("VC: - R=%lx F=%lx\n",
0315 a->responded, a->failed);
0316 if (a == vc->ac.alist)
0317 pr_notice("VC: - current\n");
0318 }
0319 }
0320 }
0321
0322 pr_notice("AC: t=%lx ax=%u ac=%d er=%d r=%u ni=%u\n",
0323 vc->ac.tried, vc->ac.index, vc->ac.abort_code, vc->ac.error,
0324 vc->ac.responded, vc->ac.nr_iterations);
0325 rcu_read_unlock();
0326 }
0327
0328
0329
0330
0331 int afs_end_vlserver_operation(struct afs_vl_cursor *vc)
0332 {
0333 struct afs_net *net = vc->cell->net;
0334
0335 if (vc->error == -EDESTADDRREQ ||
0336 vc->error == -EADDRNOTAVAIL ||
0337 vc->error == -ENETUNREACH ||
0338 vc->error == -EHOSTUNREACH)
0339 afs_vl_dump_edestaddrreq(vc);
0340
0341 afs_end_cursor(&vc->ac);
0342 afs_put_vlserverlist(net, vc->server_list);
0343
0344 if (vc->error == -ECONNABORTED)
0345 vc->error = afs_abort_to_error(vc->ac.abort_code);
0346
0347 return vc->error;
0348 }