From b5a0773259ce9f2ef44e8e6925ab11dc1a5e55e6 Mon Sep 17 00:00:00 2001 From: Patrick Donnelly Date: Fri, 10 Jun 2016 17:33:04 -0400 Subject: [PATCH] client: move readahead ref get/put to obj constr The readahead context was incrementing the file handle reference count but only decreasing in finish which is not called if readahead is a no-op. This fixes a bug caught in testing where readahead was causing inode to become disconnected: 2016-06-10 19:46:48.953018 7f2a4351be80 1 client.4125 dump_inode: DISCONNECTED inode 10000000502 #10000000502 ref 110000000502.head(faked_ino=2307 ref=1 ll_ref=0 cap_refs={1024=0,2048=0,4096=0,8192=0} open={1=0,2=0} mode=100666 size=4194304/0 mtime=2016-06-10 19:29:45.107417 caps=-(0=pAsLsXsFscr) objectset[10000000502 ts 2/4012653 objects 0 dirty_or_tx 0] 0x7f2a24300d00) 2016-06-10 19:46:48.953032 7f2a4351be80 2 client.4125 cache still has 0+155 items, waiting (for caps to release?) Signed-off-by: Patrick Donnelly --- src/client/Client.cc | 14 ++++++++------ src/client/Client.h | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 3e5822d59e586..1745f981a32f8 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -8138,15 +8138,19 @@ done: } Client::C_Readahead::C_Readahead(Client *c, Fh *f) : - client(c), f(f) { - f->get(); + client(c), f(f) { + f->get(); + f->readahead.inc_pending(); +} + +Client::C_Readahead::~C_Readahead() { + f->readahead.dec_pending(); + client->_put_fh(f); } 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.get(), 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) @@ -8198,7 +8202,6 @@ int Client::_read_async(Fh *f, uint64_t off, uint64_t len, bufferlist *bl) ldout(cct, 20) << "readahead " << readahead_extent.first << "~" << readahead_extent.second << " (caller wants " << off << "~" << len << ")" << dendl; Context *onfinish2 = new C_Readahead(this, f); - f->readahead.inc_pending(); int r2 = objectcacher->file_read(&in->oset, &in->layout, in->snapid, readahead_extent.first, readahead_extent.second, NULL, 0, onfinish2); @@ -8206,7 +8209,6 @@ int Client::_read_async(Fh *f, uint64_t off, uint64_t len, bufferlist *bl) ldout(cct, 20) << "readahead initiated, c " << onfinish2 << dendl; get_cap_ref(in, CEPH_CAP_FILE_RD | CEPH_CAP_FILE_CACHE); } else { - f->readahead.dec_pending(); ldout(cct, 20) << "readahead was no-op, already cached" << dendl; delete onfinish2; } diff --git a/src/client/Client.h b/src/client/Client.h index 9a41b909e16ef..9b667d2080ec8 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -710,6 +710,7 @@ private: Client *client; Fh *f; C_Readahead(Client *c, Fh *f); + ~C_Readahead(); void finish(int r); }; -- 2.39.5