From 7b8a86f105f66eb0d39b6c4920a722eedd88fedd Mon Sep 17 00:00:00 2001 From: Igor Fedotov Date: Thu, 12 Dec 2024 08:29:17 +0300 Subject: [PATCH] libcephfs/client: pin inode/dentry for an opened directory Fixes: https://tracker.ceph.com/issues/69092 Signed-off-by: Igor Fedotov --- src/client/Client.cc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index c404057b929..eb35485cc7e 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -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); -- 2.47.3