++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();
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);
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)
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);
};
// 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
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; }
};