]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: use discover_path to open remote inode
authorYan, Zheng <zheng.z.yan@intel.com>
Mon, 13 Jan 2014 03:32:38 +0000 (11:32 +0800)
committerYan, Zheng <zheng.z.yan@intel.com>
Mon, 17 Feb 2014 01:37:50 +0000 (09:37 +0800)
MDCache::discover_ino() doesn't work well for directories that are
fragmented to several dirfrags. Because MDCache::handle_discover()
doesn't know which dirfrags the inode lives in when the sender has
outdatad frag information.

This patch replaces all use of MDCache::discover_ino() with
MDCache::discover_path().

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
src/mds/MDCache.cc

index a44e3a840235d2b1bc6e211795ff184de9a5a895..ea518df2d67189a5b7bc5a4186fb8737b436ffdd 100644 (file)
@@ -8255,10 +8255,9 @@ int MDCache::open_ino_traverse_dir(inodeno_t ino, MMDSOpenIno *m,
     }
     if (dir) {
       inodeno_t next_ino = i > 0 ? ancestors[i - 1].dirino : ino;
+      CDentry *dn = dir->lookup(name);
+      CDentry::linkage_t *dnl = dn ? dn->get_linkage() : NULL;
       if (dir->is_auth()) {
-       CDentry *dn = dir->lookup(name);
-       CDentry::linkage_t *dnl = dn ? dn->get_linkage() : NULL;
-
        if (dnl && dnl->is_primary() &&
            dnl->get_inode()->state_test(CInode::STATE_REJOINUNDEF)) {
          dout(10) << " fetching undef " << *dnl->get_inode() << dendl;
@@ -8277,9 +8276,20 @@ int MDCache::open_ino_traverse_dir(inodeno_t ino, MMDSOpenIno *m,
        if (i == 0)
          err = -ENOENT;
       } else if (discover) {
-       discover_ino(dir, next_ino, _open_ino_get_waiter(ino, m),
-                    (i == 0 && want_xlocked));
-       return 1;
+       if (!dnl) {
+         filepath path(name, 0);
+         discover_path(dir, CEPH_NOSNAP, path, _open_ino_get_waiter(ino, m),
+                       (i == 0 && want_xlocked));
+         return 1;
+       }
+       if (dnl->is_null() && !dn->lock.can_read(-1)) {
+         dout(10) << " null " << *dn << " is not readable, waiting" << dendl;
+         dn->lock.add_waiter(SimpleLock::WAIT_RD, _open_ino_get_waiter(ino, m));
+         return 1;
+       }
+       dout(10) << " no ino " << next_ino << " in " << *dir << dendl;
+       if (i == 0)
+         err = -ENOENT;
       }
     }
     if (hint && i == 0)
@@ -8483,8 +8493,10 @@ void MDCache::open_ino(inodeno_t ino, int64_t pool, Context* fin,
          if (diri) {
            frag_t fg = diri->pick_dirfrag(info.ancestors[0].dname);
            CDir *dir = diri->get_dirfrag(fg);
-           if (dir && !dir->is_auth())
-             discover_ino(dir, ino, NULL, true);
+           if (dir && !dir->is_auth()) {
+             filepath path(info.ancestors[0].dname, 0);
+             discover_path(dir, CEPH_NOSNAP, path, NULL, true);
+           }
          }
        }
        info.want_xlocked = true;