From: Jeff Layton Date: Fri, 12 Aug 2016 22:48:12 +0000 (-0400) Subject: client: don't use special faked-up inode for /.. X-Git-Tag: v10.2.6~113^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7819adb3b5f9af813d4df05d3483175ee54e10df;p=ceph.git client: don't use special faked-up inode for /.. 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. Signed-off-by: Jeff Layton (cherry picked from commit 30d4ca01db0de9a1e12658793ba9bf9faf0331dd) --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 282c57bb1816..c09af04b0c3a 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -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; diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index e8f5f2f5d576..3f1128677f13 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -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) */