]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: reference counting 'struct Fh' 5164/head
authorYan, Zheng <zyan@redhat.com>
Wed, 8 Jul 2015 02:11:43 +0000 (10:11 +0800)
committerYan, Zheng <zyan@redhat.com>
Wed, 8 Jul 2015 02:12:47 +0000 (10:12 +0800)
The async readahead finisher needs to reference 'struct Fh'. But
it's possible user closes FD and free the corresponding 'struct Fh'
before async readahead finishes.

Fixes: #12088
Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/client/Client.cc
src/client/Client.h
src/client/Fh.h

index 4e70756d4c062c694dd61df35345e82ede7cd404..7973ddeb243ad6b326ff139c3210f5077c615690 100644 (file)
@@ -248,8 +248,7 @@ void Client::tear_down_cache()
        ++it) {
     Fh *fh = it->second;
     ldout(cct, 1) << "tear_down_cache forcing close of fh " << it->first << " ino " << fh->inode->ino << dendl;
-    put_inode(fh->inode);
-    delete fh;
+    _release_fh(fh);
   }
   fd_map.clear();
 
@@ -6910,12 +6909,20 @@ int Client::_release_fh(Fh *f)
     ldout(cct, 10) << "_release_fh " << f << " on inode " << *in << " no async_err state" << dendl;
   }
 
-  put_inode(in);
-  delete f;
+  _put_fh(f);
 
   return err;
 }
 
+void Client::_put_fh(Fh *f)
+{
+  int left = f->put();
+  if (!left) {
+    put_inode(f->inode);
+    delete f;
+  }
+}
+
 int Client::_open(Inode *in, int flags, mode_t mode, Fh **fhp, int uid, int gid)
 {
   int cmode = ceph_flags_to_mode(flags);
@@ -7262,10 +7269,16 @@ done:
   return r < 0 ? r : bl->length();
 }
 
+Client::C_Readahead::C_Readahead(Client *c, Fh *f) :
+  client(c), f(f) {
+    f->get();
+}
+
 void Client::C_Readahead::finish(int r) {
   lgeneric_subdout(client->cct, client, 20) << "client." << client->get_nodeid() << " " << "C_Readahead on " << f->inode << dendl;
   client->put_cap_ref(f->inode, CEPH_CAP_FILE_RD | CEPH_CAP_FILE_CACHE);
   f->readahead.dec_pending();
+  client->_put_fh(f);
 }
 
 int Client::_read_async(Fh *f, uint64_t off, uint64_t len, bufferlist *bl)
index cc9a5acdb231fdb18c9770ad8def8b24cd492b9d..b24a7829ddbe3fbb8010ca3cf6fdbdb4dfb54e78 100644 (file)
@@ -639,14 +639,13 @@ private:
 
   Fh *_create_fh(Inode *in, int flags, int cmode);
   int _release_fh(Fh *fh);
+  void _put_fh(Fh *fh);
 
 
   struct C_Readahead : public Context {
     Client *client;
     Fh *f;
-    C_Readahead(Client *c, Fh *f)
-      : client(c),
-       f(f) { }
+    C_Readahead(Client *c, Fh *f);
     void finish(int r);
   };
 
index 6f0aebd5d941ab10fe099aaecadce9bc56f154d7..dcf70cdbbe991b227303bcda3a2b7bf13ae5a7ef 100644 (file)
@@ -11,7 +11,8 @@ class ceph_lock_state_t;
 // file handle for any open file state
 
 struct Fh {
-  Inode    *inode;
+  int      _ref;
+  Inode     *inode;
   loff_t    pos;
   int       mds;        // have to talk to mds we opened with (for now)
   int       mode;       // the mode i opened the file with
@@ -26,8 +27,10 @@ struct Fh {
   ceph_lock_state_t *fcntl_locks;
   ceph_lock_state_t *flock_locks;
 
-  Fh() : inode(0), pos(0), mds(0), mode(0), flags(0), pos_locked(false),
+  Fh() : _ref(1), inode(0), pos(0), mds(0), mode(0), flags(0), pos_locked(false),
       readahead(), fcntl_locks(NULL), flock_locks(NULL) {}
+  void get() { ++_ref; }
+  int put() { return --_ref; }
 };