snapid_t first, last;
dentry_key_t key() {
- return dentry_key_t(last, name.c_str());
+ return dentry_key_t(last, name.c_str(), hash);
}
public:
return good;
}
-CDentry *CDir::lookup(const char *name, snapid_t snap)
+CDentry *CDir::lookup(const string& name, snapid_t snap)
{
dout(20) << "lookup (" << snap << ", '" << name << "')" << dendl;
- map_t::iterator iter = items.lower_bound(dentry_key_t(snap, name));
+ map_t::iterator iter = items.lower_bound(dentry_key_t(snap, name.c_str(),
+ inode->hash_dentry_name(name)));
if (iter == items.end())
return 0;
if (iter->second->name == name &&
return 0;
}
-
-
-
+CDentry *CDir::lookup_exact_snap(const string& name, snapid_t last) {
+ map_t::iterator p = items.find(dentry_key_t(last, name.c_str(),
+ inode->hash_dentry_name(name)));
+ if (p == items.end())
+ return NULL;
+ return p->second;
+}
/***
* linking fun
// -- dentries and inodes --
public:
- CDentry* lookup_exact_snap(const std::string& dname, snapid_t last) {
- map_t::iterator p = items.find(dentry_key_t(last, dname.c_str()));
- if (p == items.end())
- return NULL;
- return p->second;
+ CDentry* lookup_exact_snap(const std::string& dname, snapid_t last);
+ CDentry* lookup(const std::string& n, snapid_t snap=CEPH_NOSNAP);
+ CDentry* lookup(const char *n, snapid_t snap=CEPH_NOSNAP) {
+ return lookup(std::string(n), snap);
}
- CDentry* lookup(const std::string& n, snapid_t snap=CEPH_NOSNAP) {
- return lookup(n.c_str(), snap);
- }
- CDentry* lookup(const char *n, snapid_t snap=CEPH_NOSNAP);
CDentry* add_null_dentry(const std::string& dname,
snapid_t first=2, snapid_t last=CEPH_NOSNAP);
if (!in->is_dir()) {
assert(in->state_test(CInode::STATE_REJOINUNDEF));
in->inode.mode = S_IFDIR;
+ in->inode.dir_layout.dl_dir_hash = g_conf->mds_default_dir_hash;
}
CDir *dir = in->get_or_open_dirfrag(this, df.frag);
dir->state_set(CDir::STATE_REJOINUNDEF);
dout(10) << "opened_undef_inode " << *in << dendl;
rejoin_undef_inodes.erase(in);
if (in->is_dir()) {
+ // FIXME: re-hash dentries if necessary
+ assert(in->inode.dir_layout.dl_dir_hash == g_conf->mds_default_dir_hash);
if (in->has_dirfrags() && !in->dirfragtree.is_leaf(frag_t())) {
CDir *dir = in->get_dirfrag(frag_t());
assert(dir);
string offset_str = req->get_path2();
dout(10) << " frag " << fg << " offset '" << offset_str << "'" << dendl;
+ __u32 offset_hash = 0;
+ if (!offset_str.empty())
+ offset_hash = ceph_frag_value(diri->hash_dentry_name(offset_str));
+
// does the frag exist?
if (diri->dirfragtree[fg.value()] != fg) {
frag_t newfg = diri->dirfragtree[fg.value()];
continue;
}
- if (!offset_str.empty() && dn->get_name().compare(offset_str) <= 0)
- continue;
+ if (!offset_str.empty()) {
+ dentry_key_t offset_key(dn->last, offset_str.c_str(), offset_hash);
+ if (!(offset_key < dn->key()))
+ continue;
+ }
CInode *in = dnl->get_inode();
struct dentry_key_t {
snapid_t snapid;
const char *name;
- dentry_key_t() : snapid(0), name(0) {}
- dentry_key_t(snapid_t s, const char *n) : snapid(s), name(n) {}
+ __u32 hash;
+ dentry_key_t() : snapid(0), name(0), hash(0) {}
+ dentry_key_t(snapid_t s, const char *n, __u32 h=0) :
+ snapid(s), name(n), hash(h) {}
bool is_valid() { return name || snapid; }
inline bool operator<(const dentry_key_t& k1, const dentry_key_t& k2)
{
/*
- * order by name, then snap
+ * order by hash, name, snap
*/
- int c = strcmp(k1.name, k2.name);
- return
- c < 0 || (c == 0 && k1.snapid < k2.snapid);
+ int c = ceph_frag_value(k1.hash) - ceph_frag_value(k2.hash);
+ if (c)
+ return c < 0;
+ c = strcmp(k1.name, k2.name);
+ if (c)
+ return c < 0;
+ return k1.snapid < k2.snapid;
}