X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fptlrpc%2Fconnection.c;h=6b7690b3000ad92601c169a6b5374af28dd97252;hb=96ec6856f91f7f9031cfce4273c714d72cfe59ae;hp=7ed2e9b76b9aac65e9491713c801625ccd7675de;hpb=fbb9e5820f50f2ed3bb9bca7ce1c8fcc7137e80e;p=fs%2Flustre-release.git diff --git a/lustre/ptlrpc/connection.c b/lustre/ptlrpc/connection.c index 7ed2e9b..6b7690b 100644 --- a/lustre/ptlrpc/connection.c +++ b/lustre/ptlrpc/connection.c @@ -20,35 +20,69 @@ * */ -#define EXPORT_SYMTAB - #define DEBUG_SUBSYSTEM S_RPC - +#ifdef __KERNEL__ +#include +#include #include +#else +#include +#endif + +#include "ptlrpc_internal.h" static spinlock_t conn_lock; static struct list_head conn_list; static struct list_head conn_unused_list; -struct ptlrpc_connection *ptlrpc_get_connection(struct lustre_peer *peer) +void ptlrpc_dump_connections(void) +{ + struct list_head *tmp; + struct ptlrpc_connection *c; + ENTRY; + + list_for_each(tmp, &conn_list) { + c = list_entry(tmp, struct ptlrpc_connection, c_link); + CERROR("Connection %p/%s has refcount %d (nid="LPX64" on %s)\n", + c, c->c_remote_uuid.uuid, atomic_read(&c->c_refcount), + c->c_peer.peer_nid, c->c_peer.peer_ni->pni_name); + } + EXIT; +} + +struct ptlrpc_connection *ptlrpc_get_connection(struct ptlrpc_peer *peer, + struct obd_uuid *uuid) { struct list_head *tmp, *pos; struct ptlrpc_connection *c; ENTRY; + + CDEBUG(D_INFO, "peer is "LPX64" on %s\n", + peer->peer_nid, peer->peer_ni->pni_name); + spin_lock(&conn_lock); + if (list_empty(&conn_list)) { + if (!ptlrpc_get_ldlm_hooks()) { + spin_unlock(&conn_lock); + RETURN(NULL); + } + } + list_for_each(tmp, &conn_list) { c = list_entry(tmp, struct ptlrpc_connection, c_link); - if (memcmp(peer, &c->c_peer, sizeof(*peer)) == 0) { - atomic_inc(&c->c_refcount); + if (peer->peer_nid == c->c_peer.peer_nid && + peer->peer_ni == c->c_peer.peer_ni) { + ptlrpc_connection_addref(c); GOTO(out, c); } } list_for_each_safe(tmp, pos, &conn_unused_list) { c = list_entry(tmp, struct ptlrpc_connection, c_link); - if (memcmp(peer, &c->c_peer, sizeof(*peer)) == 0) { - atomic_inc(&c->c_refcount); + if (peer->peer_nid == c->c_peer.peer_nid && + peer->peer_ni == c->c_peer.peer_ni) { + ptlrpc_connection_addref(c); list_del(&c->c_link); list_add(&c->c_link, &conn_list); GOTO(out, c); @@ -61,15 +95,18 @@ struct ptlrpc_connection *ptlrpc_get_connection(struct lustre_peer *peer) if (c == NULL) GOTO(out, c); - c->c_xid_in = 1; - c->c_xid_out = 1; c->c_generation = 1; c->c_epoch = 1; c->c_bootcount = 0; - atomic_set(&c->c_refcount, 1); + c->c_flags = 0; + if (uuid && uuid->uuid) /* XXX ???? */ + obd_str2uuid(&c->c_remote_uuid, uuid->uuid); + atomic_set(&c->c_refcount, 0); + memcpy(&c->c_peer, peer, sizeof(c->c_peer)); spin_lock_init(&c->c_lock); - memcpy(&c->c_peer, peer, sizeof(c->c_peer)); + ptlrpc_connection_addref(c); + list_add(&c->c_link, &conn_list); EXIT; @@ -81,22 +118,42 @@ struct ptlrpc_connection *ptlrpc_get_connection(struct lustre_peer *peer) int ptlrpc_put_connection(struct ptlrpc_connection *c) { int rc = 0; + ENTRY; + + if (c == NULL) { + CERROR("NULL connection\n"); + RETURN(0); + } + + CDEBUG (D_INFO, "connection=%p refcount %d to "LPX64" on %s\n", + c, atomic_read(&c->c_refcount) - 1, c->c_peer.peer_nid, + c->c_peer.peer_ni->pni_name); if (atomic_dec_and_test(&c->c_refcount)) { spin_lock(&conn_lock); list_del(&c->c_link); list_add(&c->c_link, &conn_unused_list); + if (list_empty(&conn_list)) { + ptlrpc_put_ldlm_hooks(); + } spin_unlock(&conn_lock); rc = 1; } + if (atomic_read(&c->c_refcount) < 0) + CERROR("connection %p refcount %d!\n", + c, atomic_read(&c->c_refcount)); - return rc; + RETURN(rc); } struct ptlrpc_connection *ptlrpc_connection_addref(struct ptlrpc_connection *c) { + ENTRY; atomic_inc(&c->c_refcount); - return c; + CDEBUG (D_INFO, "connection=%p refcount %d to "LPX64" on %s\n", + c, atomic_read(&c->c_refcount), c->c_peer.peer_nid, + c->c_peer.peer_ni->pni_name); + RETURN(c); } void ptlrpc_init_connection(void) @@ -119,9 +176,9 @@ void ptlrpc_cleanup_connection(void) } list_for_each_safe(tmp, pos, &conn_list) { c = list_entry(tmp, struct ptlrpc_connection, c_link); - CERROR("Connection %p has refcount %d at cleanup (nid=%lu)!\n", - c, atomic_read(&c->c_refcount), - (unsigned long)c->c_peer.peer_nid); + CERROR("Connection %p/%s has refcount %d (nid="LPX64" on %s)\n", + c, c->c_remote_uuid.uuid, atomic_read(&c->c_refcount), + c->c_peer.peer_nid, c->c_peer.peer_ni->pni_name); list_del(&c->c_link); OBD_FREE(c, sizeof(*c)); }