mirror of
https://github.com/ceph/ceph
synced 2025-03-19 17:06:24 +00:00
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:
commit
d783e96775
@ -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 << ")"
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user