]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: don't use special faked-up inode for /.. 12766/head
authorJeff Layton <jlayton@redhat.com>
Tue, 3 Jan 2017 17:56:51 +0000 (12:56 -0500)
committerJeff Layton <jlayton@redhat.com>
Tue, 3 Jan 2017 17:56:51 +0000 (12:56 -0500)
The CEPH_INO_DOTDOT thing is quite strange. Under most OS (Linux
included), the parent of the root is itself. IOW, at the root, '.' and
'..' refer to the same inode.

Change the ceph client to do the same, as this allows users to get
valid stat info for '..', as well as elimnating some special-casing.

Also in several places, we're checking dn_set.empty as an indicator
of being the root. While that is true for the root, it's also true
for unlinked directories.

This patch has treats them the same. An unlinked directory will
be reparented to itself, effectively acting as a root of its own.

Fixes: http://tracker.ceph.com/issues/18408
Signed-off-by: Jeff Layton <jlayton@redhat.com>
(cherry picked from commit 30d4ca01db0de9a1e12658793ba9bf9faf0331dd)

src/client/Client.cc
src/include/ceph_fs.h

index 282c57bb18165a8a40a3861762a954139920bd71..c09af04b0c3a2f1d65ea8816cb57fe1a09d5252a 100644 (file)
@@ -5876,7 +5876,7 @@ int Client::_lookup(Inode *dir, const string& dname, int mask,
 
   if (dname == "..") {
     if (dir->dn_set.empty())
-      r = -ENOENT;
+      *target = dir;
     else
       *target = dir->get_first_parent()->dir->parent_inode; //dirs can't be hard-linked
     goto done;
@@ -7216,16 +7216,14 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p)
   if (dirp->offset == 1) {
     ldout(cct, 15) << " including .." << dendl;
     uint64_t next_off = 2;
-    if (!diri->dn_set.empty()) {
-      InodeRef& in = diri->get_first_parent()->inode;
-      fill_stat(in, &st);
-      fill_dirent(&de, "..", S_IFDIR, st.st_ino, next_off);
-    } else {
-      /* must be at the root (no parent),
-       * so we add the dotdot with a special inode (3) */
-      fill_dirent(&de, "..", S_IFDIR, CEPH_INO_DOTDOT, next_off);
-    }
+    InodeRef in;
+    if (diri->dn_set.empty())
+      in = diri;
+    else
+      in = diri->get_first_parent()->inode;
 
+    fill_stat(in, &st);
+    fill_dirent(&de, "..", S_IFDIR, st.st_ino, next_off);
 
     client_lock.Unlock();
     int r = cb(p, &de, &st, -1, next_off);
@@ -9614,13 +9612,6 @@ int Client::ll_getattr(Inode *in, struct stat *attr, int uid, int gid)
   tout(cct) << "ll_getattr" << std::endl;
   tout(cct) << vino.ino.val << std::endl;
 
-  /* special case for dotdot (..) */
-  if (vino.ino.val == CEPH_INO_DOTDOT) {
-    attr->st_mode = S_IFDIR | 0755;
-    attr->st_nlink = 2;
-    return 0;
-  }
-
   int res;
   if (vino.snapid < CEPH_NOSNAP)
     res = 0;
index e8f5f2f5d576d8f6f8fd2c8f792adc1f5f16953c..3f1128677f13987272ef06aec04c50aad020600f 100644 (file)
@@ -28,7 +28,6 @@
 
 #define CEPH_INO_ROOT   1
 #define CEPH_INO_CEPH   2       /* hidden .ceph dir */
-#define CEPH_INO_DOTDOT 3      /* used by ceph fuse for parent (..) */
 #define CEPH_INO_LOST_AND_FOUND 4      /* reserved ino for use in recovery */
 
 /* arbitrary limit on max # of monitors (cluster of 3 is typical) */