From fb05dd1806fc0edf2e4c0908aae114d57099a6d6 Mon Sep 17 00:00:00 2001 From: Patrick Donnelly Date: Fri, 26 Jan 2024 16:34:41 -0500 Subject: [PATCH] mds: convert encoded ephemeral dist pin to flags To use space efficiently, convert this field to a 8 bit flags field that is backward compatible. Signed-off-by: Patrick Donnelly --- src/include/cephfs/types.h | 46 +++++++++++++++++++++++++++++++++----- src/mds/CInode.cc | 18 +++++++-------- src/mds/CInode.h | 2 +- src/mds/Server.cc | 2 +- 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/include/cephfs/types.h b/src/include/cephfs/types.h index 1b66929240b..5ab5c229a06 100644 --- a/src/include/cephfs/types.h +++ b/src/include/cephfs/types.h @@ -394,6 +394,8 @@ struct inode_t { */ using client_range_map = std::map,Allocator>>; + static const uint8_t F_EPHEMERAL_DISTRIBUTED_PIN = (1<<0); + inode_t() { clear_layout(); @@ -482,6 +484,23 @@ struct inode_t { old_pools.insert(l); } + void set_flag(bool v, uint8_t flag) { + if (v) { + flags |= flag; + } else { + flags &= ~(flag); + } + } + bool get_flag(uint8_t flag) const { + return flags&flag; + } + void set_ephemeral_distributed_pin(bool v) { + set_flag(v, F_EPHEMERAL_DISTRIBUTED_PIN); + } + bool get_ephemeral_distributed_pin() const { + return get_flag(F_EPHEMERAL_DISTRIBUTED_PIN); + } + void encode(ceph::buffer::list &bl, uint64_t features) const; void decode(ceph::buffer::list::const_iterator& bl); void dump(ceph::Formatter *f) const; @@ -548,7 +567,23 @@ struct inode_t { mds_rank_t export_pin = MDS_RANK_NONE; double export_ephemeral_random_pin = 0; - bool export_ephemeral_distributed_pin = false; + /** + * N.B. previously this was a bool for distributed_ephemeral_pin which is + * encoded as a __u8. We take advantage of that to harness the remaining 7 + * bits to avoid adding yet another field to this struct. This is safe also + * because the integral conversion of a bool to int (__u8) is well-defined + * per the standard as 0 (false) and 1 (true): + * + * [conv.integral] + * If the destination type is bool, see [conv.bool]. If the source type is + * bool, the value false is converted to zero and the value true is converted + * to one. + * + * So we can be certain the other bits have not be set during + * encoding/decoding due to implementation defined compiler behavior. + * + */ + uint8_t flags = 0; // special stuff version_t version = 0; // auth only @@ -630,12 +665,13 @@ void inode_t::encode(ceph::buffer::list &bl, uint64_t features) const encode(export_pin, bl); encode(export_ephemeral_random_pin, bl); - encode(export_ephemeral_distributed_pin, bl); + encode(flags, bl); encode(!fscrypt_auth.empty(), bl); encode(fscrypt_auth, bl); encode(fscrypt_file, bl); encode(fscrypt_last_block, bl); + ENCODE_FINISH(bl); } @@ -734,10 +770,10 @@ void inode_t::decode(ceph::buffer::list::const_iterator &p) if (struct_v >= 16) { decode(export_ephemeral_random_pin, p); - decode(export_ephemeral_distributed_pin, p); + decode(flags, p); } else { export_ephemeral_random_pin = 0; - export_ephemeral_distributed_pin = false; + flags = 0; } if (struct_v >= 17) { @@ -791,7 +827,7 @@ void inode_t::dump(ceph::Formatter *f) const f->dump_unsigned("change_attr", change_attr); f->dump_int("export_pin", export_pin); f->dump_int("export_ephemeral_random_pin", export_ephemeral_random_pin); - f->dump_bool("export_ephemeral_distributed_pin", export_ephemeral_distributed_pin); + f->dump_bool("export_ephemeral_distributed_pin", get_ephemeral_distributed_pin()); f->open_array_section("client_ranges"); for (const auto &p : client_ranges) { diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 911bedf408f..8225e4fbb5a 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -493,8 +493,8 @@ void CInode::pop_and_dirty_projected_inode(LogSegment *ls, const MutationRef& mu bool pool_updated = get_inode()->layout.pool_id != front.inode->layout.pool_id; bool pin_updated = (get_inode()->export_pin != front.inode->export_pin) || - (get_inode()->export_ephemeral_distributed_pin != - front.inode->export_ephemeral_distributed_pin); + (get_inode()->get_ephemeral_distributed_pin() != + front.inode->get_ephemeral_distributed_pin()); reset_inode(std::move(front.inode)); if (front.xattrs != get_xattrs()) @@ -2130,7 +2130,7 @@ void CInode::encode_lock_ipolicy(bufferlist& bl) encode(get_inode()->layout, bl, mdcache->mds->mdsmap->get_up_features()); encode(get_inode()->quota, bl); encode(get_inode()->export_pin, bl); - encode(get_inode()->export_ephemeral_distributed_pin, bl); + encode(get_inode()->flags, bl); encode(get_inode()->export_ephemeral_random_pin, bl); } ENCODE_FINISH(bl); @@ -2151,15 +2151,15 @@ void CInode::decode_lock_ipolicy(bufferlist::const_iterator& p) decode(_inode->quota, p); decode(_inode->export_pin, p); if (struct_v >= 2) { - decode(_inode->export_ephemeral_distributed_pin, p); + decode(_inode->flags, p); decode(_inode->export_ephemeral_random_pin, p); } } DECODE_FINISH(p); bool pin_updated = (get_inode()->export_pin != _inode->export_pin) || - (get_inode()->export_ephemeral_distributed_pin != - _inode->export_ephemeral_distributed_pin); + (get_inode()->get_ephemeral_distributed_pin() != + _inode->get_ephemeral_distributed_pin()); reset_inode(std::move(_inode)); maybe_export_pin(pin_updated); } @@ -5443,7 +5443,7 @@ void CInode::setxattr_ephemeral_rand(double probability) void CInode::setxattr_ephemeral_dist(bool val) { ceph_assert(is_dir()); - _get_projected_inode()->export_ephemeral_distributed_pin = val; + _get_projected_inode()->set_ephemeral_distributed_pin(val); } void CInode::set_export_pin(mds_rank_t rank) @@ -5479,7 +5479,7 @@ mds_rank_t CInode::get_export_pin(bool inherit) const if (in->get_inode()->export_pin >= 0) { return in->get_inode()->export_pin; - } else if (in->get_inode()->export_ephemeral_distributed_pin && + } else if (in->get_inode()->get_ephemeral_distributed_pin() && mdcache->get_export_ephemeral_distributed_config()) { if (in != this) return mdcache->hash_into_rank_bucket(in->ino(), dir->get_frag()); @@ -5545,7 +5545,7 @@ double CInode::get_ephemeral_rand() const * random pin set. */ if (in->get_inode()->export_pin >= 0 || - in->get_inode()->export_ephemeral_distributed_pin) + in->get_inode()->get_ephemeral_distributed_pin()) return 0.0; in = pdn->get_dir()->inode; diff --git a/src/mds/CInode.h b/src/mds/CInode.h index 1aaa5eadb5f..10fabc402d6 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -1025,7 +1025,7 @@ class CInode : public MDSCacheObject, public InodeStoreBase, public Counterexport_ephemeral_random_pin > 0.0 || - get_inode()->export_ephemeral_distributed_pin; + get_inode()->get_ephemeral_distributed_pin(); } bool is_ephemerally_pinned() const { return state_test(STATE_DISTEPHEMERALPIN) || diff --git a/src/mds/Server.cc b/src/mds/Server.cc index d3d14a61ce6..3bc4f9196b6 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -6885,7 +6885,7 @@ void Server::handle_client_getvxattr(const MDRequestRef& mdr) } else if (xattr_name == "ceph.dir.pin.random"sv) { *css << cur->get_projected_inode()->export_ephemeral_random_pin; } else if (xattr_name == "ceph.dir.pin.distributed"sv) { - *css << cur->get_projected_inode()->export_ephemeral_distributed_pin; + *css << cur->get_projected_inode()->get_ephemeral_distributed_pin(); } else { // otherwise respond as invalid request // since we only handle ceph vxattrs here -- 2.39.5