]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/ceph/mds_client.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux.git] / fs / ceph / mds_client.c
index c8a9b89b922d71d3ca137119dcddfbf0842e0169..920e9f048bd8f4b38e26da4cb53ce5d9fb6bcda4 100644 (file)
@@ -150,14 +150,13 @@ static int parse_reply_info_in(void **p, void *end,
                        info->pool_ns_data = *p;
                        *p += info->pool_ns_len;
                }
-               /* btime, change_attr */
-               {
-                       struct ceph_timespec btime;
-                       u64 change_attr;
-                       ceph_decode_need(p, end, sizeof(btime), bad);
-                       ceph_decode_copy(p, &btime, sizeof(btime));
-                       ceph_decode_64_safe(p, end, change_attr, bad);
-               }
+
+               /* btime */
+               ceph_decode_need(p, end, sizeof(info->btime), bad);
+               ceph_decode_copy(p, &info->btime, sizeof(info->btime));
+
+               /* change attribute */
+               ceph_decode_64_safe(p, end, info->change_attr, bad);
 
                /* dir pin */
                if (struct_v >= 2) {
@@ -166,6 +165,15 @@ static int parse_reply_info_in(void **p, void *end,
                        info->dir_pin = -ENODATA;
                }
 
+               /* snapshot birth time, remains zero for v<=2 */
+               if (struct_v >= 3) {
+                       ceph_decode_need(p, end, sizeof(info->snap_btime), bad);
+                       ceph_decode_copy(p, &info->snap_btime,
+                                        sizeof(info->snap_btime));
+               } else {
+                       memset(&info->snap_btime, 0, sizeof(info->snap_btime));
+               }
+
                *p = end;
        } else {
                if (features & CEPH_FEATURE_MDS_INLINE_DATA) {
@@ -197,7 +205,14 @@ static int parse_reply_info_in(void **p, void *end,
                        }
                }
 
+               if (features & CEPH_FEATURE_FS_BTIME) {
+                       ceph_decode_need(p, end, sizeof(info->btime), bad);
+                       ceph_decode_copy(p, &info->btime, sizeof(info->btime));
+                       ceph_decode_64_safe(p, end, info->change_attr, bad);
+               }
+
                info->dir_pin = -ENODATA;
+               /* info->snap_btime remains zero */
        }
        return 0;
 bad:
@@ -717,6 +732,7 @@ void ceph_mdsc_release_request(struct kref *kref)
                ceph_pagelist_release(req->r_pagelist);
        put_request_session(req);
        ceph_unreserve_caps(req->r_mdsc, &req->r_caps_reservation);
+       WARN_ON_ONCE(!list_empty(&req->r_wait));
        kfree(req);
 }
 
@@ -903,7 +919,7 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
                struct inode *dir;
 
                rcu_read_lock();
-               parent = req->r_dentry->d_parent;
+               parent = READ_ONCE(req->r_dentry->d_parent);
                dir = req->r_parent ? : d_inode_rcu(parent);
 
                if (!dir || dir->i_sb != mdsc->fsc->sb) {
@@ -2135,7 +2151,7 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *pbase,
                        memcpy(path + pos, temp->d_name.name, temp->d_name.len);
                }
                spin_unlock(&temp->d_lock);
-               temp = temp->d_parent;
+               temp = READ_ONCE(temp->d_parent);
 
                /* Are we at the root? */
                if (IS_ROOT(temp))
@@ -3727,42 +3743,35 @@ 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_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);
+               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);
+                       mutex_unlock(&mdsc->mutex);
 
-                               mutex_lock(&s->s_mutex);
-                               cleanup_session_requests(mdsc, s);
-                               remove_session_caps(s);
-                               mutex_unlock(&s->s_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);
+                       ceph_put_mds_session(s);
 
-                               mutex_lock(&mdsc->mutex);
-                       } else {
-                               /* just close it */
-                               mutex_unlock(&mdsc->mutex);
-                               mutex_lock(&s->s_mutex);
-                               mutex_lock(&mdsc->mutex);
-                               ceph_con_close(&s->s_con);
-                               mutex_unlock(&s->s_mutex);
-                               s->s_state = CEPH_MDS_SESSION_RESTARTING;
-                       }
+                       mutex_lock(&mdsc->mutex);
+                       kick_requests(mdsc, i);
+                       continue;
+               }
+
+               if (memcmp(ceph_mdsmap_get_addr(oldmap, i),
+                          ceph_mdsmap_get_addr(newmap, i),
+                          sizeof(struct ceph_entity_addr))) {
+                       /* just close it */
+                       mutex_unlock(&mdsc->mutex);
+                       mutex_lock(&s->s_mutex);
+                       mutex_lock(&mdsc->mutex);
+                       ceph_con_close(&s->s_con);
+                       mutex_unlock(&s->s_mutex);
+                       s->s_state = CEPH_MDS_SESSION_RESTARTING;
                } else if (oldstate == newstate) {
                        continue;  /* nothing new with this mds */
                }
@@ -3931,31 +3940,33 @@ static void handle_lease(struct ceph_mds_client *mdsc,
 }
 
 void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session,
-                             struct inode *inode,
                              struct dentry *dentry, char action,
                              u32 seq)
 {
        struct ceph_msg *msg;
        struct ceph_mds_lease *lease;
-       int len = sizeof(*lease) + sizeof(u32);
-       int dnamelen = 0;
+       struct inode *dir;
+       int len = sizeof(*lease) + sizeof(u32) + NAME_MAX;
 
-       dout("lease_send_msg inode %p dentry %p %s to mds%d\n",
-            inode, dentry, ceph_lease_op_name(action), session->s_mds);
-       dnamelen = dentry->d_name.len;
-       len += dnamelen;
+       dout("lease_send_msg identry %p %s to mds%d\n",
+            dentry, ceph_lease_op_name(action), session->s_mds);
 
        msg = ceph_msg_new(CEPH_MSG_CLIENT_LEASE, len, GFP_NOFS, false);
        if (!msg)
                return;
        lease = msg->front.iov_base;
        lease->action = action;
-       lease->ino = cpu_to_le64(ceph_vino(inode).ino);
-       lease->first = lease->last = cpu_to_le64(ceph_vino(inode).snap);
        lease->seq = cpu_to_le32(seq);
-       put_unaligned_le32(dnamelen, lease + 1);
-       memcpy((void *)(lease + 1) + 4, dentry->d_name.name, dnamelen);
 
+       spin_lock(&dentry->d_lock);
+       dir = d_inode(dentry->d_parent);
+       lease->ino = cpu_to_le64(ceph_ino(dir));
+       lease->first = lease->last = cpu_to_le64(ceph_snap(dir));
+
+       put_unaligned_le32(dentry->d_name.len, lease + 1);
+       memcpy((void *)(lease + 1) + 4,
+              dentry->d_name.name, dentry->d_name.len);
+       spin_unlock(&dentry->d_lock);
        /*
         * if this is a preemptive lease RELEASE, no need to
         * flush request stream, since the actual request will
@@ -4157,6 +4168,7 @@ static void wait_requests(struct ceph_mds_client *mdsc)
                while ((req = __get_oldest_req(mdsc))) {
                        dout("wait_requests timed out on tid %llu\n",
                             req->r_tid);
+                       list_del_init(&req->r_wait);
                        __unregister_request(mdsc, req);
                }
        }