+#define ATTEMPT_TOO_SOON(last) \
+ ((last) && ((long)(jiffies - (last)) <= (long)(obd_timeout * 2 * HZ)))
+
+static int import_select_connection(struct obd_import *imp)
+{
+ struct obd_import_conn *imp_conn, *tmp;
+ struct obd_export *dlmexp;
+ int found = 0;
+ ENTRY;
+
+ spin_lock(&imp->imp_lock);
+
+ if (list_empty(&imp->imp_conn_list)) {
+ CERROR("no available connections on imp %p@%s\n",
+ imp, imp->imp_obd->obd_name);
+ spin_unlock(&imp->imp_lock);
+ RETURN(-EINVAL);
+ }
+
+ list_for_each_entry(imp_conn, &imp->imp_conn_list, oic_item) {
+ if (!ATTEMPT_TOO_SOON(imp_conn->oic_last_attempt)) {
+ found = 1;
+ break;
+ }
+ }
+
+ /* if not found, simply choose the current one */
+ if (!found) {
+ CWARN("obd %s imp 0x%p: all connections have been "
+ "tried recently\n", imp->imp_obd->obd_name, imp);
+ LASSERT(imp->imp_conn_current);
+ imp_conn = imp->imp_conn_current;
+ }
+ LASSERT(imp_conn->oic_conn);
+
+ imp_conn->oic_last_attempt = jiffies;
+
+ /* move the items ahead of the selected one to list tail */
+ while (1) {
+ tmp= list_entry(imp->imp_conn_list.next,
+ struct obd_import_conn, oic_item);
+ if (tmp == imp_conn)
+ break;
+ list_del(&tmp->oic_item);
+ list_add_tail(&tmp->oic_item, &imp->imp_conn_list);
+ }
+
+ /* switch connection, don't mind if it's same as the current one */
+ if (imp->imp_connection)
+ ptlrpc_put_connection(imp->imp_connection);
+ imp->imp_connection = ptlrpc_connection_addref(imp_conn->oic_conn);
+
+ dlmexp = class_conn2export(&imp->imp_dlm_handle);
+ LASSERT(dlmexp != NULL);
+ if (dlmexp->exp_connection)
+ ptlrpc_put_connection(imp->imp_connection);
+ dlmexp->exp_connection = ptlrpc_connection_addref(imp_conn->oic_conn);
+ class_export_put(dlmexp);
+
+ imp->imp_conn_current = imp_conn;
+ CWARN("obd %s imp 0x%p: select conn %s\n",
+ imp->imp_obd->obd_name, imp,
+ imp_conn->oic_uuid.uuid);
+ spin_unlock(&imp->imp_lock);
+
+ RETURN(0);
+}
+
+
+