From: Jeff Layton Date: Mon, 1 Feb 2021 16:04:07 +0000 (-0500) Subject: client: add ceph_ll_lookup_vino X-Git-Tag: v14.2.22~35^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6359af14b10dc0df99f39cfe764fe2efe3a671d1;p=ceph.git client: add ceph_ll_lookup_vino Add a new API function for looking up an inode via a vinodeno_t. This should give ganesha a way to reliably look up snapshot inodes. We do need to add some special handling for CEPH_SNAPDIRs. If we're looking for one, then find the non-snapped parent, and then call open_snapdir to get the snapdir inode. Also, have the function check the local cache before calling the MDS to look up an inode. Fixes: https://tracker.ceph.com/issues/48991 Signed-off-by: Jeff Layton (cherry picked from commit 70622079c2ec55222a139fa5042902e0b19bd839) Conflicts: src/client/Client.cc --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 07fe47940ea8..abfc49434ac5 100755 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -10801,21 +10801,56 @@ int Client::ll_lookup(Inode *parent, const char *name, struct stat *attr, return r; } -int Client::ll_lookup_inode( - struct inodeno_t ino, +int Client::ll_lookup_vino( + vinodeno_t vino, const UserPerm& perms, Inode **inode) { ceph_assert(inode != NULL); - std::lock_guard lock(client_lock); - ldout(cct, 3) << "ll_lookup_inode " << ino << dendl; - + if (unmounting) return -ENOTCONN; - // Num1: get inode and *inode + std::lock_guard lock(client_lock); + ldout(cct, 3) << __func__ << vino << dendl; + + // Check the cache first + unordered_map::iterator p = inode_map.find(vino); + if (p != inode_map.end()) { + *inode = p->second; + _ll_get(*inode); + return 0; + } + + uint64_t snapid = vino.snapid; + + // for snapdir, find the non-snapped dir inode + if (snapid == CEPH_SNAPDIR) + vino.snapid = CEPH_NOSNAP; + + int r = _lookup_vino(vino, perms, inode); + if (r) + return r; + ceph_assert(*inode != NULL); + + if (snapid == CEPH_SNAPDIR) { + Inode *tmp = *inode; + + // open the snapdir and put the inode ref + *inode = open_snapdir(tmp); + _ll_forget(tmp, 1); + _ll_get(*inode); + } + return 0; +} + +int Client::ll_lookup_inode( + struct inodeno_t ino, + const UserPerm& perms, + Inode **inode) +{ vinodeno_t vino(ino, CEPH_NOSNAP); - return _lookup_vino(vino, perms, inode); + return ll_lookup_vino(vino, perms, inode); } int Client::ll_lookupx(Inode *parent, const char *name, Inode **out, diff --git a/src/client/Client.h b/src/client/Client.h index 5914029925ed..91e93e61aa96 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -479,6 +479,7 @@ public: int ll_lookup(Inode *parent, const char *name, struct stat *attr, Inode **out, const UserPerm& perms); int ll_lookup_inode(struct inodeno_t ino, const UserPerm& perms, Inode **inode); + int ll_lookup_vino(vinodeno_t vino, const UserPerm& perms, Inode **inode); int ll_lookupx(Inode *parent, const char *name, Inode **out, struct ceph_statx *stx, unsigned want, unsigned flags, const UserPerm& perms); diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h index 1608ac7cf9b3..1ef73921d51d 100755 --- a/src/include/cephfs/libcephfs.h +++ b/src/include/cephfs/libcephfs.h @@ -1601,6 +1601,10 @@ int ceph_debug_get_file_caps(struct ceph_mount_info *cmount, const char *path); /* Low Level */ struct Inode *ceph_ll_get_inode(struct ceph_mount_info *cmount, vinodeno_t vino); + +int ceph_ll_lookup_vino(struct ceph_mount_info *cmount, vinodeno_t vino, + Inode **inode); + int ceph_ll_lookup_inode( struct ceph_mount_info *cmount, struct inodeno_t ino, diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 6d1855644946..243549ed1210 100755 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -1572,6 +1572,14 @@ extern "C" struct Inode *ceph_ll_get_inode(class ceph_mount_info *cmount, } +extern "C" int ceph_ll_lookup_vino( + struct ceph_mount_info *cmount, + vinodeno_t vino, + Inode **inode) +{ + return (cmount->get_client())->ll_lookup_vino(vino, cmount->default_perms, inode); +} + /** * Populates the client cache with the requested inode, and its * parent dentry.