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
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;
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));
/* 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;
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;
}
EXPORT_SYMBOL(class_fail_export);
#ifdef HAVE_SERVER_SUPPORT
+
+static int take_first(struct obd_export *exp, void *data)
+{
+ 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;
- struct rhashtable_iter iter;
int exports_evicted = 0;
spin_lock(&obd->obd_dev_lock);
}
spin_unlock(&obd->obd_dev_lock);
- rhltable_walk_enter(&obd->obd_nid_hash, &iter);
- rhashtable_walk_start(&iter);
- while ((doomed_exp = rhashtable_walk_next(&iter)) != NULL) {
- if (IS_ERR(doomed_exp))
- continue;
-
- if (!doomed_exp->exp_connection ||
- doomed_exp->exp_connection->c_peer.nid != nid_key)
- continue;
-
- if (!refcount_inc_not_zero(&doomed_exp->exp_handle.h_ref))
- continue;
-
- rhashtable_walk_stop(&iter);
+ doomed_exp = NULL;
+ while (obd_nid_export_for_each(obd, nid_key,
+ take_first, &doomed_exp) > 0) {
LASSERTF(doomed_exp != obd->obd_self_export,
"self-export is hashed by NID?\n");
class_fail_export(doomed_exp);
class_export_put(doomed_exp);
exports_evicted++;
-
- rhashtable_walk_start(&iter);
+ doomed_exp = NULL;
}
- rhashtable_walk_stop(&iter);
- rhashtable_walk_exit(&iter);
- 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);