Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* Handle vlserver selection and rotation.
0003  *
0004  * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
0005  * Written by David Howells (dhowells@redhat.com)
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  * Begin an operation on a volume location server.
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  * Begin iteration through a server list, starting with the last used server if
0037  * possible, or the last recorded good server if not.
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         /* Status load is ordered after lookup counter load */
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  * Select the vlserver to use.  May be called multiple times to rotate
0082  * through the vlservers.
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     /* Evaluate the result of the previous operation, if there was one. */
0105     switch (error) {
0106     case SHRT_MAX:
0107         goto start;
0108 
0109     default:
0110     case 0:
0111         /* Success or local failure.  Stop. */
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         /* The far side rejected the operation on some grounds.  This
0119          * might involve the server being busy or the volume having been moved.
0120          */
0121         switch (vc->ac.abort_code) {
0122         case AFSVL_IO:
0123         case AFSVL_BADVOLOPER:
0124         case AFSVL_NOMEM:
0125             /* The server went weird. */
0126             vc->error = -EREMOTEIO;
0127             //write_lock(&vc->cell->vl_servers_lock);
0128             //vc->server_list->weird_mask |= 1 << vc->index;
0129             //write_unlock(&vc->cell->vl_servers_lock);
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     /* Pick the untried server with the lowest RTT. */
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     /* We're starting on a different vlserver from the list.  We need to
0212      * check it, find its address list and probe its capabilities before we
0213      * use it.
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     /* Iterate over the current server's address list to try and find an
0239      * address on which it will respond to us.
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     /* That's all the servers poked to no good effect.  Try again if some
0256      * of them were busy.
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  * Dump cursor state in the case of the error being EDESTADDRREQ.
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  * Tidy up a volume location server cursor and unlock the vnode.
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 }