Whamcloud - gitweb
Return an LDLM error code from osc_enqueue, just to be clear at the caller
[fs/lustre-release.git] / lustre / llite / recover.c
index d21954c..3692042 100644 (file)
 #include <linux/lustre_ha.h>
 #include <linux/lustre_dlm.h>
 #include <linux/lustre_idl.h>
+#include <linux/obd_lov.h> /* for IOC_LOV_SET_OSC_ACTIVE */
 
 static int ll_retry_recovery(struct ptlrpc_connection *conn)
 {
-    ENTRY;
-    RETURN(0);
+        ENTRY;
+        RETURN(0);
 }
 
 /* XXX looks a lot like super.c:invalidate_request_list, don't it? */
@@ -25,8 +26,8 @@ static void abort_inflight_for_import(struct obd_import *imp)
         struct list_head *tmp, *n;
 
         /* Make sure that no new requests get processed for this import.
-         * ptlrpc_queue_wait must (and does) hold c_lock while testing this flags and
-         * then putting requests on sending_head or delayed_head.
+         * ptlrpc_queue_wait must (and does) hold c_lock while testing this
+         * flags and then putting requests on sending_head or delayed_head.
          */
         spin_lock(&imp->imp_connection->c_lock);
         imp->imp_flags |= IMP_INVALID;
@@ -68,10 +69,12 @@ static void abort_inflight_for_import(struct obd_import *imp)
         }
 }
 
-static void reconnect_ost(struct obd_import *imp)
+static void prepare_osc(struct obd_import *imp)
 {
+        int rc;
         struct ldlm_namespace *ns = imp->imp_obd->obd_namespace;
-        
+        struct obd_device *notify_obd = imp->imp_obd->u.cli.cl_containing_lov;
+
         CDEBUG(D_HA, "invalidating all locks for OST imp %p (to %s):\n",
                imp, imp->imp_connection->c_remote_uuid);
         ldlm_namespace_dump(ns);
@@ -79,9 +82,66 @@ static void reconnect_ost(struct obd_import *imp)
 
         abort_inflight_for_import(imp);
 
+        if (notify_obd == NULL)
+                return;
+
+        /* How gross is _this_? */
+        if (!list_empty(&notify_obd->obd_exports)) {
+                struct lustre_handle fakeconn;
+                struct obd_ioctl_data ioc_data;
+                struct obd_export *exp =
+                        list_entry(&notify_obd->obd_exports.next,
+                                   struct obd_export, exp_obd_chain);
+                fakeconn.addr = (__u64)(unsigned long)exp;
+                fakeconn.cookie = exp->exp_cookie;
+                ioc_data.ioc_inlbuf1 = imp->imp_obd->obd_uuid;
+                ioc_data.ioc_offset = 0; /* inactive */
+                rc = obd_iocontrol(IOC_LOV_SET_OSC_ACTIVE, &fakeconn,
+                                   sizeof ioc_data, &ioc_data, NULL);
+                if (rc)
+                        CERROR("disabling %s on LOV %p/%s: %d\n",
+                               imp->imp_obd->obd_uuid, notify_obd,
+                               notify_obd->obd_uuid, rc);
+        } else {
+                CDEBUG(D_HA, "No exports for obd %p/%s, can't notify about "
+                       "%p\n", notify_obd, notify_obd->obd_uuid,
+                       imp->imp_obd->obd_uuid);
+        }
+}
+
+static void prepare_mdc(struct obd_import *imp)
+{
+        struct ldlm_namespace *ns = imp->imp_obd->obd_namespace;
+        ldlm_cli_cancel_unused(ns, NULL, 1 /* local only */);
+}
+
+static int ll_prepare_recovery(struct ptlrpc_connection *conn)
+{
+        struct list_head *tmp;
+
+        list_for_each(tmp, &conn->c_imports) {
+                struct obd_import *imp = list_entry(tmp, struct obd_import,
+                                                    imp_chain);
+
+                if (imp->imp_obd->obd_type->typ_ops->o_brw)
+                        prepare_osc(imp);
+                else
+                        prepare_mdc(imp);
+        }
+
+        return ptlrpc_run_recovery_upcall(conn);
+}
+
+static void reconnect_osc(struct obd_import *imp)
+{
         (void)ptlrpc_reconnect_import(imp, OST_CONNECT);
 }
 
+static int reconnect_mdc(struct obd_import *imp)
+{
+        return ptlrpc_reconnect_import(imp, MDS_CONNECT);
+}
+
 static int ll_reconnect(struct ptlrpc_connection *conn)
 {
         struct list_head *tmp;
@@ -98,19 +158,18 @@ static int ll_reconnect(struct ptlrpc_connection *conn)
                                                     imp_chain);
                 if (imp->imp_obd->obd_type->typ_ops->o_brw) {
                         /* XXX what to do if we fail? */
-                        reconnect_ost(imp);
+                        reconnect_osc(imp);
                 } else {
-                        int rc = ptlrpc_reconnect_import(imp, MDS_CONNECT);
+                        int rc = reconnect_mdc(imp);
                         if (!rc) {
                                 need_replay = 1;
-                                /* XXX obd_cancel_unused */
                         }
                         /* make sure we don't try to replay for dead imps?
                          *
                          * else imp->imp_connection = NULL;
                          *
                          */
-                        
+
                 }
         }
 
@@ -119,10 +178,10 @@ static int ll_reconnect(struct ptlrpc_connection *conn)
                 conn->c_level = LUSTRE_CONN_FULL;
                 RETURN(0);
         }
-        
+
         conn->c_level = LUSTRE_CONN_RECOVD;
-        /* this will replay, up the c_level, recovd_conn_fixed and continue reqs.
-         * also, makes a mean cup of coffee.
+        /* this will replay, up the c_level, recovd_conn_fixed and continue
+         * reqs. also, makes a mean cup of coffee.
          */
         RETURN(ptlrpc_replay(conn));
 }
@@ -136,7 +195,7 @@ int ll_recover(struct recovd_data *rd, int phase)
 
         switch (phase) {
             case PTLRPC_RECOVD_PHASE_PREPARE:
-                RETURN(ptlrpc_run_recovery_upcall(conn));
+                RETURN(ll_prepare_recovery(conn));
             case PTLRPC_RECOVD_PHASE_RECOVER:
                 RETURN(ll_reconnect(conn));
             case PTLRPC_RECOVD_PHASE_FAILURE: