aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/ceph_fs.h11
-rw-r--r--fs/ceph/mds_client.c52
2 files changed, 50 insertions, 13 deletions
diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h
index 5bf4ec2cf9eb..bb17a18cc190 100644
--- a/fs/ceph/ceph_fs.h
+++ b/fs/ceph/ceph_fs.h
@@ -635,12 +635,21 @@ struct ceph_mds_cap_reconnect {
635 __le64 cap_id; 635 __le64 cap_id;
636 __le32 wanted; 636 __le32 wanted;
637 __le32 issued; 637 __le32 issued;
638 __le64 snaprealm;
639 __le64 pathbase; /* base ino for our path to this ino */
640 __le32 flock_len; /* size of flock state blob, if any */
641} __attribute__ ((packed));
642/* followed by flock blob */
643
644struct ceph_mds_cap_reconnect_v1 {
645 __le64 cap_id;
646 __le32 wanted;
647 __le32 issued;
638 __le64 size; 648 __le64 size;
639 struct ceph_timespec mtime, atime; 649 struct ceph_timespec mtime, atime;
640 __le64 snaprealm; 650 __le64 snaprealm;
641 __le64 pathbase; /* base ino for our path to this ino */ 651 __le64 pathbase; /* base ino for our path to this ino */
642} __attribute__ ((packed)); 652} __attribute__ ((packed));
643/* followed by encoded string */
644 653
645struct ceph_mds_snaprealm_reconnect { 654struct ceph_mds_snaprealm_reconnect {
646 __le64 ino; /* snap realm base */ 655 __le64 ino; /* snap realm base */
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 34d215ff4c82..615f720a819d 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -37,6 +37,11 @@
37 * are no longer valid. 37 * are no longer valid.
38 */ 38 */
39 39
40struct ceph_reconnect_state {
41 struct ceph_pagelist *pagelist;
42 bool flock;
43};
44
40static void __wake_requests(struct ceph_mds_client *mdsc, 45static void __wake_requests(struct ceph_mds_client *mdsc,
41 struct list_head *head); 46 struct list_head *head);
42 47
@@ -2268,9 +2273,14 @@ static void replay_unsafe_requests(struct ceph_mds_client *mdsc,
2268static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, 2273static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap,
2269 void *arg) 2274 void *arg)
2270{ 2275{
2271 struct ceph_mds_cap_reconnect rec; 2276 union {
2277 struct ceph_mds_cap_reconnect v2;
2278 struct ceph_mds_cap_reconnect_v1 v1;
2279 } rec;
2280 size_t reclen;
2272 struct ceph_inode_info *ci; 2281 struct ceph_inode_info *ci;
2273 struct ceph_pagelist *pagelist = arg; 2282 struct ceph_reconnect_state *recon_state = arg;
2283 struct ceph_pagelist *pagelist = recon_state->pagelist;
2274 char *path; 2284 char *path;
2275 int pathlen, err; 2285 int pathlen, err;
2276 u64 pathbase; 2286 u64 pathbase;
@@ -2303,17 +2313,29 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap,
2303 spin_lock(&inode->i_lock); 2313 spin_lock(&inode->i_lock);
2304 cap->seq = 0; /* reset cap seq */ 2314 cap->seq = 0; /* reset cap seq */
2305 cap->issue_seq = 0; /* and issue_seq */ 2315 cap->issue_seq = 0; /* and issue_seq */
2306 rec.cap_id = cpu_to_le64(cap->cap_id); 2316
2307 rec.pathbase = cpu_to_le64(pathbase); 2317 if (recon_state->flock) {
2308 rec.wanted = cpu_to_le32(__ceph_caps_wanted(ci)); 2318 rec.v2.cap_id = cpu_to_le64(cap->cap_id);
2309 rec.issued = cpu_to_le32(cap->issued); 2319 rec.v2.wanted = cpu_to_le32(__ceph_caps_wanted(ci));
2310 rec.size = cpu_to_le64(inode->i_size); 2320 rec.v2.issued = cpu_to_le32(cap->issued);
2311 ceph_encode_timespec(&rec.mtime, &inode->i_mtime); 2321 rec.v2.snaprealm = cpu_to_le64(ci->i_snap_realm->ino);
2312 ceph_encode_timespec(&rec.atime, &inode->i_atime); 2322 rec.v2.pathbase = cpu_to_le64(pathbase);
2313 rec.snaprealm = cpu_to_le64(ci->i_snap_realm->ino); 2323 rec.v2.flock_len = 0;
2324 reclen = sizeof(rec.v2);
2325 } else {
2326 rec.v1.cap_id = cpu_to_le64(cap->cap_id);
2327 rec.v1.wanted = cpu_to_le32(__ceph_caps_wanted(ci));
2328 rec.v1.issued = cpu_to_le32(cap->issued);
2329 rec.v1.size = cpu_to_le64(inode->i_size);
2330 ceph_encode_timespec(&rec.v1.mtime, &inode->i_mtime);
2331 ceph_encode_timespec(&rec.v1.atime, &inode->i_atime);
2332 rec.v1.snaprealm = cpu_to_le64(ci->i_snap_realm->ino);
2333 rec.v1.pathbase = cpu_to_le64(pathbase);
2334 reclen = sizeof(rec.v1);
2335 }
2314 spin_unlock(&inode->i_lock); 2336 spin_unlock(&inode->i_lock);
2315 2337
2316 err = ceph_pagelist_append(pagelist, &rec, sizeof(rec)); 2338 err = ceph_pagelist_append(pagelist, &rec, reclen);
2317 2339
2318out: 2340out:
2319 kfree(path); 2341 kfree(path);
@@ -2342,6 +2364,7 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
2342 int mds = session->s_mds; 2364 int mds = session->s_mds;
2343 int err = -ENOMEM; 2365 int err = -ENOMEM;
2344 struct ceph_pagelist *pagelist; 2366 struct ceph_pagelist *pagelist;
2367 struct ceph_reconnect_state recon_state;
2345 2368
2346 pr_info("mds%d reconnect start\n", mds); 2369 pr_info("mds%d reconnect start\n", mds);
2347 2370
@@ -2376,7 +2399,10 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
2376 err = ceph_pagelist_encode_32(pagelist, session->s_nr_caps); 2399 err = ceph_pagelist_encode_32(pagelist, session->s_nr_caps);
2377 if (err) 2400 if (err)
2378 goto fail; 2401 goto fail;
2379 err = iterate_session_caps(session, encode_caps_cb, pagelist); 2402
2403 recon_state.pagelist = pagelist;
2404 recon_state.flock = session->s_con.peer_features & CEPH_FEATURE_FLOCK;
2405 err = iterate_session_caps(session, encode_caps_cb, &recon_state);
2380 if (err < 0) 2406 if (err < 0)
2381 goto fail; 2407 goto fail;
2382 2408
@@ -2401,6 +2427,8 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
2401 } 2427 }
2402 2428
2403 reply->pagelist = pagelist; 2429 reply->pagelist = pagelist;
2430 if (recon_state.flock)
2431 reply->hdr.version = cpu_to_le16(2);
2404 reply->hdr.data_len = cpu_to_le32(pagelist->length); 2432 reply->hdr.data_len = cpu_to_le32(pagelist->length);
2405 reply->nr_pages = calc_pages_for(0, pagelist->length); 2433 reply->nr_pages = calc_pages_for(0, pagelist->length);
2406 ceph_con_send(&session->s_con, reply); 2434 ceph_con_send(&session->s_con, reply);