]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: hold FILE_BUFFER ref while waiting for dirty throttle
authorSage Weil <sage@newdream.net>
Thu, 19 May 2011 22:03:13 +0000 (15:03 -0700)
committerSage Weil <sage@newdream.net>
Thu, 19 May 2011 22:04:31 +0000 (15:04 -0700)
We may block in the write path because we've reached out dirty data limit.
Hold a reference to the FILE_BUFFER cap during that interval so we don't
lose the cap and put new dirty buffers into the objectcacher out of turn.

(We could also recheck our ability to take the ref after blocking, but I
think this is cleaner.)

Signed-off-by: Sage Weil <sage@newdream.net>
src/client/Client.cc

index 5fbca40c229628ef3a4adbb89b88f86bc0ed6c25..bf8f6f2e7a916501002b40f91c2417b2c7828307 100644 (file)
@@ -5018,20 +5018,24 @@ int Client::_write(Fh *f, int64_t offset, uint64_t size, const char *buf)
   int r = get_caps(in, CEPH_CAP_FILE_WR, CEPH_CAP_FILE_BUFFER, &got, endoff);
   if (r < 0)
     return r;
-  
+
   dout(10) << " snaprealm " << *in->snaprealm << dendl;
 
   if (g_conf.client_oc && (got & CEPH_CAP_FILE_BUFFER)) {
     // do buffered write
     if (in->cap_refs[CEPH_CAP_FILE_BUFFER] == 0)
       get_cap_ref(in, CEPH_CAP_FILE_BUFFER);
-    
+
+    get_cap_ref(in, CEPH_CAP_FILE_BUFFER);
+
     // wait? (this may block!)
     objectcacher->wait_for_write(size, client_lock);
     
     // async, caching, non-blocking.
     objectcacher->file_write(&in->oset, &in->layout, in->snaprealm->get_snap_context(),
                             offset, size, bl, g_clock.now(), 0);
+
+    put_cap_ref(in, CEPH_CAP_FILE_BUFFER);
   } else {
     /*
       // atomic, synchronous, blocking.