From: Igor Fedotov Date: Thu, 12 Dec 2024 05:29:17 +0000 (+0300) Subject: libcephfs/client: pin inode/dentry for an opened directory X-Git-Tag: v20.0.0~197^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7b8a86f105f66eb0d39b6c4920a722eedd88fedd;p=ceph.git libcephfs/client: pin inode/dentry for an opened directory Fixes: https://tracker.ceph.com/issues/69092 Signed-off-by: Igor Fedotov --- diff --git a/src/client/Client.cc b/src/client/Client.cc index c404057b929d..eb35485cc7ea 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);