+
+ if (h.version >= 3) {
+ decode(h.struct_len, bl);
+ struct_end += h.struct_len;
+
+ decode(h.owner_uid, bl);
+ decode(h.owner_gid, bl);
+ } else {
+ /*
+ * client is old: let's take caller_{u,g}id as owner_{u,g}id
+ * this is how it worked before adding of owner_{u,g}id fields.
+ */
+ h.owner_uid = h.caller_uid;
+ h.owner_gid = h.caller_gid;
+ }
+
+ /* add new fields handling here */
+
+ /*
+ * From version 3 we have struct_len field.
+ * It allows us to properly handle a case
+ * when client send struct ceph_mds_request_head
+ * bigger in size than MDS supports. In this
+ * case we just want to skip all remaining bytes
+ * at the end.
+ *
+ * See also DECODE_FINISH macro. Unfortunately,
+ * we can't start using it right now as it will be
+ * an incompatible protocol change.
+ */
+ if (h.version >= 3) {
+ if (bl.get_off() > struct_end)
+ throw ::ceph::buffer::malformed_input(DECODE_ERR_PAST(__PRETTY_FUNCTION__));
+ if (bl.get_off() < struct_end)
+ bl += struct_end - bl.get_off();
+ }