}
update_dentry_lease(dn, dlease, from, session);
+ dn->alternate_name = std::move(dlease->alternate_name);
return dn;
}
// new dn
dn = link(dir, dname, in, NULL);
}
+ dn->alternate_name = std::move(dlease.alternate_name);
update_dentry_lease(dn, &dlease, request->sent_stamp, session);
if (hash_order) {
uint64_t lease_gen = 0;
ceph_seq_t lease_seq = 0;
int cap_shared_gen = 0;
+ std::string alternate_name;
private:
xlist<Dentry *>::item inode_xlist_link;
fp.push_dentry(get_name());
}
+void CDentry::set_alternate_name(std::string_view _alternate_name)
+{
+ dout(10) << "setting alternate_name on " << *this << dendl;
+ alternate_name = _alternate_name;
+}
+
/*
* we only add ourselves to remote_parents when the linkage is
* active (no longer projected). if the passed dnl is projected,
}
}
-void CDentry::encode_remote(inodeno_t& ino, unsigned char d_type, bufferlist &bl)
+void CDentry::encode_remote(inodeno_t& ino, unsigned char d_type,
+ std::string_view alternate_name,
+ bufferlist &bl)
{
- bl.append("l", 1); // remote link
+ bl.append('l'); // remote link
// marker, name, ino
- ENCODE_START(1, 1, bl);
+ ENCODE_START(2, 1, bl);
encode(ino, bl);
encode(d_type, bl);
+ encode(alternate_name, bl);
ENCODE_FINISH(bl);
}
void CDentry::decode_remote(char icode, inodeno_t& ino, unsigned char& d_type,
+ mempool::mds_co::string& alternate_name,
ceph::buffer::list::const_iterator& bl)
{
if (icode == 'l') {
- DECODE_START(1, bl);
+ DECODE_START(2, bl);
decode(ino, bl);
decode(d_type, bl);
+ if (struct_v >= 2)
+ decode(alternate_name, bl);
DECODE_FINISH(bl);
} else if (icode == 'L') {
decode(ino, bl);
const CDir *get_dir() const { return dir; }
CDir *get_dir() { return dir; }
std::string_view get_name() const { return std::string_view(name); }
+ void set_alternate_name(std::string_view _alternate_name);
+ std::string_view get_alternate_name() const { return std::string_view(alternate_name); }
+ void decode_alternate_name(bufferlist::const_iterator &bl) { decode(alternate_name, bl); }
__u32 get_hash() const { return hash; }
void print(std::ostream& out) override;
void dump(ceph::Formatter *f) const;
- static void encode_remote(inodeno_t& ino, unsigned char d_type, bufferlist &bl);
+ static void encode_remote(inodeno_t& ino, unsigned char d_type,
+ std::string_view alternate_name,
+ bufferlist &bl);
static void decode_remote(char icode, inodeno_t& ino, unsigned char& d_type,
+ mempool::mds_co::string& alternate_name,
ceph::buffer::list::const_iterator& bl);
__u32 hash;
private:
mempool::mds_co::string name;
+ mempool::mds_co::string alternate_name;
};
std::ostream& operator<<(std::ostream& out, const CDentry& dn);
// hard link
inodeno_t ino;
unsigned char d_type;
+ mempool::mds_co::string alternate_name;
- CDentry::decode_remote(type, ino, d_type, q);
+ CDentry::decode_remote(type, ino, d_type, alternate_name, q);
+ if (alternate_name.length())
+ dn->set_alternate_name(std::move(alternate_name));
if (stale) {
if (!dn) {
// inode
// Load inode data before looking up or constructing CInode
if (type == 'i') {
- DECODE_START(1, q);
+ DECODE_START(2, q);
+ if (struct_v >= 2)
+ dn->decode_alternate_name(q);
inode_data.decode(q);
DECODE_FINISH(q);
} else {
encode(item.oldest_snap, bl);
encode(item.damage_flags, bl);
+ encode(item.alternate_name, bl);
ENCODE_FINISH(bl);
}
for (auto &item : to_set) {
encode(item.first, bl);
if (item.is_remote) {
- CDentry::encode_remote(item.ino, item.d_type, bl); // remote link
+ // remote link
+ CDentry::encode_remote(item.ino, item.d_type, item.alternate_name, bl);
} else {
// marker, name, inode, [symlink string]
bl.append('i'); // inode
- ENCODE_START(1, 1, bl);
+ ENCODE_START(2, 1, bl);
_encode_primary_inode_base(item, dfts, bl);
ENCODE_FINISH(bl);
}
// reverve enough memories, which maybe larger than the actually needed
to_set.reserve(count);
+ // for dir fragtrees
bufferlist dfts(CEPH_PAGE_SIZE);
auto write_one = [&](CDentry *dn) {
item.first = dn->first;
+ // Only in very rare case the dn->alternate_name not empty,
+ // so it won't cost much to copy it here
+ item.alternate_name = dn->get_alternate_name();
+
// primary or remote?
if (dn->linkage.is_remote()) {
item.is_remote = true;
inodeno_t ino;
unsigned char d_type;
+ mempool::mds_co::string alternate_name;
bool snaprealm = false;
sr_t srnode;
lstat.mask = CEPH_LEASE_VALID | mask;
lstat.duration_ms = (uint32_t)(1000 * mdcache->client_lease_durations[pool]);
lstat.seq = ++l->seq;
+ lstat.alternate_name = mempool::mds_co::string(dn->get_alternate_name());
encode_lease(bl, session->info, lstat);
dout(20) << "issue_client_lease seq " << lstat.seq << " dur " << lstat.duration_ms << "ms "
<< " on " << *dn << dendl;
// null lease
LeaseStat lstat;
lstat.mask = mask;
+ lstat.alternate_name = mempool::mds_co::string(dn->get_alternate_name());
encode_lease(bl, session->info, lstat);
dout(20) << "issue_client_lease no/null lease on " << *dn << dendl;
}
const LeaseStat& ls)
{
if (info.has_feature(CEPHFS_FEATURE_REPLY_ENCODING)) {
- ENCODE_START(1, 1, bl);
+ ENCODE_START(2, 1, bl);
encode(ls.mask, bl);
encode(ls.duration_ms, bl);
encode(ls.seq, bl);
+ encode(ls.alternate_name, bl);
ENCODE_FINISH(bl);
}
else {
if (dn->get_linkage()->is_remote()) {
inodeno_t ino = dn->get_linkage()->get_remote_ino();
unsigned char d_type = dn->get_linkage()->get_remote_d_type();
- CDentry::encode_remote(ino, d_type, exportbl); // remote link
+ // remote link
+ CDentry::encode_remote(ino, d_type, dn->get_alternate_name(), exportbl);
continue;
}
// -- inode
exportbl.append("i", 1); // inode dentry
- ENCODE_START(1, 1, exportbl);
+ ENCODE_START(2, 1, exportbl);
encode_export_inode(in, exportbl, exported_client_map, exported_client_metadata_map); // encode, and (update state for) export
+ encode(dn->get_alternate_name(), exportbl);
ENCODE_FINISH(exportbl);
// directory?
// remote link
inodeno_t ino;
unsigned char d_type;
- CDentry::decode_remote(icode, ino, d_type, blp);
+ mempool::mds_co::string alternate_name;
+
+ CDentry::decode_remote(icode, ino, d_type, alternate_name, blp);
+ if (alternate_name.length())
+ dn->set_alternate_name(std::move(alternate_name));
+
if (dn->get_linkage()->is_remote()) {
ceph_assert(dn->get_linkage()->get_remote_ino() == ino);
} else {
// inode
ceph_assert(le);
if (icode == 'i') {
- DECODE_START(1, blp);
+ DECODE_START(2, blp);
decode_import_inode(dn, blp, oldauth, ls,
peer_exports, updated_scatterlocks);
+ if (struct_v >= 2)
+ dn->decode_alternate_name(blp);
DECODE_FINISH(blp);
} else {
decode_import_inode(dn, blp, oldauth, ls,
req->head.args.open.mode | S_IFREG, &layout);
ceph_assert(newi);
+ dn->set_alternate_name(req->get_alternate_name());
+
// it's a file.
dn->push_projected_linkage(newi);
CInode *newi = prepare_new_inode(mdr, dn->get_dir(), inodeno_t(req->head.ino), mode, &layout);
ceph_assert(newi);
+ dn->set_alternate_name(req->get_alternate_name());
dn->push_projected_linkage(newi);
auto _inode = newi->_get_inode();
CInode *newi = prepare_new_inode(mdr, dir, inodeno_t(req->head.ino), mode);
ceph_assert(newi);
+ dn->set_alternate_name(req->get_alternate_name());
+
// it's a directory.
dn->push_projected_linkage(newi);
const cref_t<MClientRequest> &req = mdr->client_request;
+ dn->set_alternate_name(req->get_alternate_name());
+
unsigned mode = S_IFLNK | 0777;
CInode *newi = prepare_new_inode(mdr, dir, inodeno_t(req->head.ino), mode);
ceph_assert(newi);
return;
}
+ destdn->set_alternate_name(req->get_alternate_name());
+
targeti = ret.second->get_projected_linkage()->get_inode();
}
return;
}
+ destdn->set_alternate_name(req->get_alternate_name());
+
// is this a stray migration, reintegration or merge? (sanity checks!)
if (mdr->reqid.name.is_mds() &&
!(MDS_INO_IS_STRAY(srcpath.get_ino()) &&
"multi_reconnect",
"deleg_ino",
"metric_collect",
+ "alternate_name",
};
static_assert(feature_names.size() == CEPHFS_FEATURE_MAX + 1);
#define CEPHFS_FEATURE_DELEG_INO 13
#define CEPHFS_FEATURE_OCTOPUS 13
#define CEPHFS_FEATURE_METRIC_COLLECT 14
-#define CEPHFS_FEATURE_MAX 14
+#define CEPHFS_FEATURE_ALTERNATE_NAME 15
+#define CEPHFS_FEATURE_MAX 15
#define CEPHFS_FEATURES_ALL { \
0, 1, 2, 3, 4, \
CEPHFS_FEATURE_DELEG_INO, \
CEPHFS_FEATURE_OCTOPUS, \
CEPHFS_FEATURE_METRIC_COLLECT, \
+ CEPHFS_FEATURE_ALTERNATE_NAME, \
}
#define CEPHFS_METRIC_FEATURES_ALL { \
#include "include/types.h"
#include "include/fs_types.h"
+#include "include/mempool.h"
#include "MClientRequest.h"
#include "msg/Message.h"
__u16 mask;
__u32 duration_ms;
__u32 seq;
+ std::string alternate_name;
LeaseStat() : mask(0), duration_ms(0), seq(0) {}
LeaseStat(__u16 msk, __u32 dur, __u32 sq) : mask{msk}, duration_ms{dur}, seq{sq} {}
void decode(ceph::buffer::list::const_iterator &bl, const uint64_t features) {
using ceph::decode;
if (features == (uint64_t)-1) {
- DECODE_START(1, bl);
+ DECODE_START(2, bl);
decode(mask, bl);
decode(duration_ms, bl);
decode(seq, bl);
+ if (struct_v >= 2)
+ decode(alternate_name, bl);
DECODE_FINISH(bl);
}
else {
class MClientRequest final : public MMDSOp {
private:
- static constexpr int HEAD_VERSION = 4;
+ static constexpr int HEAD_VERSION = 5;
static constexpr int COMPAT_VERSION = 1;
public:
// path arguments
filepath path, path2;
+ std::string alternate_name;
std::vector<uint64_t> gid_list;
/* XXX HACK */
head.flags = head.flags | CEPH_MDS_FLAG_ASYNC;
}
+ void set_alternate_name(std::string&& _alternate_name) {
+ alternate_name = std::move(_alternate_name);
+ }
+ void set_alternate_name(bufferptr&& cipher) {
+ alternate_name = std::move(cipher.c_str());
+ }
+
utime_t get_stamp() const { return stamp; }
ceph_tid_t get_oldest_client_tid() const { return head.oldest_client_tid; }
int get_num_fwd() const { return head.num_fwd; }
const filepath& get_filepath() const { return path; }
const std::string& get_path2() const { return path2.get_path(); }
const filepath& get_filepath2() const { return path2; }
+ std::string_view get_alternate_name() const { return std::string_view(alternate_name); }
int get_dentry_wanted() const { return get_flags() & CEPH_MDS_FLAG_WANT_DENTRY; }
decode(stamp, p);
if (header.version >= 4) // epoch 3 was for a ceph_mds_request_args change
decode(gid_list, p);
+ if (header.version >= 5)
+ decode(alternate_name, p);
}
void encode_payload(uint64_t features) override {
ceph::encode_nohead(releases, payload);
encode(stamp, payload);
encode(gid_list, payload);
+ encode(alternate_name, payload);
}
std::string_view get_type_name() const override { return "creq"; }
#include "mds/CDentry.h"
#include "mds/CInode.h"
+#include "mds/CDentry.h"
#include "mds/InoTable.h"
#include "mds/SnapServer.h"
#include "cls/cephfs/cls_cephfs_client.h"
}
char dentry_type;
decode(dentry_type, q);
+ mempool::mds_co::string alternate_name;
if (dentry_type == 'I' || dentry_type == 'i') {
InodeStore inode;
if (dentry_type == 'i') {
- DECODE_START(1, q);
+ DECODE_START(2, q);
+ if (struct_v >= 2)
+ decode(alternate_name, q);
inode.decode(q);
DECODE_FINISH(q);
} else {
} else if (dentry_type == 'L' || dentry_type == 'l') {
inodeno_t ino;
unsigned char d_type;
- CDentry::decode_remote(dentry_type, ino, d_type, q);
+ CDentry::decode_remote(dentry_type, ino, d_type, alternate_name, q);
if (step == SCAN_INOS) {
remote_links[ino]++;
decode(dentry_type, q);
if (dentry_type == 'I' || dentry_type == 'i') {
if (dentry_type == 'i') {
- DECODE_START(1, q);
+ mempool::mds_co::string alternate_name;
+
+ DECODE_START(2, q);
+ if (struct_v >= 2)
+ decode(alternate_name, q);
inode->decode(q);
DECODE_FINISH(q);
} else {
// Read out inode version to compare with backing store
InodeStore inode;
if (dentry_type == 'i') {
- DECODE_START(1, q);
+ mempool::mds_co::string alternate_name;
+
+ DECODE_START(2, q);
+ if (struct_v >= 2)
+ decode(alternate_name, q);
inode.decode(q);
DECODE_FINISH(q);
} else {
// hard link
inodeno_t ino;
unsigned char d_type;
+ mempool::mds_co::string alternate_name;
- CDentry::decode_remote(type, ino, d_type, q);
+ CDentry::decode_remote(type, ino, d_type, alternate_name, q);
if (sp_ino > 0) {
if (sp_ino == ino) {
// load inode data before lookuping up or constructing CInode
InodeStore& inode_data = *(new InodeStore);
if (type == 'i') {
- DECODE_START(1, q);
+ mempool::mds_co::string alternate_name;
+
+ DECODE_START(2, q);
+ if (struct_v >= 2)
+ decode(alternate_name, q);
inode_data.decode(q);
DECODE_FINISH(q);
} else {