mirror of
https://github.com/ceph/ceph
synced 2025-02-24 03:27:10 +00:00
Merge pull request #15440 from ukernel/wip-20170
mds: multimds flock fixes Reviewed-by: John Spray <john.spray@redhat.com>
This commit is contained in:
commit
3d9a0a577b
@ -2763,11 +2763,19 @@ void Client::kick_requests(MetaSession *session)
|
||||
for (map<ceph_tid_t, MetaRequest*>::iterator p = mds_requests.begin();
|
||||
p != mds_requests.end();
|
||||
++p) {
|
||||
if (p->second->got_unsafe)
|
||||
MetaRequest *req = p->second;
|
||||
if (req->got_unsafe)
|
||||
continue;
|
||||
if (p->second->retry_attempt > 0)
|
||||
if (req->aborted()) {
|
||||
if (req->caller_cond) {
|
||||
req->kick = true;
|
||||
req->caller_cond->Signal();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (req->retry_attempt > 0)
|
||||
continue; // new requests only
|
||||
if (p->second->mds == session->mds_num) {
|
||||
if (req->mds == session->mds_num) {
|
||||
send_request(p->second, session);
|
||||
}
|
||||
}
|
||||
@ -2788,6 +2796,8 @@ void Client::resend_unsafe_requests(MetaSession *session)
|
||||
MetaRequest *req = p->second;
|
||||
if (req->got_unsafe)
|
||||
continue;
|
||||
if (req->aborted())
|
||||
continue;
|
||||
if (req->retry_attempt == 0)
|
||||
continue; // old requests only
|
||||
if (req->mds == session->mds_num)
|
||||
@ -9511,9 +9521,12 @@ int Client::_do_filelock(Inode *in, Fh *fh, int lock_type, int op, int sleep,
|
||||
// enable interrupt
|
||||
switch_interrupt_cb(callback_handle, req->get());
|
||||
ret = make_request(req, fh->actor_perms, NULL, NULL, -1, &bl);
|
||||
|
||||
// disable interrupt
|
||||
switch_interrupt_cb(callback_handle, NULL);
|
||||
if (ret == 0 && req->aborted()) {
|
||||
// effect of this lock request has been revoked by the 'lock intr' request
|
||||
ret = req->get_abort_code();
|
||||
}
|
||||
put_request(req);
|
||||
} else {
|
||||
ret = make_request(req, fh->actor_perms, NULL, NULL, -1, &bl);
|
||||
@ -9572,6 +9585,12 @@ int Client::_do_filelock(Inode *in, Fh *fh, int lock_type, int op, int sleep,
|
||||
|
||||
int Client::_interrupt_filelock(MetaRequest *req)
|
||||
{
|
||||
// Set abort code, but do not kick. The abort code prevents the request
|
||||
// from being re-sent.
|
||||
req->abort(-EINTR);
|
||||
if (req->mds < 0)
|
||||
return 0; // haven't sent the request
|
||||
|
||||
Inode *in = req->inode();
|
||||
|
||||
int lock_type;
|
||||
|
@ -2270,6 +2270,7 @@ void Locker::calc_new_client_ranges(CInode *in, uint64_t size,
|
||||
nr.range.last = MAX(ms, oldr.range.last);
|
||||
nr.follows = oldr.follows;
|
||||
} else {
|
||||
*max_increased = true;
|
||||
nr.range.last = ms;
|
||||
nr.follows = in->first - 1;
|
||||
}
|
||||
|
@ -10,20 +10,25 @@
|
||||
|
||||
static multimap<ceph_filelock, ceph_lock_state_t*> global_waiting_locks;
|
||||
|
||||
static void remove_global_waiting(ceph_filelock &fl, ceph_lock_state_t *lock_state)
|
||||
{
|
||||
for (auto p = global_waiting_locks.find(fl);
|
||||
p != global_waiting_locks.end(); ) {
|
||||
if (p->first != fl)
|
||||
break;
|
||||
if (p->second == lock_state) {
|
||||
global_waiting_locks.erase(p);
|
||||
break;
|
||||
}
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
ceph_lock_state_t::~ceph_lock_state_t()
|
||||
{
|
||||
if (type == CEPH_LOCK_FCNTL) {
|
||||
for (auto p = waiting_locks.begin(); p != waiting_locks.end(); ++p) {
|
||||
for (auto q = global_waiting_locks.find(p->second);
|
||||
q != global_waiting_locks.end(); ) {
|
||||
if (q->first != p->second)
|
||||
break;
|
||||
if (q->second == this) {
|
||||
global_waiting_locks.erase(q);
|
||||
break;
|
||||
}
|
||||
++q;
|
||||
}
|
||||
remove_global_waiting(p->second, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -50,6 +55,9 @@ void ceph_lock_state_t::remove_waiting(const ceph_filelock& fl)
|
||||
break;
|
||||
if (p->second.length == fl.length &&
|
||||
ceph_filelock_owner_equal(p->second, fl)) {
|
||||
if (type == CEPH_LOCK_FCNTL) {
|
||||
remove_global_waiting(p->second, this);
|
||||
}
|
||||
waiting_locks.erase(p);
|
||||
--client_waiting_lock_counts[(client_t)fl.client];
|
||||
if (!client_waiting_lock_counts[(client_t)fl.client]) {
|
||||
@ -59,19 +67,6 @@ void ceph_lock_state_t::remove_waiting(const ceph_filelock& fl)
|
||||
}
|
||||
++p;
|
||||
}
|
||||
|
||||
if (type == CEPH_LOCK_FCNTL) {
|
||||
for (auto q = global_waiting_locks.find(fl);
|
||||
q != global_waiting_locks.end(); ) {
|
||||
if (q->first != fl)
|
||||
break;
|
||||
if (q->second == this) {
|
||||
global_waiting_locks.erase(q);
|
||||
break;
|
||||
}
|
||||
++q;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ceph_lock_state_t::is_deadlock(const ceph_filelock& fl,
|
||||
@ -141,6 +136,7 @@ bool ceph_lock_state_t::is_deadlock(const ceph_filelock& fl,
|
||||
void ceph_lock_state_t::add_waiting(const ceph_filelock& fl)
|
||||
{
|
||||
waiting_locks.insert(pair<uint64_t, ceph_filelock>(fl.start, fl));
|
||||
++client_waiting_lock_counts[(client_t)fl.client];
|
||||
if (type == CEPH_LOCK_FCNTL) {
|
||||
global_waiting_locks.insert(pair<ceph_filelock,ceph_lock_state_t*>(fl, this));
|
||||
}
|
||||
@ -200,8 +196,6 @@ bool ceph_lock_state_t::add_lock(ceph_filelock& new_lock,
|
||||
if (ret) {
|
||||
++client_held_lock_counts[(client_t)new_lock.client];
|
||||
}
|
||||
else if (wait_on_fail && !replay)
|
||||
++client_waiting_lock_counts[(client_t)new_lock.client];
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -320,16 +314,8 @@ bool ceph_lock_state_t::remove_all_from (client_t client)
|
||||
++iter;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto p = global_waiting_locks.find(iter->second);
|
||||
p != global_waiting_locks.end(); ) {
|
||||
if (p->first != iter->second)
|
||||
break;
|
||||
if (p->second == this) {
|
||||
global_waiting_locks.erase(p);
|
||||
break;
|
||||
}
|
||||
++p;
|
||||
if (type == CEPH_LOCK_FCNTL) {
|
||||
remove_global_waiting(iter->second, this);
|
||||
}
|
||||
waiting_locks.erase(iter++);
|
||||
}
|
||||
|
@ -252,21 +252,11 @@ private:
|
||||
public:
|
||||
void encode(bufferlist& bl) const {
|
||||
::encode(held_locks, bl);
|
||||
::encode(waiting_locks, bl);
|
||||
::encode(client_held_lock_counts, bl);
|
||||
::encode(client_waiting_lock_counts, bl);
|
||||
}
|
||||
void decode(bufferlist::iterator& bl) {
|
||||
::decode(held_locks, bl);
|
||||
::decode(waiting_locks, bl);
|
||||
::decode(client_held_lock_counts, bl);
|
||||
::decode(client_waiting_lock_counts, bl);
|
||||
}
|
||||
void clear() {
|
||||
held_locks.clear();
|
||||
waiting_locks.clear();
|
||||
client_held_lock_counts.clear();
|
||||
client_waiting_lock_counts.clear();
|
||||
}
|
||||
bool empty() const {
|
||||
return held_locks.empty() && waiting_locks.empty() &&
|
||||
|
Loading…
Reference in New Issue
Block a user