diff options
author | Sage Weil <sage@newdream.net> | 2010-05-12 18:21:32 -0400 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-08-02 18:48:50 -0400 |
commit | 20cb34ae9e4b008a8789a48d52f5aa279dc400b6 (patch) | |
tree | 03b0c011ebaec2cb26c81f122b5432119976dc6b /fs/ceph | |
parent | ce1fbc8dd657a4bbcf26c683c9d07c88db83fd86 (diff) |
ceph: support v2 reconnect encoding
Encode either old or v2 encoding of client_reconnect message, depending on
whether the peer has the FLOCK feature bit.
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/ceph_fs.h | 11 | ||||
-rw-r--r-- | fs/ceph/mds_client.c | 52 |
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 | |||
644 | struct 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 | ||
645 | struct ceph_mds_snaprealm_reconnect { | 654 | struct 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 | ||
40 | struct ceph_reconnect_state { | ||
41 | struct ceph_pagelist *pagelist; | ||
42 | bool flock; | ||
43 | }; | ||
44 | |||
40 | static void __wake_requests(struct ceph_mds_client *mdsc, | 45 | static 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, | |||
2268 | static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, | 2273 | static 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 | ||
2318 | out: | 2340 | out: |
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); |