]> 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)
committerNathan Cutler <ncutler@suse.com>
Wed, 12 May 2021 09:03:53 +0000 (11:03 +0200)
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)

Conflicts:
src/client/Client.cc

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

index 07fe47940ea87460aa4061afcb33a9fd45fe37bb..abfc49434ac5bc2500d895e92c36cc01ceae2ed1 100755 (executable)
@@ -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<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);
+
+  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 5914029925ed97fcf6e5cb5c7daa594d012519d5..91e93e61aa9620efa16d083a64f5c58caa3f65b5 100644 (file)
@@ -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);
index 1608ac7cf9b38e3db66e503e8995727bd58944ba..1ef73921d51d7dffc09639e42f59ec6c57899dec 100755 (executable)
@@ -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,
index 6d18556449465dd2de231e34acbff961edace5c9..243549ed121023f6a75bd0f6dec1180ee63dd13e 100755 (executable)
@@ -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.