+/**
+ * update flags for import during reconnect process
+ */
+static int rev_import_flags_update(struct obd_import *revimp,
+ struct ptlrpc_request *req)
+{
+ int rc;
+ struct obd_connect_data *data;
+
+ data = req_capsule_client_get(&req->rq_pill, &RMF_CONNECT_DATA);
+
+ if (data->ocd_connect_flags & OBD_CONNECT_AT)
+ revimp->imp_msghdr_flags |= MSGHDR_AT_SUPPORT;
+ else
+ revimp->imp_msghdr_flags &= ~MSGHDR_AT_SUPPORT;
+
+ revimp->imp_msghdr_flags |= MSGHDR_CKSUM_INCOMPAT18;
+
+ rc = sptlrpc_import_sec_adapt(revimp, req->rq_svc_ctx, &req->rq_flvr);
+ if (rc) {
+ CERROR("%s: cannot get reverse import %s security: rc = %d\n",
+ revimp->imp_client->cli_name,
+ libcfs_id2str(req->rq_peer), rc);
+ return rc;
+ }
+
+ return 0;
+}
+
+/**
+ * Allocate a new reverse import for an export.
+ *
+ * \retval -errno in case error hit
+ * \retval 0 if reverse import correctly init
+ **/
+int rev_import_init(struct obd_export *export)
+{
+ struct obd_device *obd = export->exp_obd;
+ struct obd_import *revimp;
+
+ LASSERT(export->exp_imp_reverse == NULL);
+
+ revimp = class_new_import(obd);
+ if (revimp == NULL)
+ return -ENOMEM;
+
+ revimp->imp_remote_handle.cookie = 0ULL;
+ revimp->imp_client = &obd->obd_ldlm_client;
+ revimp->imp_dlm_fake = 1;
+
+ /* it is safe to connect import in new state as no sends possible */
+ spin_lock(&export->exp_lock);
+ export->exp_imp_reverse = revimp;
+ spin_unlock(&export->exp_lock);
+ class_import_put(revimp);
+
+ return 0;
+}
+EXPORT_SYMBOL(rev_import_init);
+
+/**
+ * Handle reconnect for an export.
+ *
+ * \param exp export to handle reconnect process
+ * \param req client reconnect request
+ *
+ * \retval -rc in case securitfy flavor can't be changed
+ * \retval 0 in case none problems
+ */
+static int rev_import_reconnect(struct obd_export *exp,
+ struct ptlrpc_request *req)
+{
+ struct obd_import *revimp = exp->exp_imp_reverse;
+ struct lustre_handle *lh;
+ int rc;
+
+ /* avoid sending a request until import flags are changed */
+ ptlrpc_import_enter_resend(revimp);
+
+ if (revimp->imp_connection != NULL)
+ ptlrpc_connection_put(revimp->imp_connection);
+
+ /*
+ * client from recovery don't have a handle so we need to take from
+ * request. it may produce situation when wrong client connected
+ * to recovery as we trust a client uuid
+ */
+ lh = req_capsule_client_get(&req->rq_pill, &RMF_CONN);
+ revimp->imp_remote_handle = *lh;
+
+ /* unknown versions will be caught in
+ * ptlrpc_handle_server_req_in->lustre_unpack_msg() */
+ revimp->imp_msg_magic = req->rq_reqmsg->lm_magic;
+
+ revimp->imp_connection = ptlrpc_connection_addref(exp->exp_connection);
+
+ rc = rev_import_flags_update(revimp, req);
+ if (rc != 0) {
+ /* it is safe to still be in RECOVERY phase as we are not able
+ * to setup correct security flavor so requests are not able to
+ * be delivered correctly */
+ return rc;
+ }
+
+ /* resend all rpc's via new connection */
+ return ptlrpc_import_recovery_state_machine(revimp);
+}
+