From e750f48c03c047c61730440422f877028e6735d9 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 31 Dec 2015 14:05:03 -0500 Subject: [PATCH] messages/MClientCaps: avoid fixed struct for encoding At least for new clients. Signed-off-by: Sage Weil --- src/client/Client.cc | 28 ++++---- src/include/ceph_features.h | 1 + src/include/ceph_fs.h | 4 +- src/include/types.h | 3 +- src/mds/CInode.cc | 20 +++--- src/messages/MClientCaps.h | 123 ++++++++++++++++++++++++++++-------- 6 files changed, 125 insertions(+), 54 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 7733f627dee1c..03049d028df2c 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -3113,15 +3113,15 @@ void Client::send_cap(Inode *in, MetaSession *session, Cap *cap, m->head.xattr_version = in->xattr_version; } - m->head.layout = in->layout; - m->head.size = in->size; - m->head.max_size = in->max_size; - m->head.truncate_seq = in->truncate_seq; - m->head.truncate_size = in->truncate_size; - in->mtime.encode_timeval(&m->head.mtime); - in->atime.encode_timeval(&m->head.atime); - in->ctime.encode_timeval(&m->head.ctime); - m->head.time_warp_seq = in->time_warp_seq; + m->layout = in->layout; + m->size = in->size; + m->max_size = in->max_size; + m->truncate_seq = in->truncate_seq; + m->truncate_size = in->truncate_size; + m->mtime = in->mtime; + m->atime = in->atime; + m->ctime = in->ctime; + m->time_warp_seq = in->time_warp_seq; if (flush & CEPH_CAP_FILE_WR) { m->inline_version = in->inline_version; @@ -3395,15 +3395,15 @@ void Client::flush_snaps(Inode *in, bool all_again, CapSnap *again) m->head.gid = capsnap->gid; m->head.mode = capsnap->mode; - m->head.size = capsnap->size; + m->size = capsnap->size; m->head.xattr_version = capsnap->xattr_version; ::encode(capsnap->xattrs, m->xattrbl); - capsnap->ctime.encode_timeval(&m->head.ctime); - capsnap->mtime.encode_timeval(&m->head.mtime); - capsnap->atime.encode_timeval(&m->head.atime); - m->head.time_warp_seq = capsnap->time_warp_seq; + m->ctime = capsnap->ctime; + m->mtime = capsnap->mtime; + m->atime = capsnap->atime; + m->time_warp_seq = capsnap->time_warp_seq; if (capsnap->dirty & CEPH_CAP_FILE_WR) { m->inline_version = in->inline_version; diff --git a/src/include/ceph_features.h b/src/include/ceph_features.h index 1513e9d54e101..5d349284c5023 100755 --- a/src/include/ceph_features.h +++ b/src/include/ceph_features.h @@ -175,6 +175,7 @@ static inline unsigned long long ceph_sanitize_features(unsigned long long f) { CEPH_FEATURE_MON_ROUTE_OSDMAP | \ CEPH_FEATURE_CRUSH_TUNABLES5 | \ CEPH_FEATURE_SERVER_JEWEL | \ + CEPH_FEATURE_FS_FILE_LAYOUT_V2 | \ 0ULL) #define CEPH_FEATURES_SUPPORTED_DEFAULT CEPH_FEATURES_ALL diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index d04215b95e778..744c3ce8a5730 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -655,7 +655,7 @@ struct ceph_mds_cap_peer { /* * caps message, used for capability callbacks, acks, requests, etc. */ -struct ceph_mds_caps { +struct ceph_mds_caps_head { __le32 op; /* CEPH_CAP_OP_* */ __le64 ino, realm; __le64 cap_id; @@ -674,7 +674,9 @@ struct ceph_mds_caps { /* xattrlock */ __le32 xattr_len; __le64 xattr_version; +} __attribute__ ((packed)); +struct ceph_mds_caps_body_legacy { union { /* all except export */ struct { diff --git a/src/include/types.h b/src/include/types.h index 02129dbbb8ca2..d8a679f574357 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -247,7 +247,8 @@ WRITE_RAW_ENCODER(ceph_mds_session_head) WRITE_RAW_ENCODER(ceph_mds_request_head) WRITE_RAW_ENCODER(ceph_mds_request_release) WRITE_RAW_ENCODER(ceph_filelock) -WRITE_RAW_ENCODER(ceph_mds_caps) +WRITE_RAW_ENCODER(ceph_mds_caps_head) +WRITE_RAW_ENCODER(ceph_mds_caps_body_legacy) WRITE_RAW_ENCODER(ceph_mds_cap_peer) WRITE_RAW_ENCODER(ceph_mds_cap_release) WRITE_RAW_ENCODER(ceph_mds_cap_item) diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 4f0b987850cd9..554fd00f64e18 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -3339,20 +3339,20 @@ void CInode::encode_cap_message(MClientCaps *m, Capability *cap) inode_t *oi = &inode; inode_t *pi = get_projected_inode(); inode_t *i = (pfile|pauth|plink|pxattr) ? pi : oi; - i->ctime.encode_timeval(&m->head.ctime); - + dout(20) << "encode_cap_message pfile " << pfile << " pauth " << pauth << " plink " << plink << " pxattr " << pxattr << " ctime " << i->ctime << dendl; i = pfile ? pi:oi; - m->head.layout = i->layout; - m->head.size = i->size; - m->head.truncate_seq = i->truncate_seq; - m->head.truncate_size = i->truncate_size; - i->mtime.encode_timeval(&m->head.mtime); - i->atime.encode_timeval(&m->head.atime); - m->head.time_warp_seq = i->time_warp_seq; + m->layout = i->layout; + m->size = i->size; + m->truncate_seq = i->truncate_seq; + m->truncate_size = i->truncate_size; + m->mtime = i->mtime; + m->atime = i->atime; + m->ctime = i->ctime; + m->time_warp_seq = i->time_warp_seq; if (cap->client_inline_version < i->inline_data.version) { m->inline_version = cap->client_inline_version = i->inline_data.version; @@ -3365,7 +3365,7 @@ void CInode::encode_cap_message(MClientCaps *m, Capability *cap) // max_size is min of projected, actual. uint64_t oldms = oi->client_ranges.count(client) ? oi->client_ranges[client].range.last : 0; uint64_t newms = pi->client_ranges.count(client) ? pi->client_ranges[client].range.last : 0; - m->head.max_size = MIN(oldms, newms); + m->max_size = MIN(oldms, newms); i = pauth ? pi:oi; m->head.mode = i->mode; diff --git a/src/messages/MClientCaps.h b/src/messages/MClientCaps.h index 1b3f487f271d3..d9450dfff41dd 100644 --- a/src/messages/MClientCaps.h +++ b/src/messages/MClientCaps.h @@ -20,12 +20,20 @@ class MClientCaps : public Message { - static const int HEAD_VERSION = 7; + static const int HEAD_VERSION = 8; static const int COMPAT_VERSION = 1; public: - struct ceph_mds_caps head; + struct ceph_mds_caps_head head; + + uint64_t size, max_size, truncate_size; + uint32_t truncate_seq; + utime_t mtime, atime, ctime; + ceph_file_layout layout; + uint32_t time_warp_seq; + struct ceph_mds_cap_peer peer; + bufferlist snapbl; bufferlist xattrbl; bufferlist flockbl; @@ -49,16 +57,18 @@ class MClientCaps : public Message { inodeno_t get_realm() { return inodeno_t(head.realm); } uint64_t get_cap_id() { return head.cap_id; } - uint64_t get_size() { return head.size; } - uint64_t get_max_size() { return head.max_size; } - __u32 get_truncate_seq() { return head.truncate_seq; } - uint64_t get_truncate_size() { return head.truncate_size; } - utime_t get_ctime() { return utime_t(head.ctime); } - utime_t get_mtime() { return utime_t(head.mtime); } - utime_t get_atime() { return utime_t(head.atime); } - __u32 get_time_warp_seq() { return head.time_warp_seq; } - - ceph_file_layout& get_layout() { return head.layout; } + uint64_t get_size() { return size; } + uint64_t get_max_size() { return max_size; } + __u32 get_truncate_seq() { return truncate_seq; } + uint64_t get_truncate_size() { return truncate_size; } + utime_t get_ctime() { return ctime; } + utime_t get_mtime() { return mtime; } + utime_t get_atime() { return atime; } + __u32 get_time_warp_seq() { return time_warp_seq; } + + const ceph_file_layout& get_layout() { + return layout; + } int get_migrate_seq() { return head.migrate_seq; } int get_op() { return head.op; } @@ -72,14 +82,15 @@ class MClientCaps : public Message { void set_caps(int c) { head.caps = c; } void set_wanted(int w) { head.wanted = w; } - void set_max_size(uint64_t ms) { head.max_size = ms; } + void set_max_size(uint64_t ms) { max_size = ms; } void set_migrate_seq(unsigned m) { head.migrate_seq = m; } void set_op(int o) { head.op = o; } - void set_size(loff_t s) { head.size = s; } - void set_mtime(const utime_t &t) { t.encode_timeval(&head.mtime); } - void set_atime(const utime_t &t) { t.encode_timeval(&head.atime); } + void set_size(loff_t s) { size = s; } + void set_mtime(const utime_t &t) { mtime = t; } + void set_ctime(const utime_t &t) { ctime = t; } + void set_atime(const utime_t &t) { atime = t; } void set_cap_peer(uint64_t id, ceph_seq_t seq, ceph_seq_t mseq, int mds, int flags) { peer.cap_id = id; @@ -163,12 +174,12 @@ public: if (head.migrate_seq) out << " mseq " << head.migrate_seq; - out << " size " << head.size << "/" << head.max_size; - if (head.truncate_seq) - out << " ts " << head.truncate_seq; - out << " mtime " << utime_t(head.mtime); - if (head.time_warp_seq) - out << " tws " << head.time_warp_seq; + out << " size " << size << "/" << max_size; + if (truncate_seq) + out << " ts " << truncate_seq; + out << " mtime " << mtime; + if (time_warp_seq) + out << " tws " << time_warp_seq; if (head.xattr_version) out << " xattrs(v=" << head.xattr_version << " l=" << xattrbl.length() << ")"; @@ -179,6 +190,36 @@ public: void decode_payload() { bufferlist::iterator p = payload.begin(); ::decode(head, p); + if (header.version < 8) { + ceph_mds_caps_body_legacy body; + ::decode(body, p); + if (head.op == CEPH_CAP_OP_EXPORT) { + peer = body.peer; + } else { + size = body.size; + max_size = body.max_size; + truncate_size = body.truncate_size; + mtime = utime_t(body.mtime); + atime = utime_t(body.atime); + ctime = utime_t(body.ctime); + layout = body.layout; + time_warp_seq = body.time_warp_seq; + } + } else { + if (head.op == CEPH_CAP_OP_EXPORT) { + ::decode(peer, p); + } else { + ::decode(size, p); + ::decode(max_size, p); + ::decode(truncate_size, p); + ::decode(truncate_seq, p); + ::decode(mtime, p); + ::decode(atime, p); + ::decode(ctime, p); + ::decode(layout, p); + ::decode(time_warp_seq, p); + } + } ::decode_nohead(head.snap_trace_len, snapbl, p); assert(middle.length() == head.xattr_len); @@ -192,8 +233,6 @@ public: if (header.version >= 3) { if (head.op == CEPH_CAP_OP_IMPORT) ::decode(peer, p); - else if (head.op == CEPH_CAP_OP_EXPORT) - memcpy(&peer, &head.peer, sizeof(peer)); } if (header.version >= 4) { @@ -219,11 +258,39 @@ public: head.snap_trace_len = snapbl.length(); head.xattr_len = xattrbl.length(); - // record peer in unused fields of cap export message - if ((features & CEPH_FEATURE_EXPORT_PEER) && head.op == CEPH_CAP_OP_EXPORT) - memcpy(&head.peer, &peer, sizeof(peer)); - ::encode(head, payload); + if (features & CEPH_FEATURE_FS_FILE_LAYOUT_V2) { + if (head.op == CEPH_CAP_OP_EXPORT) { + ::encode(peer, payload); + } else { + ::encode(size, payload); + ::encode(max_size, payload); + ::encode(truncate_size, payload); + ::encode(truncate_seq, payload); + ::encode(mtime, payload); + ::encode(atime, payload); + ::encode(ctime, payload); + ::encode(layout, payload, features); + ::encode(time_warp_seq, payload); + } + } else { + header.version = 7; + ceph_mds_caps_body_legacy body; + if (head.op == CEPH_CAP_OP_EXPORT) { + body.peer = peer; + } else { + body.size = size; + body.max_size = max_size; + body.truncate_size = truncate_size; + body.truncate_seq = truncate_seq; + mtime.encode_timeval(&body.mtime); + atime.encode_timeval(&body.atime); + ctime.encode_timeval(&body.ctime); + body.layout = layout; + body.time_warp_seq = time_warp_seq; + } + ::encode(body, payload); + } ::encode_nohead(snapbl, payload); middle = xattrbl; -- 2.39.5