| 52 | } |
| 53 | |
| 54 | void decode(struct ceph_mds_request_head& h, ceph::buffer::list::const_iterator& bl) { |
| 55 | using ceph::decode; |
| 56 | unsigned struct_end = bl.get_off(); |
| 57 | |
| 58 | decode(h.version, bl); |
| 59 | decode(h.oldest_client_tid, bl); |
| 60 | decode(h.mdsmap_epoch, bl); |
| 61 | decode(h.flags, bl); |
| 62 | decode(h.num_retry, bl); |
| 63 | decode(h.num_fwd, bl); |
| 64 | decode(h.num_releases, bl); |
| 65 | decode(h.op, bl); |
| 66 | decode(h.caller_uid, bl); |
| 67 | decode(h.caller_gid, bl); |
| 68 | decode(h.ino, bl); |
| 69 | bl.copy(sizeof(h.args), (char*)&(h.args)); |
| 70 | |
| 71 | if (h.version >= 2) { |
| 72 | decode(h.ext_num_retry, bl); |
| 73 | decode(h.ext_num_fwd, bl); |
| 74 | } else { |
| 75 | h.ext_num_retry = h.num_retry; |
| 76 | h.ext_num_fwd = h.num_fwd; |
| 77 | } |
| 78 | |
| 79 | if (h.version >= 3) { |
| 80 | decode(h.struct_len, bl); |
| 81 | struct_end += h.struct_len; |
| 82 | |
| 83 | decode(h.owner_uid, bl); |
| 84 | decode(h.owner_gid, bl); |
| 85 | } else { |
| 86 | /* |
| 87 | * client is old: let's take caller_{u,g}id as owner_{u,g}id |
| 88 | * this is how it worked before adding of owner_{u,g}id fields. |
| 89 | */ |
| 90 | h.owner_uid = h.caller_uid; |
| 91 | h.owner_gid = h.caller_gid; |
| 92 | } |
| 93 | |
| 94 | /* add new fields handling here */ |
| 95 | |
| 96 | /* |
| 97 | * From version 3 we have struct_len field. |
| 98 | * It allows us to properly handle a case |
| 99 | * when client send struct ceph_mds_request_head |
| 100 | * bigger in size than MDS supports. In this |
| 101 | * case we just want to skip all remaining bytes |
| 102 | * at the end. |
| 103 | * |
| 104 | * See also DECODE_FINISH macro. Unfortunately, |
| 105 | * we can't start using it right now as it will be |
| 106 | * an incompatible protocol change. |
| 107 | */ |
| 108 | if (h.version >= 3) { |
| 109 | if (bl.get_off() > struct_end) |
| 110 | throw ::ceph::buffer::malformed_input(DECODE_ERR_PAST(__PRETTY_FUNCTION__)); |
| 111 | if (bl.get_off() < struct_end) |
nothing calls this directly
no test coverage detected