-struct ptlrpc_connection *
-ptlrpc_connection_get(lnet_process_id_t peer, lnet_nid_t self,
- struct obd_uuid *uuid)
-{
- struct ptlrpc_connection *conn, *conn2;
- ENTRY;
-
- conn = cfs_hash_lookup(conn_hash, &peer);
- if (conn)
- GOTO(out, conn);
-
- OBD_ALLOC_PTR(conn);
- if (!conn)
- RETURN(NULL);
-
- conn->c_peer = peer;
- conn->c_self = self;
- CFS_INIT_HLIST_NODE(&conn->c_hash);
- cfs_atomic_set(&conn->c_refcount, 1);
- if (uuid)
- obd_str2uuid(&conn->c_remote_uuid, uuid->uuid);
-
- /*
- * Add the newly created conn to the hash, on key collision we
- * lost a racing addition and must destroy our newly allocated
- * connection. The object which exists in the has will be
- * returned and may be compared against out object.
- */
- conn2 = cfs_hash_findadd_unique(conn_hash, &peer, &conn->c_hash);
- if (conn != conn2) {
- OBD_FREE_PTR(conn);
- conn = conn2;
- }
- EXIT;
-out:
- CDEBUG(D_INFO, "conn=%p refcount %d to %s\n",
- conn, cfs_atomic_read(&conn->c_refcount),
- libcfs_nid2str(conn->c_peer.nid));
- return conn;
-}
-
-int ptlrpc_connection_put(struct ptlrpc_connection *conn)
-{
- int rc = 0;
- ENTRY;
-
- if (!conn)
- RETURN(rc);
-
- LASSERT(!cfs_hlist_unhashed(&conn->c_hash));
-
- /*
- * We do not remove connection from hashtable and
- * do not free it even if last caller released ref,
- * as we want to have it cached for the case it is
- * needed again.
- *
- * Deallocating it and later creating new connection
- * again would be wastful. This way we also avoid
- * expensive locking to protect things from get/put
- * race when found cached connection is freed by
- * ptlrpc_connection_put().
- *
- * It will be freed later in module unload time,
- * when ptlrpc_connection_fini()->lh_exit->conn_exit()
- * path is called.
- */
- if (cfs_atomic_dec_return(&conn->c_refcount) == 1)
- rc = 1;
-
- CDEBUG(D_INFO, "PUT conn=%p refcount %d to %s\n",
- conn, cfs_atomic_read(&conn->c_refcount),
- libcfs_nid2str(conn->c_peer.nid));
-
- RETURN(rc);
-}