]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/ceph/mds_client.c
ceph: use current_kernel_time() to get request time stamp
[karo-tx-linux.git] / fs / ceph / mds_client.c
index 1d3fa90d40b92a660bce5e5d5a73a0f0823fb2c7..0c05df44cc6c8888d56d32f53d54fba109f8508c 100644 (file)
@@ -189,6 +189,7 @@ static int parse_reply_info_dir(void **p, void *end,
                info->dir_end = !!(flags & CEPH_READDIR_FRAG_END);
                info->dir_complete = !!(flags & CEPH_READDIR_FRAG_COMPLETE);
                info->hash_order = !!(flags & CEPH_READDIR_HASH_ORDER);
+               info->offset_hash = !!(flags & CEPH_READDIR_OFFSET_HASH);
        }
        if (num == 0)
                goto done;
@@ -378,9 +379,9 @@ const char *ceph_session_state_name(int s)
 
 static struct ceph_mds_session *get_session(struct ceph_mds_session *s)
 {
-       if (atomic_inc_not_zero(&s->s_ref)) {
+       if (refcount_inc_not_zero(&s->s_ref)) {
                dout("mdsc get_session %p %d -> %d\n", s,
-                    atomic_read(&s->s_ref)-1, atomic_read(&s->s_ref));
+                    refcount_read(&s->s_ref)-1, refcount_read(&s->s_ref));
                return s;
        } else {
                dout("mdsc get_session %p 0 -- FAIL", s);
@@ -391,8 +392,8 @@ static struct ceph_mds_session *get_session(struct ceph_mds_session *s)
 void ceph_put_mds_session(struct ceph_mds_session *s)
 {
        dout("mdsc put_session %p %d -> %d\n", s,
-            atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1);
-       if (atomic_dec_and_test(&s->s_ref)) {
+            refcount_read(&s->s_ref), refcount_read(&s->s_ref)-1);
+       if (refcount_dec_and_test(&s->s_ref)) {
                if (s->s_auth.authorizer)
                        ceph_auth_destroy_authorizer(s->s_auth.authorizer);
                kfree(s);
@@ -411,7 +412,7 @@ struct ceph_mds_session *__ceph_lookup_mds_session(struct ceph_mds_client *mdsc,
                return NULL;
        session = mdsc->sessions[mds];
        dout("lookup_mds_session %p %d\n", session,
-            atomic_read(&session->s_ref));
+            refcount_read(&session->s_ref));
        get_session(session);
        return session;
 }
@@ -441,7 +442,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc,
 {
        struct ceph_mds_session *s;
 
-       if (mds >= mdsc->mdsmap->m_max_mds)
+       if (mds >= mdsc->mdsmap->m_num_mds)
                return ERR_PTR(-EINVAL);
 
        s = kzalloc(sizeof(*s), GFP_NOFS);
@@ -466,7 +467,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc,
        INIT_LIST_HEAD(&s->s_caps);
        s->s_nr_caps = 0;
        s->s_trim_caps = 0;
-       atomic_set(&s->s_ref, 1);
+       refcount_set(&s->s_ref, 1);
        INIT_LIST_HEAD(&s->s_waiting);
        INIT_LIST_HEAD(&s->s_unsafe);
        s->s_num_cap_releases = 0;
@@ -494,7 +495,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc,
        }
        mdsc->sessions[mds] = s;
        atomic_inc(&mdsc->num_sessions);
-       atomic_inc(&s->s_ref);  /* one ref to sessions[], one to caller */
+       refcount_inc(&s->s_ref);  /* one ref to sessions[], one to caller */
 
        ceph_con_open(&s->s_con, CEPH_ENTITY_TYPE_MDS, mds,
                      ceph_mdsmap_get_addr(mdsc->mdsmap, mds));
@@ -1004,7 +1005,7 @@ static void __open_export_target_sessions(struct ceph_mds_client *mdsc,
        struct ceph_mds_session *ts;
        int i, mds = session->s_mds;
 
-       if (mds >= mdsc->mdsmap->m_max_mds)
+       if (mds >= mdsc->mdsmap->m_num_mds)
                return;
 
        mi = &mdsc->mdsmap->m_info[mds];
@@ -1551,9 +1552,15 @@ void ceph_send_cap_releases(struct ceph_mds_client *mdsc,
        struct ceph_msg *msg = NULL;
        struct ceph_mds_cap_release *head;
        struct ceph_mds_cap_item *item;
+       struct ceph_osd_client *osdc = &mdsc->fsc->client->osdc;
        struct ceph_cap *cap;
        LIST_HEAD(tmp_list);
        int num_cap_releases;
+       __le32  barrier, *cap_barrier;
+
+       down_read(&osdc->lock);
+       barrier = cpu_to_le32(osdc->epoch_barrier);
+       up_read(&osdc->lock);
 
        spin_lock(&session->s_cap_lock);
 again:
@@ -1571,7 +1578,11 @@ again:
                        head = msg->front.iov_base;
                        head->num = cpu_to_le32(0);
                        msg->front.iov_len = sizeof(*head);
+
+                       msg->hdr.version = cpu_to_le16(2);
+                       msg->hdr.compat_version = cpu_to_le16(1);
                }
+
                cap = list_first_entry(&tmp_list, struct ceph_cap,
                                        session_caps);
                list_del(&cap->session_caps);
@@ -1589,6 +1600,11 @@ again:
                ceph_put_cap(mdsc, cap);
 
                if (le32_to_cpu(head->num) == CEPH_CAPS_PER_RELEASE) {
+                       // Append cap_barrier field
+                       cap_barrier = msg->front.iov_base + msg->front.iov_len;
+                       *cap_barrier = barrier;
+                       msg->front.iov_len += sizeof(*cap_barrier);
+
                        msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
                        dout("send_cap_releases mds%d %p\n", session->s_mds, msg);
                        ceph_con_send(&session->s_con, msg);
@@ -1604,6 +1620,11 @@ again:
        spin_unlock(&session->s_cap_lock);
 
        if (msg) {
+               // Append cap_barrier field
+               cap_barrier = msg->front.iov_base + msg->front.iov_len;
+               *cap_barrier = barrier;
+               msg->front.iov_len += sizeof(*cap_barrier);
+
                msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
                dout("send_cap_releases mds%d %p\n", session->s_mds, msg);
                ceph_con_send(&session->s_con, msg);
@@ -1666,7 +1687,6 @@ struct ceph_mds_request *
 ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
 {
        struct ceph_mds_request *req = kzalloc(sizeof(*req), GFP_NOFS);
-       struct timespec ts;
 
        if (!req)
                return ERR_PTR(-ENOMEM);
@@ -1685,8 +1705,7 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
        init_completion(&req->r_safe_completion);
        INIT_LIST_HEAD(&req->r_unsafe_item);
 
-       ktime_get_real_ts(&ts);
-       req->r_stamp = timespec_trunc(ts, mdsc->fsc->sb->s_time_gran);
+       req->r_stamp = timespec_trunc(current_kernel_time(), mdsc->fsc->sb->s_time_gran);
 
        req->r_op = op;
        req->r_direct_mode = mode;
@@ -1993,7 +2012,7 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
 
        if (req->r_pagelist) {
                struct ceph_pagelist *pagelist = req->r_pagelist;
-               atomic_inc(&pagelist->refcnt);
+               refcount_inc(&pagelist->refcnt);
                ceph_msg_data_add_pagelist(msg, pagelist);
                msg->hdr.data_len = cpu_to_le32(pagelist->length);
        } else {
@@ -2640,8 +2659,10 @@ static void handle_session(struct ceph_mds_session *session,
        seq = le64_to_cpu(h->seq);
 
        mutex_lock(&mdsc->mutex);
-       if (op == CEPH_SESSION_CLOSE)
+       if (op == CEPH_SESSION_CLOSE) {
+               get_session(session);
                __unregister_session(mdsc, session);
+       }
        /* FIXME: this ttl calculation is generous */
        session->s_ttl = jiffies + HZ*mdsc->mdsmap->m_session_autoclose;
        mutex_unlock(&mdsc->mutex);
@@ -2730,6 +2751,8 @@ static void handle_session(struct ceph_mds_session *session,
                        kick_requests(mdsc, mds);
                mutex_unlock(&mdsc->mutex);
        }
+       if (op == CEPH_SESSION_CLOSE)
+               ceph_put_mds_session(session);
        return;
 
 bad:
@@ -3109,7 +3132,7 @@ static void check_new_map(struct ceph_mds_client *mdsc,
        dout("check_new_map new %u old %u\n",
             newmap->m_epoch, oldmap->m_epoch);
 
-       for (i = 0; i < oldmap->m_max_mds && i < mdsc->max_sessions; i++) {
+       for (i = 0; i < oldmap->m_num_mds && i < mdsc->max_sessions; i++) {
                if (mdsc->sessions[i] == NULL)
                        continue;
                s = mdsc->sessions[i];
@@ -3123,15 +3146,33 @@ static void check_new_map(struct ceph_mds_client *mdsc,
                     ceph_mdsmap_is_laggy(newmap, i) ? " (laggy)" : "",
                     ceph_session_state_name(s->s_state));
 
-               if (i >= newmap->m_max_mds ||
+               if (i >= newmap->m_num_mds ||
                    memcmp(ceph_mdsmap_get_addr(oldmap, i),
                           ceph_mdsmap_get_addr(newmap, i),
                           sizeof(struct ceph_entity_addr))) {
                        if (s->s_state == CEPH_MDS_SESSION_OPENING) {
                                /* the session never opened, just close it
                                 * out now */
+                               get_session(s);
+                               __unregister_session(mdsc, s);
                                __wake_requests(mdsc, &s->s_waiting);
+                               ceph_put_mds_session(s);
+                       } else if (i >= newmap->m_num_mds) {
+                               /* force close session for stopped mds */
+                               get_session(s);
                                __unregister_session(mdsc, s);
+                               __wake_requests(mdsc, &s->s_waiting);
+                               kick_requests(mdsc, i);
+                               mutex_unlock(&mdsc->mutex);
+
+                               mutex_lock(&s->s_mutex);
+                               cleanup_session_requests(mdsc, s);
+                               remove_session_caps(s);
+                               mutex_unlock(&s->s_mutex);
+
+                               ceph_put_mds_session(s);
+
+                               mutex_lock(&mdsc->mutex);
                        } else {
                                /* just close it */
                                mutex_unlock(&mdsc->mutex);
@@ -3169,7 +3210,7 @@ static void check_new_map(struct ceph_mds_client *mdsc,
                }
        }
 
-       for (i = 0; i < newmap->m_max_mds && i < mdsc->max_sessions; i++) {
+       for (i = 0; i < newmap->m_num_mds && i < mdsc->max_sessions; i++) {
                s = mdsc->sessions[i];
                if (!s)
                        continue;
@@ -3883,7 +3924,7 @@ static struct ceph_connection *con_get(struct ceph_connection *con)
        struct ceph_mds_session *s = con->private;
 
        if (get_session(s)) {
-               dout("mdsc con_get %p ok (%d)\n", s, atomic_read(&s->s_ref));
+               dout("mdsc con_get %p ok (%d)\n", s, refcount_read(&s->s_ref));
                return con;
        }
        dout("mdsc con_get %p FAIL\n", s);
@@ -3894,7 +3935,7 @@ static void con_put(struct ceph_connection *con)
 {
        struct ceph_mds_session *s = con->private;
 
-       dout("mdsc con_put %p (%d)\n", s, atomic_read(&s->s_ref) - 1);
+       dout("mdsc con_put %p (%d)\n", s, refcount_read(&s->s_ref) - 1);
        ceph_put_mds_session(s);
 }