* Use the new feature bit CEPHFS_FEATURE_REPLY_ENCODING for encoding.
* encode/decode in the new format.
* Dropped DirStat::encode().
* The old format is maintained for backward compatibility.
* Created CDir::encode_dirstat() for encoding and dropped the duplicates.
Fixes: http://tracker.ceph.com/issues/24444
Signed-off-by: Jos Collin <jcollin@redhat.com>
assert(dir);
// dirstat
- DirStat dst(p);
+ DirStat dst(p, features);
__u32 numdn;
__u16 flags;
decode(numdn, p);
if (reply->head.is_dentry) {
dirst.decode(p, features);
- dst.decode(p);
+ dst.decode(p, features);
decode(dname, p);
decode(dlease, p);
}
pop_auth_subtree.zero();
}
+void CDir::encode_dirstat(bufferlist& bl, const session_info_t& info, const DirStat& ds) {
+ if (info.has_feature(CEPHFS_FEATURE_REPLY_ENCODING)) {
+ ENCODE_START(1, 1, bl);
+ encode(ds.frag, bl);
+ encode(ds.auth, bl);
+ encode(ds.dist, bl);
+ ENCODE_FINISH(bl);
+ }
+ else {
+ encode(ds.frag, bl);
+ encode(ds.auth, bl);
+ encode(ds.dist, bl);
+ }
+}
/********************************
* AUTHORITY
}
}
-
/*****************************************
* AUTH PINS and FREEZING
*
#include "CInode.h"
#include "MDSCacheObject.h"
#include "MDSContext.h"
+#include "cephfs_features.h"
+#include "SessionMap.h"
+#include "messages/MClientReply.h"
class CDentry;
class MDCache;
ls.insert(auth);
}
}
- void encode_dirstat(bufferlist& bl, mds_rank_t whoami) {
- /*
- * note: encoding matches struct ceph_client_reply_dirfrag
- */
- frag_t frag = get_frag();
- mds_rank_t auth;
- std::set<mds_rank_t> dist;
-
- auth = dir_auth.first;
- if (is_auth())
- get_dist_spec(dist, whoami);
-
- encode(frag, bl);
- encode(auth, bl);
- encode(dist, bl);
- }
+
+ static void encode_dirstat(bufferlist& bl, const session_info_t& info, const DirStat& ds);
void _encode_base(bufferlist& bl) {
encode(first, bl);
}
}
-
-void Server::encode_empty_dirstat(bufferlist& bl)
-{
- static DirStat empty;
- empty.encode(bl);
-}
-
void Server::encode_infinite_lease(bufferlist& bl)
{
LeaseStat e;
if (dir->is_complete())
dir->verify_fragstat();
#endif
- dir->encode_dirstat(bl, whoami);
+ DirStat ds;
+ ds.frag = dir->get_frag();
+ ds.auth = dir->get_dir_auth().first;
+ if (dir->is_auth())
+ dir->get_dist_spec(ds.dist, whoami);
+
+ dir->encode_dirstat(bl, session->info, ds);
dout(20) << "set_trace_dist added dir " << *dir << dendl;
encode(dn->get_name(), bl);
// start final blob
bufferlist dirbl;
- dir->encode_dirstat(dirbl, mds->get_nodeid());
+ DirStat ds;
+ ds.frag = dir->get_frag();
+ ds.auth = dir->get_dir_auth().first;
+ if (dir->is_auth())
+ dir->get_dist_spec(ds.dist, mds->get_nodeid());
+
+ dir->encode_dirstat(dirbl, mdr->session->info, ds);
// count bytes available.
// this isn't perfect, but we should capture the main variable/unbounded size items!
if (!offset_str.empty())
last_snapid = realm->resolve_snapname(offset_str, diri->ino());
+ //Empty DirStat
bufferlist dirbl;
- encode_empty_dirstat(dirbl);
+ static DirStat empty;
+ CDir::encode_dirstat(dirbl, mdr->session->info, empty);
max_bytes -= dirbl.length() - sizeof(__u32) + sizeof(__u8) * 2;
int num_dentries_wanted,
MDRequestRef& mdr);
- void encode_empty_dirstat(bufferlist& bl);
void encode_infinite_lease(bufferlist& bl);
void encode_null_lease(bufferlist& bl);
set<__s32> dist;
DirStat() : auth(CDIR_AUTH_PARENT) {}
- DirStat(bufferlist::const_iterator& p) {
- decode(p);
+ DirStat(bufferlist::const_iterator& p, const uint64_t features) {
+ decode(p, features);
}
- void encode(bufferlist& bl) {
- using ceph::encode;
- encode(frag, bl);
- encode(auth, bl);
- encode(dist, bl);
- }
- void decode(bufferlist::const_iterator& p) {
+ void decode(bufferlist::const_iterator& p, const uint64_t features) {
using ceph::decode;
- decode(frag, p);
- decode(auth, p);
- decode(dist, p);
+ if (features == (uint64_t)-1) {
+ DECODE_START(1, p);
+ decode(frag, p);
+ decode(auth, p);
+ decode(dist, p);
+ DECODE_FINISH(p);
+ }
+ else {
+ decode(frag, p);
+ decode(auth, p);
+ decode(dist, p);
+ }
}
// see CDir::encode_dirstat for encoder.