]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: Fix stat of relative symlinks
authorSam Lang <sam.lang@inktank.com>
Thu, 11 Oct 2012 17:16:02 +0000 (12:16 -0500)
committerSam Lang <sam.lang@inktank.com>
Wed, 17 Oct 2012 17:50:48 +0000 (12:50 -0500)
Stat of symlinks that are relative to their location
would return -ENOENT because the symlink target is
being appended to the path rather than replacing it.
This fix replaces the symlink component with the path
of the symlink target (in the case that its a relative
symlink), and avoids updating the inode to point the
symlink (keeps at the parent).

Signed-off-by: Sam Lang <sam.lang@inktank.com>
src/client/Client.cc

index d124cb4345713347b8becb6fe1ba362380b9a478..d5578f8149c2ca15a2ebe1828ac0656809799c2b 100644 (file)
@@ -3720,18 +3720,25 @@ int Client::path_walk(const filepath& origpath, Inode **final, bool followsym)
     int r = _lookup(cur, dname.c_str(), &next);
     if (r < 0)
       return r;
-    cur = next;
     if (i == path.depth() - 1 && followsym &&
-       cur && cur->is_symlink()) {
+       next && next->is_symlink()) {
       // resolve symlink
       if (cur->symlink[0] == '/') {
-       path = cur->symlink.c_str();
-       cur = root;
+       path = next->symlink.c_str();
+       next = root;
       } else {
-       filepath more(cur->symlink.c_str());
+       filepath more(next->symlink.c_str());
+       // we need to remove the symlink component from off of the path
+       // before adding the target that the symlink points to
+       path.pop_dentry();
        path.append(more);
+       // reset position in path walk
+       --i;
+       // remain at the same inode
+       next = cur;
       }
     }
+    cur = next;
   }
   if (!cur)
     return -ENOENT;