From: Sage Weil Date: Tue, 20 Jan 2009 01:02:02 +0000 (-0800) Subject: mds: count in-flight updates per cap, not release attempts. do not expire if updating. X-Git-Tag: v0.6~1^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=26cec48ebb7aad0df3f3d7fa743d7246dfae5e03;p=ceph.git mds: count in-flight updates per cap, not release attempts. do not expire if updating. --- diff --git a/src/mds/Capability.h b/src/mds/Capability.h index 92c5a4fa301c..f8c9a9571440 100644 --- a/src/mds/Capability.h +++ b/src/mds/Capability.h @@ -205,7 +205,7 @@ private: bool stale; public: - int releasing; // only allow a single in-progress release (it may be waiting for log to flush) + int updating; // do not release or expire until all updates commit snapid_t client_follows; version_t client_xattr_version; @@ -222,7 +222,7 @@ public: _pending(0), _issued(0), _num_revoke(0), last_sent(0), mseq(0), - suppress(0), stale(false), releasing(0), + suppress(0), stale(false), updating(0), client_follows(0), client_xattr_version(0), session_caps_item(this), rdcaps_list(rl), rdcaps_item(this), snaprealm_caps_item(this) { } @@ -257,6 +257,10 @@ public: _wanted = w; } + bool can_expire() { + return updating == 0; + } + ceph_seq_t get_last_seq() { return last_sent; } diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 8556b2b52093..b3bea2d9ab29 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -857,20 +857,23 @@ struct C_Locker_FileUpdate_finish : public Context { Mutation *mut; bool share; int client; + Capability *cap; MClientCaps *ack; ceph_seq_t releasecap; C_Locker_FileUpdate_finish(Locker *l, CInode *i, Mutation *m, bool e=false, int c=-1, + Capability *cp = 0, MClientCaps *ac = 0, ceph_seq_t rc=0) : - locker(l), in(i), mut(m), share(e), client(c), + locker(l), in(i), mut(m), share(e), client(c), cap(cp), ack(ac), releasecap(rc) { in->get(CInode::PIN_PTRWAITER); } void finish(int r) { - locker->file_update_finish(in, mut, share, client, ack, releasecap); + locker->file_update_finish(in, mut, share, client, cap, ack, releasecap); } }; void Locker::file_update_finish(CInode *in, Mutation *mut, bool share, int client, + Capability *cap, MClientCaps *ack, ceph_seq_t releasecap) { dout(10) << "file_update_finish on " << *in << dendl; @@ -879,6 +882,9 @@ void Locker::file_update_finish(CInode *in, Mutation *mut, bool share, int clien mut->apply(); + if (cap) + cap->updating--; + if (releasecap) { assert(ack); _finish_release_cap(in, client, releasecap, ack); @@ -1440,7 +1446,7 @@ void Locker::handle_client_caps(MClientCaps *m) ack = new MClientCaps(CEPH_CAP_OP_FLUSHSNAP_ACK, in->ino(), 0, 0, 0, 0, m->get_dirty(), 0); ack->set_snap_follows(follows); } - if (!_do_cap_update(in, m->get_dirty(), 0, follows, m, ack)) { + if (!_do_cap_update(in, cap, m->get_dirty(), 0, follows, m, ack)) { if (ack) mds->send_message_client(ack, client); eval_cap_gather(in); @@ -1475,7 +1481,6 @@ void Locker::handle_client_caps(MClientCaps *m) assert(ceph_seq_cmp(m->get_seq(), cap->get_last_sent()) <= 0); if (m->get_seq() == cap->get_last_sent()) { dout(7) << " releasing request client" << client << " seq " << m->get_seq() << " on " << *in << dendl; - cap->releasing++; releasecap = m->get_seq(); } else { dout(7) << " NOT releasing request client" << client << " seq " << m->get_seq() @@ -1488,7 +1493,7 @@ void Locker::handle_client_caps(MClientCaps *m) cap->set_wanted(wanted); } - if (!_do_cap_update(in, m->get_dirty(), m->get_wanted(), follows, m, ack, releasecap)) { + if (!_do_cap_update(in, cap, m->get_dirty(), m->get_wanted(), follows, m, ack, releasecap)) { // no update, ack now. if (releasecap) _finish_release_cap(in, client, releasecap, ack); @@ -1525,9 +1530,8 @@ void Locker::_finish_release_cap(CInode *in, int client, ceph_seq_t seq, MClient // _still_ the most recent (and not racing with open() or // something) - cap->releasing--; - if (cap->releasing) { - dout(10) << " another release attempt in flight, not releasing yet" << dendl; + if (cap->updating) { + dout(10) << " another update attempt in flight, not releasing yet" << dendl; delete ack; } else if (ceph_seq_cmp(seq, cap->get_last_sent()) < 0) { dout(10) << " NOT releasing cap client" << client << ", last_sent " << cap->get_last_sent() @@ -1556,7 +1560,8 @@ void Locker::_finish_release_cap(CInode *in, int client, ceph_seq_t seq, MClient * adjust max_size, if needed. * if we update, return true; otherwise, false (no updated needed). */ -bool Locker::_do_cap_update(CInode *in, int dirty, int wanted, snapid_t follows, MClientCaps *m, +bool Locker::_do_cap_update(CInode *in, Capability *cap, + int dirty, int wanted, snapid_t follows, MClientCaps *m, MClientCaps *ack, ceph_seq_t releasecap) { dout(10) << "_do_cap_update dirty " << ccap_string(dirty) @@ -1686,10 +1691,12 @@ bool Locker::_do_cap_update(CInode *in, int dirty, int wanted, snapid_t follows, mut->auth_pin(in); mdcache->predirty_journal_parents(mut, &le->metablob, in, 0, PREDIRTY_PRIMARY, 0, follows); mdcache->journal_dirty_inode(mut, &le->metablob, in, follows); + + cap->updating++; mds->mdlog->submit_entry(le); mds->mdlog->wait_for_sync(new C_Locker_FileUpdate_finish(this, in, mut, change_max, - client, ack, releasecap)); + client, cap, ack, releasecap)); // only flush immediately if the lock is unstable if (!in->filelock.is_stable()) mds->mdlog->flush(); diff --git a/src/mds/Locker.h b/src/mds/Locker.h index 84a27104707c..b16248a1ed95 100644 --- a/src/mds/Locker.h +++ b/src/mds/Locker.h @@ -183,7 +183,7 @@ public: protected: void handle_client_caps(class MClientCaps *m); - bool _do_cap_update(CInode *in, int had, int wanted, snapid_t follows, MClientCaps *m, + bool _do_cap_update(CInode *in, Capability *cap, int had, int wanted, snapid_t follows, MClientCaps *m, MClientCaps *ack=0, ceph_seq_t releasecap=0); void _finish_release_cap(CInode *in, int client, ceph_seq_t seq, MClientCaps *ack); @@ -191,7 +191,7 @@ public: void request_inode_file_caps(CInode *in); void handle_inode_file_caps(class MInodeFileCaps *m); - void file_update_finish(CInode *in, Mutation *mut, bool share, int client, + void file_update_finish(CInode *in, Mutation *mut, bool share, int client, Capability *cap, MClientCaps *ack, ceph_seq_t releasecap); public: bool check_inode_max_size(CInode *in, bool force_wrlock=false, bool update_size=false, __u64 newsize=0); diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 6f5260dbba81..9511838e9be6 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -4825,6 +4825,12 @@ void MDCache::trim_client_rdcaps() << " on " << *in << dendl; continue; } + if (!cap->can_expire()) { + dout(20) << " skipping client" << client + << " stamp " << cap->get_last_issue_stamp() + << " (can't expire) on " << *in << dendl; + continue; + } if (cap->get_last_issue_stamp() > cutoff) { dout(20) << " stopping at client" << client << " stamp " << cap->get_last_issue_stamp() << " > cutoff " << cutoff