]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mount fails gracefully
authorsageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Wed, 28 Nov 2007 20:00:26 +0000 (20:00 +0000)
committersageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Wed, 28 Nov 2007 20:00:26 +0000 (20:00 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@2138 29311d96-e01e-0410-9327-a35deaab8ce9

trunk/ceph/kernel/client.c
trunk/ceph/kernel/messenger.c
trunk/ceph/kernel/messenger.h
trunk/ceph/kernel/super.c

index c5d9eb9298eaf079084473b1ba8e35bc7f12e326..2c1167845841171c6634e01b1db575647bc26419 100644 (file)
@@ -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);
        }
index 00d789e19f37837a59809cebbb95b9b6287b53ec..6ef6d4a4523abad198b8da0ab9b1800bbbe76500 100644 (file)
@@ -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));
        }                    
index b2048a47b4b50dd69aba502ab9be5ef5489bbed6..71c35c015ce10b6f2e2f3ece44f12fe53362f6ed 100644 (file)
@@ -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) {
index e306cbd9d8ace7b6cb0aa3779e01666b4df63f2d..f68aa4ff2c0578fdcc4ff9120ca3c075908418fd 100644 (file)
@@ -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);
 }