]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: add ceph_ll_lookup_vino
authorJeff Layton <jlayton@redhat.com>
Mon, 1 Feb 2021 16:04:07 +0000 (11:04 -0500)
committerPatrick Donnelly <pdonnell@redhat.com>
Fri, 12 Mar 2021 21:02:33 +0000 (13:02 -0800)
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 <jlayton@redhat.com>
(cherry picked from commit 70622079c2ec55222a139fa5042902e0b19bd839)

src/client/Client.cc
src/client/Client.h
src/include/cephfs/libcephfs.h
src/libcephfs.cc

index ed25e465e159c4e0e3be73c9284a8e27c5fd86f1..48791b741152129bc7cc9d4a133b6057ae966e2f 100644 (file)
@@ -11328,8 +11328,8 @@ 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)
 {
@@ -11339,11 +11339,45 @@ int Client::ll_lookup_inode(
     return -ENOTCONN;
 
   std::scoped_lock lock(client_lock);
-  ldout(cct, 3) << "ll_lookup_inode " << ino << dendl;
+  ldout(cct, 3) << __func__ << " " << vino << dendl;
+
+  // Check the cache first
+  unordered_map<vinodeno_t,Inode*>::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);
 
-  // Num1: get inode and *inode
+  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,
index c4aa3bd43a3672eb1f0362ab48bcda979510c6b3..44e8fce30c88946cb2aded6d57d6da7d503bf86b 100644 (file)
@@ -520,6 +520,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);
index 40f13b713b75a0d9f5a6fe33889feef578acceb0..d3dbb2f84297dc4b053133fbb853149d514169c2 100644 (file)
@@ -1666,6 +1666,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,
index 261ee695499c63957a6db738d6b4f48f71965f91..806ad7a0a994e481c532db05e3f23d9b632ff832 100644 (file)
@@ -1628,6 +1628,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.