]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: issue caps in file_eval only if needed, indicated by WANTED cap op
authorSage Weil <sage@newdream.net>
Thu, 9 Apr 2009 20:21:34 +0000 (13:21 -0700)
committerSage Weil <sage@newdream.net>
Thu, 9 Apr 2009 20:21:34 +0000 (13:21 -0700)
We can't always issue_caps in file_eval or cap releases won't work.

Sometimes the client wanted shrink is missed, though, and a wanted
expansion is sent that doesn't actually change wanted.  In those
cases, we DO need to issue caps.  Use a separate cap op WANTED so
the mds knows when the client is asking for caps.

src/include/ceph_fs.h
src/kernel/caps.c
src/mds/Locker.cc
src/mds/Locker.h

index 5f8a5ba392221e8d2ba59f73a4bcbce58ea5d78a..e57e85b8039146b0af05215d2e5d1c94ceafe4f8 100644 (file)
@@ -1015,6 +1015,7 @@ enum {
        CEPH_CAP_OP_EXPORT,    /* mds has exported the cap */
        CEPH_CAP_OP_IMPORT,    /* mds has imported the cap from specified mds */
        CEPH_CAP_OP_UPDATE,    /* client->mds update */
+       CEPH_CAP_OP_WANT,      /* client->mds wanted update */
        CEPH_CAP_OP_FLUSH_ACK, /* mds->client flushed.  if caps=0, cap also released. */
        CEPH_CAP_OP_FLUSHSNAP, /* client->mds flush snapped metadata */
        CEPH_CAP_OP_FLUSHSNAP_ACK, /* mds->client flushed snapped metadata */
@@ -1031,6 +1032,7 @@ static inline const char *ceph_cap_op_name(int op)
        case CEPH_CAP_OP_EXPORT: return "export";
        case CEPH_CAP_OP_IMPORT: return "import";
        case CEPH_CAP_OP_UPDATE: return "update";
+       case CEPH_CAP_OP_WANT: return "want";
        case CEPH_CAP_OP_FLUSH_ACK: return "flush_ack";
        case CEPH_CAP_OP_FLUSHSNAP: return "flushsnap";
        case CEPH_CAP_OP_FLUSHSNAP_ACK: return "flushsnap_ack";
index b02005b9e9410e4fa71b47b5f3e72773c7642706..b0f2da8386fa03ba78af7813fede1cca8bee7dd2 100644 (file)
@@ -1012,6 +1012,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int is_delayed, int drop,
                           to avoid an infinite loop on retry */
        struct rb_node *p;
        int tried_invalidate = 0;
+       int op;
 
        /* if we are unmounting, flush any unused caps immediately. */
        if (mdsc->stopping)
@@ -1188,11 +1189,15 @@ ack:
                if (drop)
                        want = cap->mds_wanted; 
 
+               if (want & ~cap->mds_wanted)
+                       op = CEPH_CAP_OP_WANT;
+               else
+                       op = CEPH_CAP_OP_UPDATE;
+
                mds = cap->mds;  /* remember mds, so we don't repeat */
 
                /* __send_cap drops i_lock */
-               __send_cap(mdsc, cap, CEPH_CAP_OP_UPDATE, used, want, retain,
-                          flushing);
+               __send_cap(mdsc, cap, op, used, want, retain, flushing);
 
                goto retry; /* retake i_lock and restart our cap scan. */
        }
index 793fd7210030f9765a6001544ccac5bdffc85804..baae25fc84c6589c8a8649264f3b4d7ba290796f 100644 (file)
@@ -1466,6 +1466,7 @@ void Locker::handle_client_caps(MClientCaps *m)
   }
 
   int op = m->get_op();
+  bool do_issue = false;
 
   if (op == CEPH_CAP_OP_RENEW) {
     if (cap->touch()) {
@@ -1556,6 +1557,8 @@ void Locker::handle_client_caps(MClientCaps *m)
                   << " (seq " << m->get_seq() << " != last_issue " << cap->get_last_issue() << ")" << dendl;
        }
       }
+      if (m->get_op() == CEPH_CAP_OP_WANT && (wanted & ~cap->pending()))
+       do_issue = true;
       
       if (!_do_cap_update(in, cap, m->get_dirty(), m->get_wanted(), follows, m, ack)) {
        // no update, ack now.
@@ -1565,7 +1568,7 @@ void Locker::handle_client_caps(MClientCaps *m)
        
       eval_cap_gather(in);
       if (in->filelock.is_stable())
-       file_eval(&in->filelock);
+       file_eval(&in->filelock, do_issue);
       if (in->authlock.is_stable())
        eval(&in->authlock);
     }
@@ -2861,7 +2864,7 @@ void Locker::try_file_eval(ScatterLock *lock)
 
 
 
-void Locker::file_eval(ScatterLock *lock)
+void Locker::file_eval(ScatterLock *lock, bool do_issue)
 {
   CInode *in = (CInode*)lock->get_parent();
   int loner_wanted, other_wanted;
@@ -2893,7 +2896,6 @@ void Locker::file_eval(ScatterLock *lock)
          file_mixed(lock);
        else
          simple_sync(lock);
-       return;
       }
     }    
   }
@@ -2908,7 +2910,6 @@ void Locker::file_eval(ScatterLock *lock)
     dout(7) << "file_eval stable, bump to loner " << *lock
            << " on " << *lock->get_parent() << dendl;
     file_excl(lock);
-    return;
   }
 
   // * -> mixed?
@@ -2920,7 +2921,6 @@ void Locker::file_eval(ScatterLock *lock)
     dout(7) << "file_eval stable, bump to mixed " << *lock
            << " on " << *lock->get_parent() << dendl;
     file_mixed(lock);
-    return;
   }
   
   // * -> sync?
@@ -2939,7 +2939,10 @@ void Locker::file_eval(ScatterLock *lock)
     simple_sync(lock);
   }
   
-  if (in->is_any_caps())
+  else
+    do_issue = true;
+
+  if (in->is_any_caps() && do_issue)
     issue_caps(in);
 }
 
index 70466359b32deb4449e809b37466c3bda9bc435e..6475e37c372003d06667e1ff4aa6f2afe23d0232 100644 (file)
@@ -164,7 +164,7 @@ protected:
   // file
 public:
   void try_file_eval(ScatterLock *lock);
-  void file_eval(ScatterLock *lock);
+  void file_eval(ScatterLock *lock, bool do_issue=false);
 protected:
   void handle_file_lock(ScatterLock *lock, MLock *m);
   void file_mixed(ScatterLock *lock);