]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
libcephfs/client: pin inode/dentry for an opened directory
authorIgor Fedotov <igor.fedotov@croit.io>
Thu, 12 Dec 2024 05:29:17 +0000 (08:29 +0300)
committerIgor Fedotov <igor.fedotov@croit.io>
Mon, 27 Jan 2025 08:07:27 +0000 (11:07 +0300)
Fixes: https://tracker.ceph.com/issues/69092
Signed-off-by: Igor Fedotov <igor.fedotov@croit.io>
src/client/Client.cc

index c404057b929d7f2f6e6f7c534d1ef3ff356fb219..eb35485cc7ead5201b023f99c99330d870080762 100644 (file)
@@ -10431,8 +10431,17 @@ int Client::_open(Inode *in, int flags, mode_t mode, Fh **fhp,
 
   // success?
   if (result >= 0) {
-    if (fhp)
+    if (fhp) {
       *fhp = _create_fh(in, flags, cmode, perms);
+      // ceph_flags_sys2wire/ceph_flags_to_mode() calls above transforms O_DIRECTORY flag
+      // into CEPH_FILE_MODE_PIN mode. Although this mode is used at server size
+      // we [ab]use it here to determine whether we should pin inode to prevent from
+      // undesired cache eviction.
+      if (cmode == CEPH_FILE_MODE_PIN) {
+        ldout(cct, 20) << " pinning ll_get() call for " << *in << dendl;
+        _ll_get(in);
+      }
+    }
   } else {
     in->put_open_ref(cmode);
   }
@@ -10489,6 +10498,10 @@ int Client::_close(int fd)
   Fh *fh = get_filehandle(fd);
   if (!fh)
     return -CEPHFS_EBADF;
+  if (fh->mode == CEPH_FILE_MODE_PIN) {
+    ldout(cct, 20) << " unpinning ll_put() call for " << *(fh->inode.get()) << dendl;
+    _ll_put(fh->inode.get(), 1);
+  }
   int err = _release_fh(fh);
   fd_map.erase(fd);
   put_fd(fd);