aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/mds_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/mds_client.c')
-rw-r--r--fs/ceph/mds_client.c66
1 files changed, 43 insertions, 23 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index a50fca1e03be..a1ee8fa3a8e7 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -60,7 +60,8 @@ static const struct ceph_connection_operations mds_con_ops;
60 * parse individual inode info 60 * parse individual inode info
61 */ 61 */
62static int parse_reply_info_in(void **p, void *end, 62static int parse_reply_info_in(void **p, void *end,
63 struct ceph_mds_reply_info_in *info) 63 struct ceph_mds_reply_info_in *info,
64 int features)
64{ 65{
65 int err = -EIO; 66 int err = -EIO;
66 67
@@ -74,6 +75,12 @@ static int parse_reply_info_in(void **p, void *end,
74 info->symlink = *p; 75 info->symlink = *p;
75 *p += info->symlink_len; 76 *p += info->symlink_len;
76 77
78 if (features & CEPH_FEATURE_DIRLAYOUTHASH)
79 ceph_decode_copy_safe(p, end, &info->dir_layout,
80 sizeof(info->dir_layout), bad);
81 else
82 memset(&info->dir_layout, 0, sizeof(info->dir_layout));
83
77 ceph_decode_32_safe(p, end, info->xattr_len, bad); 84 ceph_decode_32_safe(p, end, info->xattr_len, bad);
78 ceph_decode_need(p, end, info->xattr_len, bad); 85 ceph_decode_need(p, end, info->xattr_len, bad);
79 info->xattr_data = *p; 86 info->xattr_data = *p;
@@ -88,12 +95,13 @@ bad:
88 * target inode. 95 * target inode.
89 */ 96 */
90static int parse_reply_info_trace(void **p, void *end, 97static int parse_reply_info_trace(void **p, void *end,
91 struct ceph_mds_reply_info_parsed *info) 98 struct ceph_mds_reply_info_parsed *info,
99 int features)
92{ 100{
93 int err; 101 int err;
94 102
95 if (info->head->is_dentry) { 103 if (info->head->is_dentry) {
96 err = parse_reply_info_in(p, end, &info->diri); 104 err = parse_reply_info_in(p, end, &info->diri, features);
97 if (err < 0) 105 if (err < 0)
98 goto out_bad; 106 goto out_bad;
99 107
@@ -114,7 +122,7 @@ static int parse_reply_info_trace(void **p, void *end,
114 } 122 }
115 123
116 if (info->head->is_target) { 124 if (info->head->is_target) {
117 err = parse_reply_info_in(p, end, &info->targeti); 125 err = parse_reply_info_in(p, end, &info->targeti, features);
118 if (err < 0) 126 if (err < 0)
119 goto out_bad; 127 goto out_bad;
120 } 128 }
@@ -134,7 +142,8 @@ out_bad:
134 * parse readdir results 142 * parse readdir results
135 */ 143 */
136static int parse_reply_info_dir(void **p, void *end, 144static int parse_reply_info_dir(void **p, void *end,
137 struct ceph_mds_reply_info_parsed *info) 145 struct ceph_mds_reply_info_parsed *info,
146 int features)
138{ 147{
139 u32 num, i = 0; 148 u32 num, i = 0;
140 int err; 149 int err;
@@ -182,7 +191,7 @@ static int parse_reply_info_dir(void **p, void *end,
182 *p += sizeof(struct ceph_mds_reply_lease); 191 *p += sizeof(struct ceph_mds_reply_lease);
183 192
184 /* inode */ 193 /* inode */
185 err = parse_reply_info_in(p, end, &info->dir_in[i]); 194 err = parse_reply_info_in(p, end, &info->dir_in[i], features);
186 if (err < 0) 195 if (err < 0)
187 goto out_bad; 196 goto out_bad;
188 i++; 197 i++;
@@ -205,7 +214,8 @@ out_bad:
205 * parse fcntl F_GETLK results 214 * parse fcntl F_GETLK results
206 */ 215 */
207static int parse_reply_info_filelock(void **p, void *end, 216static int parse_reply_info_filelock(void **p, void *end,
208 struct ceph_mds_reply_info_parsed *info) 217 struct ceph_mds_reply_info_parsed *info,
218 int features)
209{ 219{
210 if (*p + sizeof(*info->filelock_reply) > end) 220 if (*p + sizeof(*info->filelock_reply) > end)
211 goto bad; 221 goto bad;
@@ -225,19 +235,21 @@ bad:
225 * parse extra results 235 * parse extra results
226 */ 236 */
227static int parse_reply_info_extra(void **p, void *end, 237static int parse_reply_info_extra(void **p, void *end,
228 struct ceph_mds_reply_info_parsed *info) 238 struct ceph_mds_reply_info_parsed *info,
239 int features)
229{ 240{
230 if (info->head->op == CEPH_MDS_OP_GETFILELOCK) 241 if (info->head->op == CEPH_MDS_OP_GETFILELOCK)
231 return parse_reply_info_filelock(p, end, info); 242 return parse_reply_info_filelock(p, end, info, features);
232 else 243 else
233 return parse_reply_info_dir(p, end, info); 244 return parse_reply_info_dir(p, end, info, features);
234} 245}
235 246
236/* 247/*
237 * parse entire mds reply 248 * parse entire mds reply
238 */ 249 */
239static int parse_reply_info(struct ceph_msg *msg, 250static int parse_reply_info(struct ceph_msg *msg,
240 struct ceph_mds_reply_info_parsed *info) 251 struct ceph_mds_reply_info_parsed *info,
252 int features)
241{ 253{
242 void *p, *end; 254 void *p, *end;
243 u32 len; 255 u32 len;
@@ -250,7 +262,7 @@ static int parse_reply_info(struct ceph_msg *msg,
250 /* trace */ 262 /* trace */
251 ceph_decode_32_safe(&p, end, len, bad); 263 ceph_decode_32_safe(&p, end, len, bad);
252 if (len > 0) { 264 if (len > 0) {
253 err = parse_reply_info_trace(&p, p+len, info); 265 err = parse_reply_info_trace(&p, p+len, info, features);
254 if (err < 0) 266 if (err < 0)
255 goto out_bad; 267 goto out_bad;
256 } 268 }
@@ -258,7 +270,7 @@ static int parse_reply_info(struct ceph_msg *msg,
258 /* extra */ 270 /* extra */
259 ceph_decode_32_safe(&p, end, len, bad); 271 ceph_decode_32_safe(&p, end, len, bad);
260 if (len > 0) { 272 if (len > 0) {
261 err = parse_reply_info_extra(&p, p+len, info); 273 err = parse_reply_info_extra(&p, p+len, info, features);
262 if (err < 0) 274 if (err < 0)
263 goto out_bad; 275 goto out_bad;
264 } 276 }
@@ -654,7 +666,7 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
654 } else { 666 } else {
655 /* dir + name */ 667 /* dir + name */
656 inode = dir; 668 inode = dir;
657 hash = req->r_dentry->d_name.hash; 669 hash = ceph_dentry_hash(req->r_dentry);
658 is_hash = true; 670 is_hash = true;
659 } 671 }
660 } 672 }
@@ -681,9 +693,11 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
681 dout("choose_mds %p %llx.%llx " 693 dout("choose_mds %p %llx.%llx "
682 "frag %u mds%d (%d/%d)\n", 694 "frag %u mds%d (%d/%d)\n",
683 inode, ceph_vinop(inode), 695 inode, ceph_vinop(inode),
684 frag.frag, frag.mds, 696 frag.frag, mds,
685 (int)r, frag.ndist); 697 (int)r, frag.ndist);
686 return mds; 698 if (ceph_mdsmap_get_state(mdsc->mdsmap, mds) >=
699 CEPH_MDS_STATE_ACTIVE)
700 return mds;
687 } 701 }
688 702
689 /* since this file/dir wasn't known to be 703 /* since this file/dir wasn't known to be
@@ -696,7 +710,9 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
696 dout("choose_mds %p %llx.%llx " 710 dout("choose_mds %p %llx.%llx "
697 "frag %u mds%d (auth)\n", 711 "frag %u mds%d (auth)\n",
698 inode, ceph_vinop(inode), frag.frag, mds); 712 inode, ceph_vinop(inode), frag.frag, mds);
699 return mds; 713 if (ceph_mdsmap_get_state(mdsc->mdsmap, mds) >=
714 CEPH_MDS_STATE_ACTIVE)
715 return mds;
700 } 716 }
701 } 717 }
702 } 718 }
@@ -1693,7 +1709,6 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc,
1693 struct ceph_msg *msg; 1709 struct ceph_msg *msg;
1694 int flags = 0; 1710 int flags = 0;
1695 1711
1696 req->r_mds = mds;
1697 req->r_attempts++; 1712 req->r_attempts++;
1698 if (req->r_inode) { 1713 if (req->r_inode) {
1699 struct ceph_cap *cap = 1714 struct ceph_cap *cap =
@@ -1780,6 +1795,8 @@ static int __do_request(struct ceph_mds_client *mdsc,
1780 goto finish; 1795 goto finish;
1781 } 1796 }
1782 1797
1798 put_request_session(req);
1799
1783 mds = __choose_mds(mdsc, req); 1800 mds = __choose_mds(mdsc, req);
1784 if (mds < 0 || 1801 if (mds < 0 ||
1785 ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) { 1802 ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) {
@@ -1797,6 +1814,8 @@ static int __do_request(struct ceph_mds_client *mdsc,
1797 goto finish; 1814 goto finish;
1798 } 1815 }
1799 } 1816 }
1817 req->r_session = get_session(session);
1818
1800 dout("do_request mds%d session %p state %s\n", mds, session, 1819 dout("do_request mds%d session %p state %s\n", mds, session,
1801 session_state_name(session->s_state)); 1820 session_state_name(session->s_state));
1802 if (session->s_state != CEPH_MDS_SESSION_OPEN && 1821 if (session->s_state != CEPH_MDS_SESSION_OPEN &&
@@ -1809,7 +1828,6 @@ static int __do_request(struct ceph_mds_client *mdsc,
1809 } 1828 }
1810 1829
1811 /* send request */ 1830 /* send request */
1812 req->r_session = get_session(session);
1813 req->r_resend_mds = -1; /* forget any previous mds hint */ 1831 req->r_resend_mds = -1; /* forget any previous mds hint */
1814 1832
1815 if (req->r_request_started == 0) /* note request start time */ 1833 if (req->r_request_started == 0) /* note request start time */
@@ -1863,7 +1881,6 @@ static void kick_requests(struct ceph_mds_client *mdsc, int mds)
1863 if (req->r_session && 1881 if (req->r_session &&
1864 req->r_session->s_mds == mds) { 1882 req->r_session->s_mds == mds) {
1865 dout(" kicking tid %llu\n", req->r_tid); 1883 dout(" kicking tid %llu\n", req->r_tid);
1866 put_request_session(req);
1867 __do_request(mdsc, req); 1884 __do_request(mdsc, req);
1868 } 1885 }
1869 } 1886 }
@@ -2056,8 +2073,11 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
2056 goto out; 2073 goto out;
2057 } else { 2074 } else {
2058 struct ceph_inode_info *ci = ceph_inode(req->r_inode); 2075 struct ceph_inode_info *ci = ceph_inode(req->r_inode);
2059 struct ceph_cap *cap = 2076 struct ceph_cap *cap = NULL;
2060 ceph_get_cap_for_mds(ci, req->r_mds);; 2077
2078 if (req->r_session)
2079 cap = ceph_get_cap_for_mds(ci,
2080 req->r_session->s_mds);
2061 2081
2062 dout("already using auth"); 2082 dout("already using auth");
2063 if ((!cap || cap != ci->i_auth_cap) || 2083 if ((!cap || cap != ci->i_auth_cap) ||
@@ -2101,7 +2121,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
2101 2121
2102 dout("handle_reply tid %lld result %d\n", tid, result); 2122 dout("handle_reply tid %lld result %d\n", tid, result);
2103 rinfo = &req->r_reply_info; 2123 rinfo = &req->r_reply_info;
2104 err = parse_reply_info(msg, rinfo); 2124 err = parse_reply_info(msg, rinfo, session->s_con.peer_features);
2105 mutex_unlock(&mdsc->mutex); 2125 mutex_unlock(&mdsc->mutex);
2106 2126
2107 mutex_lock(&session->s_mutex); 2127 mutex_lock(&session->s_mutex);