From c64a4a041fb323798e40ce51d668a7b603d8aab1 Mon Sep 17 00:00:00 2001 From: sageweil Date: Wed, 28 Nov 2007 20:00:26 +0000 Subject: [PATCH] mount fails gracefully git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@2138 29311d96-e01e-0410-9327-a35deaab8ce9 --- trunk/ceph/kernel/client.c | 9 ++++--- trunk/ceph/kernel/messenger.c | 48 +++++++++++++++++++++++++++-------- trunk/ceph/kernel/messenger.h | 3 ++- trunk/ceph/kernel/super.c | 8 +++--- 4 files changed, 50 insertions(+), 18 deletions(-) diff --git a/trunk/ceph/kernel/client.c b/trunk/ceph/kernel/client.c index c5d9eb9298eaf..2c11678458411 100644 --- a/trunk/ceph/kernel/client.c +++ b/trunk/ceph/kernel/client.c @@ -94,11 +94,11 @@ static int mount(struct ceph_client *client, struct ceph_mount_args *args) { struct ceph_msg *mount_msg; int err; - int attempts = 10; + int attempts = 3; int which; char r; - client->mounting = 6; /* FIXME don't wait for osd map, for now */ + client->mounting = 06; /* FIXME don't wait for osd map, for now */ /* send mount request */ mount_msg = ceph_msg_new(CEPH_MSG_CLIENT_MOUNT, 0, 0, 0); @@ -123,7 +123,7 @@ trymount: if (err == -EINTR) return err; if (client->mounting) { - dout(10, "ceph_get_client still waiting for mount, attempts=%d\n", attempts); + dout(10, "mount still waiting for mount, attempts=%d\n", attempts); if (--attempts) goto trymount; return -EIO; @@ -212,11 +212,14 @@ struct ceph_client *ceph_get_client(struct ceph_mount_args *args) void ceph_put_client(struct ceph_client *cl) { + dout(10, "ceph_put_client %p\n", cl); if (atomic_dec_and_test(&cl->nref)) { dout(1, "ceph_put_client last put on %p\n", cl); /* unmount */ /* ... */ + + ceph_messenger_destroy(cl->msgr); put_client_counter(); kfree(cl); } diff --git a/trunk/ceph/kernel/messenger.c b/trunk/ceph/kernel/messenger.c index 00d789e19f378..6ef6d4a4523ab 100644 --- a/trunk/ceph/kernel/messenger.c +++ b/trunk/ceph/kernel/messenger.c @@ -172,15 +172,16 @@ static void add_connection_accepting(struct ceph_messenger *msgr, struct ceph_co * remove connection from all list. * also, from con_open radix tree, if it should have been there */ -static void remove_connection(struct ceph_messenger *msgr, struct ceph_connection *con) +static void __remove_connection(struct ceph_messenger *msgr, struct ceph_connection *con) { - unsigned long key = hash_addr(&con->peer_addr); + unsigned long key; - spin_lock(&msgr->con_lock); + dout(20, "__remove_connection %p from %p\n", con, msgr); list_del(&con->list_all); if (test_bit(CONNECTING, &con->state) || test_bit(OPEN, &con->state)) { /* remove from con_open too */ + key = hash_addr(&con->peer_addr); if (list_empty(&con->list_bucket)) { /* last one */ dout(20, "remove_connection %p and removing bucket %lu\n", con, key); @@ -190,11 +191,16 @@ static void remove_connection(struct ceph_messenger *msgr, struct ceph_connectio list_del(&con->list_bucket); } } - spin_unlock(&msgr->con_lock); - put_connection(con); } +static void remove_connection(struct ceph_messenger *msgr, struct ceph_connection *con) +{ + spin_lock(&msgr->con_lock); + __remove_connection(msgr, con); + spin_unlock(&msgr->con_lock); +} + /* * replace another connection @@ -717,8 +723,11 @@ struct ceph_messenger *ceph_messenger_create() msgr = kzalloc(sizeof(*msgr), GFP_KERNEL); if (msgr == NULL) return ERR_PTR(-ENOMEM); - + INIT_WORK(&msgr->awork, try_accept); spin_lock_init(&msgr->con_lock); + INIT_LIST_HEAD(&msgr->con_all); + INIT_LIST_HEAD(&msgr->con_accepting); + INIT_RADIX_TREE(&msgr->con_open, GFP_KERNEL); /* create listening socket */ ret = ceph_tcp_listen(msgr); @@ -727,14 +736,33 @@ struct ceph_messenger *ceph_messenger_create() return ERR_PTR(ret); } - INIT_WORK(&msgr->awork, try_accept); /* setup work structure */ - dout(1, "ceph_messenger_create listening on %x:%d\n", + dout(1, "ceph_messenger_create %p listening on %x:%d\n", msgr, ntohl(msgr->inst.addr.ipaddr.sin_addr.s_addr), ntohs(msgr->inst.addr.ipaddr.sin_port)); return msgr; } +void ceph_messenger_destroy(struct ceph_messenger *msgr) +{ + struct ceph_connection *con; + + dout(1, "ceph_messenger_destroy %p\n", msgr); + + /* kill off connections */ + spin_lock(&msgr->con_lock); + while (!list_empty(&msgr->con_all)) { + con = list_entry(msgr->con_all.next, struct ceph_connection, list_all); + __remove_connection(msgr, con); + } + spin_unlock(&msgr->con_lock); + + /* stop listener */ + sock_release(msgr->listen_sock); + + kfree(msgr); +} + /* * queue up an outgoing message @@ -755,13 +783,13 @@ int ceph_msg_send(struct ceph_messenger *msgr, struct ceph_msg *msg) con = new_connection(msgr); if (IS_ERR(con)) return PTR_ERR(con); - dout(5, "ceph_msg_send opening new connection %p to peer %x:%d\n", con, + dout(5, "ceph_msg_send new connection %p to peer %x:%d\n", con, ntohl(msg->hdr.dst.addr.ipaddr.sin_addr.s_addr), ntohs(msg->hdr.dst.addr.ipaddr.sin_port)); con->peer_addr = msg->hdr.dst.addr; add_connection(msgr, con); } else { - dout(5, "ceph_msg_send had connection %p to peer %x:%d\n", con, + dout(10, "ceph_msg_send had connection %p to peer %x:%d\n", con, ntohl(msg->hdr.dst.addr.ipaddr.sin_addr.s_addr), ntohs(msg->hdr.dst.addr.ipaddr.sin_port)); } diff --git a/trunk/ceph/kernel/messenger.h b/trunk/ceph/kernel/messenger.h index b2048a47b4b50..71c35c015ce10 100644 --- a/trunk/ceph/kernel/messenger.h +++ b/trunk/ceph/kernel/messenger.h @@ -26,9 +26,9 @@ static __inline__ const char *ceph_name_type_str(int t) { struct ceph_messenger { void *parent; ceph_messenger_dispatch_t dispatch; + struct ceph_entity_inst inst; /* my name+address */ struct socket *listen_sock; /* listening socket */ struct work_struct awork; /* accept work */ - struct ceph_entity_inst inst; /* my name+address */ spinlock_t con_lock; struct list_head con_all; /* all connections */ struct list_head con_accepting; /* doing handshake, or */ @@ -104,6 +104,7 @@ struct ceph_connection { extern struct ceph_messenger *ceph_messenger_create(void); +extern void ceph_messenger_destroy(struct ceph_messenger *); extern struct ceph_msg *ceph_msg_new(int type, int front_len, int page_len, int page_off); static __inline__ void ceph_msg_get(struct ceph_msg *msg) { diff --git a/trunk/ceph/kernel/super.c b/trunk/ceph/kernel/super.c index e306cbd9d8ace..f68aa4ff2c057 100644 --- a/trunk/ceph/kernel/super.c +++ b/trunk/ceph/kernel/super.c @@ -202,7 +202,7 @@ static int parse_ip(const char *c, int len, struct ceph_entity_addr *addr) int i; int v; unsigned ip = 0; - char *p = c; + const char *p = c; dout(15, "parse_ip on '%s' len %d\n", c, len); for (i=0; *p && i<4; i++) { @@ -334,6 +334,7 @@ static int ceph_get_sb(struct file_system_type *fs_type, sbinfo->sb_client = ceph_get_client(&mount_args); if (PTR_ERR(sbinfo->sb_client)) { error = PTR_ERR(sbinfo->sb_client); + sbinfo->sb_client = 0; goto out_splat; } } @@ -351,10 +352,9 @@ static void ceph_kill_sb(struct super_block *s) { struct ceph_super_info *sbinfo = ceph_sbinfo(s); dout(5, "ceph_kill_sb\n"); - kill_anon_super(s); - - ceph_put_client(sbinfo->sb_client); + if (sbinfo->sb_client) + ceph_put_client(sbinfo->sb_client); kfree(sbinfo); } -- 2.39.5