return r;
}
+int Client::get_or_create(Inode *dir, const string& name, Dentry **pdn)
+{
+ // lookup
+ if (dir->dir && dir->dir->dentries.count(name)) {
+ Dentry *dn = *pdn = dir->dir->dentries[name];
+
+ // is dn lease valid?
+ utime_t now = g_clock.now();
+ if (dn->inode &&
+ dn->lease_mds >= 0 &&
+ dn->lease_ttl > now &&
+ mds_sessions.count(dn->lease_mds)) {
+ MDSSession &s = mds_sessions[dn->lease_mds];
+ if (s.cap_ttl > now &&
+ s.cap_gen == dn->lease_gen) {
+ return -EEXIST;
+ }
+ }
+ } else {
+ // link up new one
+ *pdn = link(dir->dir, name.c_str(), NULL);
+ }
+ return 0;
+}
+
int Client::path_walk(const filepath& origpath, Inode **final, bool followsym)
{
filepath path = origpath;
//int get_cache_size() { return lru.lru_get_size(); }
//void set_cache_size(int m) { lru.lru_set_max(m); }
+ /**
+ * Don't call this with in==NULL, use get_or_create for that
+ */
Dentry* link(Dir *dir, const string& name, Inode *in) {
Dentry *dn = new Dentry;
dn->name = name;
//cout << "link dir " << dir->parent_inode->ino << " '" << name << "' -> inode " << in->ino << endl;
dir->dentries[dn->name] = dn;
- // link to inode
- dn->inode = in;
- assert(in->dn == 0);
- in->dn = dn;
- in->get();
-
- if (in->dir) dn->get(); // dir -> dn pin
+ if (in) { // link to inode
+ dn->inode = in;
+ assert(in->dn == 0);
+ in->dn = dn;
+ in->get();
+
+ if (in->dir) dn->get(); // dir -> dn pin
+ }
lru.lru_insert_mid(dn); // mid or top?
return dn;
int _sync_fs();
MClientRequest* make_request_from_Meta(MetaRequest * request);
+ int get_or_create(Inode *dir, const string& name, Dentry **pdn);
public:
int mount();