]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
uclient: Functions to create Dentrys prior to gettin caps from mds.
authorGreg Farnum <gregf@hq.newdream.net>
Fri, 18 Sep 2009 20:51:26 +0000 (13:51 -0700)
committerGreg Farnum <gregf@hq.newdream.net>
Tue, 22 Sep 2009 20:02:50 +0000 (13:02 -0700)
src/client/Client.cc
src/client/Client.h

index 4cc60f0e757a2ddfa8be1030b463f3a56e57c6d6..ef6f52c9774e67f8fcd03ea3b3ec36d61cd0dd7d 100644 (file)
@@ -2982,6 +2982,31 @@ int Client::_lookup(Inode *dir, const string& dname, Inode **target)
   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;
index e190f835b80efba0647d8d5024c7900cd3d99ab1..75ad46f9689f593d139be65a2001ee23b62e6828 100644 (file)
@@ -946,6 +946,9 @@ protected:
   //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;
@@ -955,13 +958,14 @@ protected:
     //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;
@@ -1178,6 +1182,7 @@ private:
   int _sync_fs();
 
   MClientRequest* make_request_from_Meta(MetaRequest * request);
+  int get_or_create(Inode *dir, const string& name, Dentry **pdn);
 
 public:
   int mount();