diff --git a/src/civetweb b/src/civetweb index 4390635..8a07012 160000 --- a/src/civetweb +++ b/src/civetweb @@ -1 +1 @@ -Subproject commit 439063547d58427efa921296aa7be107182a026c +Subproject commit 8a07012185851b8e8be180391866b5995c10ee93 diff --git a/src/client/Client.cc b/src/client/Client.cc index 5c4654d..25b8b85 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -254,8 +254,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(); @@ -6693,12 +6692,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); @@ -7038,10 +7045,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) diff --git a/src/client/Client.h b/src/client/Client.h index d1dbebb..2a1baeb 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -624,14 +624,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); }; diff --git a/src/client/Fh.h b/src/client/Fh.h index 6f0aebd..dcf70cd 100644 --- a/src/client/Fh.h +++ b/src/client/Fh.h @@ -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; } };