Whamcloud - gitweb
LU-14161 obdclass: fix some problems with obd_nid_hash
[fs/lustre-release.git] / lustre / obdclass / genops.c
index d4feb7c..f85dfd3 100644 (file)
@@ -62,9 +62,6 @@ static LIST_HEAD(obd_stale_exports);
 static DEFINE_SPINLOCK(obd_stale_export_lock);
 static atomic_t obd_stale_export_num = ATOMIC_INIT(0);
 
-int (*ptlrpc_put_connection_superhack)(struct ptlrpc_connection *c);
-EXPORT_SYMBOL(ptlrpc_put_connection_superhack);
-
 /*
  * support functions: we could use inter-module communication, but this
  * is more portable to other OS's
@@ -226,7 +223,7 @@ EXPORT_SYMBOL(class_add_symlinks);
 
 int class_register_type(const struct obd_ops *dt_ops,
                        const struct md_ops *md_ops,
-                       bool enable_proc, struct lprocfs_vars *vars,
+                       bool enable_proc, struct ldebugfs_vars *vars,
                        const char *name, struct lu_device_type *ldt)
 {
        struct obd_type *type;
@@ -947,8 +944,7 @@ static void class_export_destroy(struct obd_export *exp)
                exp->exp_client_uuid.uuid, obd->obd_name);
 
         /* "Local" exports (lctl, LOV->{mdc,osc}) have no connection. */
-        if (exp->exp_connection)
-                ptlrpc_put_connection_superhack(exp->exp_connection);
+       ptlrpc_connection_put(exp->exp_connection);
 
        LASSERT(list_empty(&exp->exp_outstanding_replies));
        LASSERT(list_empty(&exp->exp_uncommitted_replies));
@@ -1057,7 +1053,6 @@ struct obd_export *__class_new_export(struct obd_device *obd,
        export->exp_last_request_time = ktime_get_real_seconds();
        spin_lock_init(&export->exp_lock);
        spin_lock_init(&export->exp_rpc_lock);
-       INIT_HLIST_NODE(&export->exp_nid_hash);
        INIT_HLIST_NODE(&export->exp_gen_hash);
        spin_lock_init(&export->exp_bl_list_lock);
        INIT_LIST_HEAD(&export->exp_bl_list);
@@ -1162,14 +1157,14 @@ EXPORT_SYMBOL(class_unlink_export);
 /* Import management functions */
 static void obd_zombie_import_free(struct obd_import *imp)
 {
-        ENTRY;
+       ENTRY;
 
-        CDEBUG(D_IOCTL, "destroying import %p for %s\n", imp,
-                imp->imp_obd->obd_name);
+       CDEBUG(D_IOCTL, "destroying import %p for %s\n", imp,
+              imp->imp_obd->obd_name);
 
        LASSERT(refcount_read(&imp->imp_refcount) == 0);
 
-        ptlrpc_put_connection_superhack(imp->imp_connection);
+       ptlrpc_connection_put(imp->imp_connection);
 
        while (!list_empty(&imp->imp_conn_list)) {
                struct obd_import_conn *imp_conn;
@@ -1177,14 +1172,14 @@ static void obd_zombie_import_free(struct obd_import *imp)
                imp_conn = list_first_entry(&imp->imp_conn_list,
                                            struct obd_import_conn, oic_item);
                list_del_init(&imp_conn->oic_item);
-                ptlrpc_put_connection_superhack(imp_conn->oic_conn);
-                OBD_FREE(imp_conn, sizeof(*imp_conn));
-        }
+               ptlrpc_connection_put(imp_conn->oic_conn);
+               OBD_FREE(imp_conn, sizeof(*imp_conn));
+       }
 
-        LASSERT(imp->imp_sec == NULL);
+       LASSERT(imp->imp_sec == NULL);
        LASSERTF(atomic_read(&imp->imp_reqs) == 0, "%s: imp_reqs = %d\n",
                 imp->imp_obd->obd_name, atomic_read(&imp->imp_reqs));
-        class_decref(imp->imp_obd, "import", imp);
+       class_decref(imp->imp_obd, "import", imp);
        OBD_FREE_PTR(imp);
        EXIT;
 }
@@ -1273,6 +1268,7 @@ struct obd_import *class_new_import(struct obd_device *obd)
        atomic_set(&imp->imp_reqs, 0);
        atomic_set(&imp->imp_inflight, 0);
        atomic_set(&imp->imp_replay_inflight, 0);
+       init_waitqueue_head(&imp->imp_replay_waitq);
        atomic_set(&imp->imp_inval_count, 0);
        INIT_LIST_HEAD(&imp->imp_conn_list);
        init_imp_at(&imp->imp_at);
@@ -1427,22 +1423,21 @@ int class_disconnect(struct obd_export *export)
        spin_lock(&export->exp_lock);
        already_disconnected = export->exp_disconnected;
        export->exp_disconnected = 1;
+#ifdef HAVE_SERVER_SUPPORT
        /*  We hold references of export for uuid hash
         *  and nid_hash and export link at least. So
-        *  it is safe to call cfs_hash_del in there.  */
-       if (!hlist_unhashed(&export->exp_nid_hash))
-               cfs_hash_del(export->exp_obd->obd_nid_hash,
-                            &export->exp_connection->c_peer.nid,
-                            &export->exp_nid_hash);
+        *  it is safe to call rh*table_remove_fast in
+        *  there.
+        */
+       obd_nid_del(export->exp_obd, export);
+#endif /* HAVE_SERVER_SUPPORT */
        spin_unlock(&export->exp_lock);
 
         /* class_cleanup(), abort_recovery(), and class_fail_export()
          * all end up in here, and if any of them race we shouldn't
          * call extra class_export_puts(). */
-        if (already_disconnected) {
-               LASSERT(hlist_unhashed(&export->exp_nid_hash));
+       if (already_disconnected)
                 GOTO(no_disconn, already_disconnected);
-        }
 
        CDEBUG(D_IOCTL, "disconnect: cookie %#llx\n",
                export->exp_handle.h_cookie);
@@ -1626,13 +1621,30 @@ void class_fail_export(struct obd_export *exp)
 }
 EXPORT_SYMBOL(class_fail_export);
 
-int obd_export_evict_by_nid(struct obd_device *obd, const char *nid)
+#ifdef HAVE_SERVER_SUPPORT
+
+static int take_first(struct obd_export *exp, void *data)
 {
-       struct cfs_hash *nid_hash;
-       struct obd_export *doomed_exp = NULL;
-       int exports_evicted = 0;
+       struct obd_export **expp = data;
+
+       if (*expp)
+               /* already have one */
+               return 0;
+       if (exp->exp_failed)
+               /* Don't want this one */
+               return 0;
+       if (!refcount_inc_not_zero(&exp->exp_handle.h_ref))
+               /* Cannot get a ref on this one */
+               return 0;
+       *expp = exp;
+       return 1;
+}
 
+int obd_export_evict_by_nid(struct obd_device *obd, const char *nid)
+{
        lnet_nid_t nid_key = libcfs_str2nid((char *)nid);
+       struct obd_export *doomed_exp;
+       int exports_evicted = 0;
 
        spin_lock(&obd->obd_dev_lock);
        /* umount has run already, so evict thread should leave
@@ -1641,40 +1653,34 @@ int obd_export_evict_by_nid(struct obd_device *obd, const char *nid)
                spin_unlock(&obd->obd_dev_lock);
                return exports_evicted;
        }
-       nid_hash = obd->obd_nid_hash;
-       cfs_hash_getref(nid_hash);
        spin_unlock(&obd->obd_dev_lock);
 
-       do {
-               doomed_exp = cfs_hash_lookup(nid_hash, &nid_key);
-                if (doomed_exp == NULL)
-                        break;
+       doomed_exp = NULL;
+       while (obd_nid_export_for_each(obd, nid_key,
+                                      take_first, &doomed_exp) > 0) {
 
-                LASSERTF(doomed_exp->exp_connection->c_peer.nid == nid_key,
-                         "nid %s found, wanted nid %s, requested nid %s\n",
-                         obd_export_nid2str(doomed_exp),
-                         libcfs_nid2str(nid_key), nid);
-                LASSERTF(doomed_exp != obd->obd_self_export,
-                         "self-export is hashed by NID?\n");
-                exports_evicted++;
-               LCONSOLE_WARN("%s: evicting %s (at %s) by administrative "
-                             "request\n", obd->obd_name,
+               LASSERTF(doomed_exp != obd->obd_self_export,
+                        "self-export is hashed by NID?\n");
+
+               LCONSOLE_WARN("%s: evicting %s (at %s) by administrative request\n",
+                             obd->obd_name,
                              obd_uuid2str(&doomed_exp->exp_client_uuid),
                              obd_export_nid2str(doomed_exp));
-                class_fail_export(doomed_exp);
-                class_export_put(doomed_exp);
-        } while (1);
 
-       cfs_hash_putref(nid_hash);
+               class_fail_export(doomed_exp);
+               class_export_put(doomed_exp);
+               exports_evicted++;
+               doomed_exp = NULL;
+       }
 
-        if (!exports_evicted)
-                CDEBUG(D_HA,"%s: can't disconnect NID '%s': no exports found\n",
-                       obd->obd_name, nid);
-        return exports_evicted;
+       if (!exports_evicted)
+               CDEBUG(D_HA,
+                      "%s: can't disconnect NID '%s': no exports found\n",
+                      obd->obd_name, nid);
+       return exports_evicted;
 }
 EXPORT_SYMBOL(obd_export_evict_by_nid);
 
-#ifdef HAVE_SERVER_SUPPORT
 int obd_export_evict_by_uuid(struct obd_device *obd, const char *uuid)
 {
        struct obd_export *doomed_exp = NULL;