From b87f3cafe006616d325053fc81c7e6432f7e9750 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Tue, 5 Nov 2019 11:42:58 +0800 Subject: [PATCH] client: -EIO on filelock operations if inode has lost filelocks Signed-off-by: "Yan, Zheng" --- src/client/Client.cc | 38 ++++++++++++++++++++++++++------------ src/client/Inode.h | 17 ++++++++++++----- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index b8a67c1ce18..5294759ef99 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -4133,6 +4133,8 @@ void Client::remove_session_caps(MetaSession *s, int err) dirty_caps = in->dirty_caps | in->flushing_caps; in->wanted_max_size = 0; in->requested_max_size = 0; + if (in->has_any_filelocks()) + in->flags |= I_ERROR_FILELOCK; } auto caps = cap->implemented; if (cap->wanted | cap->issued) @@ -10112,6 +10114,9 @@ int Client::_do_filelock(Inode *in, Fh *fh, int lock_type, int op, int sleep, << " type " << fl->l_type << " owner " << owner << " " << fl->l_start << "~" << fl->l_len << dendl; + if (in->flags & I_ERROR_FILELOCK) + return -EIO; + int lock_cmd; if (F_RDLCK == fl->l_type) lock_cmd = CEPH_LOCK_SHARED; @@ -10285,30 +10290,39 @@ void Client::_release_filelocks(Fh *fh) Inode *in = fh->inode.get(); ldout(cct, 10) << __func__ << " " << fh << " ino " << in->ino << dendl; + list activated_locks; + list > to_release; if (fh->fcntl_locks) { auto &lock_state = fh->fcntl_locks; - for(multimap::iterator p = lock_state->held_locks.begin(); - p != lock_state->held_locks.end(); - ++p) - to_release.push_back(pair(CEPH_LOCK_FCNTL, p->second)); + for(auto p = lock_state->held_locks.begin(); p != lock_state->held_locks.end(); ) { + auto q = p++; + if (in->flags & I_ERROR_FILELOCK) { + lock_state->remove_lock(q->second, activated_locks); + } else { + to_release.push_back(pair(CEPH_LOCK_FCNTL, q->second)); + } + } lock_state.reset(); } if (fh->flock_locks) { auto &lock_state = fh->flock_locks; - for(multimap::iterator p = lock_state->held_locks.begin(); - p != lock_state->held_locks.end(); - ++p) - to_release.push_back(pair(CEPH_LOCK_FLOCK, p->second)); + for(auto p = lock_state->held_locks.begin(); p != lock_state->held_locks.end(); ) { + auto q = p++; + if (in->flags & I_ERROR_FILELOCK) { + lock_state->remove_lock(q->second, activated_locks); + } else { + to_release.push_back(pair(CEPH_LOCK_FLOCK, q->second)); + } + } lock_state.reset(); } - if (to_release.empty()) - return; + if ((in->flags & I_ERROR_FILELOCK) && !in->has_any_filelocks()) + in->flags &= ~I_ERROR_FILELOCK; - // mds has already released filelocks if session was closed. - if (in->caps.empty()) + if (to_release.empty()) return; struct flock fl; diff --git a/src/client/Inode.h b/src/client/Inode.h index 42dbddc97ec..afaf64e0515 100644 --- a/src/client/Inode.h +++ b/src/client/Inode.h @@ -109,11 +109,12 @@ struct CapSnap { }; // inode flags -#define I_COMPLETE 1 -#define I_DIR_ORDERED 2 -#define I_CAP_DROPPED 4 -#define I_SNAPDIR_OPEN 8 -#define I_KICK_FLUSH 16 +#define I_COMPLETE (1 << 0) +#define I_DIR_ORDERED (1 << 1) +#define I_SNAPDIR_OPEN (1 << 2) +#define I_KICK_FLUSH (1 << 3) +#define I_CAP_DROPPED (1 << 4) +#define I_ERROR_FILELOCK (1 << 5) struct Inode { Client *client; @@ -258,6 +259,12 @@ struct Inode { std::unique_ptr fcntl_locks; std::unique_ptr flock_locks; + bool has_any_filelocks() { + return + (fcntl_locks && !fcntl_locks->empty()) || + (flock_locks && !flock_locks->empty()); + } + list delegations; xlist unsafe_ops; -- 2.39.5