From 8fc1b1b095fc564e1f7380b64e730f5399d95b58 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Wed, 9 Mar 2016 12:04:59 +0800 Subject: [PATCH 1/2] client: close opened dirs when umounting Fixes: #14996 Signed-off-by: Yan, Zheng --- src/client/Client.cc | 22 +++++++++++++++------- src/client/Client.h | 3 +++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 31f31f86e99..67b6d74b313 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -337,6 +337,12 @@ void Client::tear_down_cache() } fd_map.clear(); + while (!opened_dirs.empty()) { + dir_result_t *dirp = *opened_dirs.begin(); + ldout(cct, 1) << "tear_down_cache forcing close of dir " << dirp << " ino " << dirp->inode->ino << dendl; + _closedir(dirp); + } + // caps! // *** FIXME *** @@ -5486,6 +5492,12 @@ void Client::unmount() _release_fh(fh); } + while (!opened_dirs.empty()) { + dir_result_t *dirp = *opened_dirs.begin(); + ldout(cct, 0) << " destroyed lost open dir " << dirp << " on " << *dirp->inode << dendl; + _closedir(dirp); + } + _ll_drop_pins(); while (unsafe_sync_write > 0) { @@ -6691,6 +6703,7 @@ int Client::_opendir(Inode *in, dir_result_t **dirpp, int uid, int gid) if (!in->is_dir()) return -ENOTDIR; *dirpp = new dir_result_t(in); + opened_dirs.insert(*dirpp); if (in->dir) { (*dirpp)->release_count = in->dir->release_count; (*dirpp)->ordered_count = in->dir->ordered_count; @@ -6723,6 +6736,7 @@ void Client::_closedir(dir_result_t *dirp) dirp->inode.reset(); } _readdir_drop_dirp_buffer(dirp); + opened_dirs.erase(dirp); delete dirp; } @@ -10974,13 +10988,7 @@ int Client::ll_opendir(Inode *in, int flags, dir_result_t** dirpp, return r; } - int r = 0; - if (vino.snapid == CEPH_SNAPDIR) { - *dirpp = new dir_result_t(in); - } else { - r = _opendir(in, dirpp, uid, gid); - } - + int r = _opendir(in, dirpp, uid, gid); tout(cct) << (unsigned long)*dirpp << std::endl; ldout(cct, 3) << "ll_opendir " << vino << " = " << r << " (" << *dirpp << ")" diff --git a/src/client/Client.h b/src/client/Client.h index 74752bf005b..40a97af8884 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -30,6 +30,7 @@ using std::set; using std::map; using std::fstream; +#include "include/unordered_set.h" #include "include/unordered_map.h" #include "include/filepath.h" @@ -421,6 +422,8 @@ protected: // file handles, etc. interval_set free_fd_set; // unused fds ceph::unordered_map fd_map; + + ceph::unordered_set opened_dirs; int get_fd() { int fd = free_fd_set.range_start(); From 9e3441733c3deba16a9dffbba0e5ab095b858f95 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Wed, 9 Mar 2016 12:06:52 +0800 Subject: [PATCH 2/2] ceph_test_libcephfs: shutdown without closing file/dir Signed-off-by: Yan, Zheng --- src/test/libcephfs/test.cc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc index 464c5a96645..06061a6f24e 100644 --- a/src/test/libcephfs/test.cc +++ b/src/test/libcephfs/test.cc @@ -1321,3 +1321,26 @@ TEST(LibCephFS, GetOsdAddr) { ceph_shutdown(cmount); } + +TEST(LibCephFS, OpenNoClose) { + struct ceph_mount_info *cmount; + ASSERT_EQ(ceph_create(&cmount, NULL), 0); + ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0); + ASSERT_EQ(0, ceph_conf_parse_env(cmount, NULL)); + ASSERT_EQ(ceph_mount(cmount, "/"), 0); + + pid_t mypid = getpid(); + char str_buf[256]; + sprintf(str_buf, "open_no_close_dir%d", mypid); + ASSERT_EQ(0, ceph_mkdirs(cmount, str_buf, 0777)); + + struct ceph_dir_result *ls_dir = NULL; + ASSERT_EQ(ceph_opendir(cmount, str_buf, &ls_dir), 0); + + sprintf(str_buf, "open_no_close_file%d", mypid); + int fd = ceph_open(cmount, str_buf, O_RDONLY|O_CREAT, 0666); + ASSERT_LT(0, fd); + + // shutdown should force close opened file/dir + ceph_shutdown(cmount); +}