]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: count in-flight updates per cap, not release attempts. do not expire if updating.
authorSage Weil <sage@newdream.net>
Tue, 20 Jan 2009 01:02:02 +0000 (17:02 -0800)
committerSage Weil <sage@newdream.net>
Tue, 20 Jan 2009 01:02:02 +0000 (17:02 -0800)
src/mds/Capability.h
src/mds/Locker.cc
src/mds/Locker.h
src/mds/MDCache.cc

index 92c5a4fa301cc7ae8c62bb34a7704a59cc2fa612..f8c9a9571440cffac59181ab47173a6632dd15fa 100644 (file)
@@ -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; }
 
 
index 8556b2b52093fcf2a6e1708a7d041ff41040ab85..b3bea2d9ab2954c5362225c8e134bd829733d8a6 100644 (file)
@@ -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();
index 84a27104707cc65091ce4c8494131b7db163cbcd..b16248a1ed95aeccf8976c6bd45fe33fe8e858a6 100644 (file)
@@ -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);
index 6f5260dbba8140dea345dfcd71ce384a6744b941..9511838e9be660c65839c5b3988fc48de94ae1e1 100644 (file)
@@ -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