]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
uclient: pin inodes on first cap ref to CAP_FILE_BUFFER
authorSage Weil <sage@newdream.net>
Fri, 28 Aug 2009 23:00:00 +0000 (16:00 -0700)
committerSage Weil <sage@newdream.net>
Fri, 28 Aug 2009 23:00:00 +0000 (16:00 -0700)
We need to keep inode pinned if there is dirty data.  Der.

src/client/Client.cc
src/client/Client.h

index 6f1c9915e1f68c6059a42bf26a163c3763a2d1dd..2fd97f5910212cce161db1dc1f745dbcd54f8ba2 100644 (file)
@@ -1421,6 +1421,15 @@ bool Inode::put_cap_ref(int cap)
   return last;
 }
 
+void Client::get_cap_ref(Inode *in, int cap)
+{
+  if ((cap & CEPH_CAP_FILE_BUFFER) &&
+      in->cap_refs[CEPH_CAP_FILE_BUFFER] == 0) {
+    dout(5) << "get_cap_ref got first FILE_BUFFER ref on " << *in << dendl;
+    in->get();
+  }
+}
+
 void Client::put_cap_ref(Inode *in, int cap)
 {
   if (in->put_cap_ref(cap) && in->snapid == CEPH_NOSNAP) {
@@ -1433,12 +1442,17 @@ void Client::put_cap_ref(Inode *in, int cap)
       signal_cond_list(in->waitfor_caps);  // wake up blocked sync writers
     }
     if (cap & CEPH_CAP_FILE_BUFFER) {
+      int last = in->cap_refs[CEPH_CAP_FILE_BUFFER];
       for (map<snapid_t,CapSnap>::iterator p = in->cap_snaps.begin();
           p != in->cap_snaps.end();
           p++)
        p->second.dirty_data = 0;
       check_caps(in, false);
       signal_cond_list(in->waitfor_commit);
+      if (last) {
+       dout(5) << "put_cap_ref dropped last FILE_BUFFER ref on " << *in << dendl;
+       put_inode(in);
+      }
     }
   }
 }
@@ -4265,7 +4279,7 @@ int Client::_write(Fh *f, __s64 offset, __u64 size, const char *buf)
     if (in->caps_issued_mask(CEPH_CAP_FILE_BUFFER)) {
       // do buffered write
       if (in->cap_refs[CEPH_CAP_FILE_BUFFER] == 0)
-       in->get_cap_ref(CEPH_CAP_FILE_BUFFER);
+       get_cap_ref(in, CEPH_CAP_FILE_BUFFER);
       
       // wait? (this may block!)
       objectcacher->wait_for_write(size, client_lock);
@@ -4287,7 +4301,7 @@ int Client::_write(Fh *f, __s64 offset, __u64 size, const char *buf)
     Context *onsafe = new C_Client_SyncCommit(this, in);
 
     unsafe_sync_write++;
-    in->get_cap_ref(CEPH_CAP_FILE_BUFFER);
+    get_cap_ref(in, CEPH_CAP_FILE_BUFFER);
     
     filer->write(in->ino, &in->layout, in->snaprealm->get_snap_context(),
                 offset, size, bl, g_clock.now(), 0, onfinish, onsafe);
index e29fa6832783f1b9de8e7c4ac4c686c9e6ea675d..9452070789e3089196dded63636cd51897f5d508 100644 (file)
@@ -1015,6 +1015,7 @@ protected:
   void cap_delay_requeue(Inode *in);
   void send_cap(Inode *in, int mds, InodeCap *cap, int used, int want, int retain, int flush, __u64 tid);
   void check_caps(Inode *in, bool is_delayed);
+  void get_cap_ref(Inode *in, int cap);
   void put_cap_ref(Inode *in, int cap);
   void flush_snaps(Inode *in);
   void wait_sync_caps(__u64 want);