From d78235be1b5c20440f3a55abb3f4b980aa3f3596 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 17 Jul 2012 19:19:39 -0700 Subject: [PATCH] client: fix readdir locking Several of the readdir-related methods were not taking client_lock. Fixes: #1737 Backport: argonaut Signed-off-by: Sage Weil --- src/client/Client.cc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index b5e44b8fae5c6..633ee3ad81c42 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -4188,6 +4188,8 @@ void Client::_closedir(dir_result_t *dirp) void Client::rewinddir(dir_result_t *dirp) { + Mutex::Locker lock(client_lock); + ldout(cct, 3) << "rewinddir(" << dirp << ")" << dendl; dir_result_t *d = (dir_result_t*)dirp; _readdir_drop_dirp_buffer(d); @@ -4203,6 +4205,8 @@ loff_t Client::telldir(dir_result_t *dirp) void Client::seekdir(dir_result_t *dirp, loff_t offset) { + Mutex::Locker lock(client_lock); + ldout(cct, 3) << "seekdir(" << dirp << ", " << offset << ")" << dendl; dir_result_t *d = (dir_result_t*)dirp; @@ -4357,6 +4361,7 @@ int Client::_readdir_get_frag(dir_result_t *dirp) int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p) { + assert(client_lock.is_locked()); ldout(cct, 10) << "_readdir_cache_cb " << dirp << " on " << dirp->inode->ino << " at_cache_name " << dirp->at_cache_name << " offset " << hex << dirp->offset << dec << dendl; @@ -4397,7 +4402,9 @@ int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p) if (pd == dir->dentry_map.end()) next_off = dir_result_t::END; + client_lock.Unlock(); int r = cb(p, &de, &st, stmask, next_off); // _next_ offset + client_lock.Lock(); ldout(cct, 15) << " de " << de.d_name << " off " << hex << dn->offset << dec << " = " << r << dendl; @@ -4418,6 +4425,8 @@ int Client::_readdir_cache_cb(dir_result_t *dirp, add_dirent_cb_t cb, void *p) int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p) { + Mutex::Locker lock(client_lock); + dir_result_t *dirp = (dir_result_t*)d; ldout(cct, 10) << "readdir_r_cb " << *dirp->inode << " offset " << hex << dirp->offset << dec @@ -4447,7 +4456,9 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p) fill_stat(diri, &st); + client_lock.Unlock(); int r = cb(p, &de, &st, -1, next_off); + client_lock.Lock(); if (r < 0) return r; @@ -4462,7 +4473,9 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p) fill_stat(in, &st); + client_lock.Unlock(); int r = cb(p, &de, &st, -1, 2); + client_lock.Lock(); if (r < 0) return r; @@ -4493,7 +4506,6 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p) return 0; if (dirp->buffer_frag != dirp->frag() || dirp->buffer == NULL) { - Mutex::Locker lock(client_lock); int r = _readdir_get_frag(dirp); if (r) return r; @@ -4510,7 +4522,9 @@ int Client::readdir_r_cb(dir_result_t *d, add_dirent_cb_t cb, void *p) int stmask = fill_stat(ent.second, &st); fill_dirent(&de, ent.first.c_str(), st.st_mode, st.st_ino, dirp->offset + 1); + client_lock.Unlock(); int r = cb(p, &de, &st, stmask, dirp->offset + 1); // _next_ offset + client_lock.Lock(); ldout(cct, 15) << " de " << de.d_name << " off " << hex << dirp->offset << dec << " = " << r << dendl; -- 2.39.5