Merge pull request #7994 from ukernel/jewel-14996

Merge: Fix client handling of "lost" open directories on shutdown

Reviewed-by: Greg Farnum <gfarnum@redhat.com>
This commit is contained in:
Gregory Farnum 2016-03-09 22:43:04 -08:00
commit d783e96775
3 changed files with 41 additions and 7 deletions

View File

@ -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 << ")"

View File

@ -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<int> free_fd_set; // unused fds
ceph::unordered_map<int, Fh*> fd_map;
ceph::unordered_set<dir_result_t*> opened_dirs;
int get_fd() {
int fd = free_fd_set.range_start();

View File

@ -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);
}