From f1c7b4ef0cd064a9cb86757f17118d17913850db Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 26 Mar 2014 21:52:00 -0700 Subject: [PATCH] client: pin Inode during readahead Make sure the Inode does not go away while a readahead is in progress. In particular: - read_async - start a readahead - get actual read from cache, return - close/release - call ObjectCacher::release_set() and get unclean > 0, assert Fixes: #7867 Backport: emperor, dumpling Signed-off-by: Sage Weil --- src/client/Client.cc | 13 +++++++++++-- src/client/Client.h | 13 +++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 7a18a821eb8ff..49c9c6f218c6c 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -6190,8 +6190,17 @@ int Client::_read_async(Fh *f, uint64_t off, uint64_t len, bufferlist *bl) if (objectcacher->file_is_cached(&in->oset, &in->layout, in->snapid, off, min)) ldout(cct, 20) << "readahead already have min" << dendl; else { - objectcacher->file_read(&in->oset, &in->layout, in->snapid, off, l, NULL, 0, 0); - ldout(cct, 20) << "readahead initiated" << dendl; + Context *onfinish = new C_Readahead(this, in); + int r = objectcacher->file_read(&in->oset, &in->layout, in->snapid, + off, l, + NULL, 0, onfinish); + if (r == 0) { + ldout(cct, 20) << "readahead initiated, c " << onfinish << dendl; + in->get(); + } else { + ldout(cct, 20) << "readahead was no-op, already cached" << dendl; + delete onfinish; + } } } } diff --git a/src/client/Client.h b/src/client/Client.h index d180aba9368d6..458dd4c6e3e49 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -556,6 +556,19 @@ private: Fh *_create_fh(Inode *in, int flags, int cmode); int _release_fh(Fh *fh); + + struct C_Readahead : public Context { + Client *client; + Inode *inode; + C_Readahead(Client *c, Inode *i) + : client(c), + inode(i) { } + void finish(int r) { + lsubdout(client->cct, client, 20) << "C_Readahead on " << inode << dendl; + client->put_inode(inode, 1); + } + }; + int _read_sync(Fh *f, uint64_t off, uint64_t len, bufferlist *bl); int _read_async(Fh *f, uint64_t off, uint64_t len, bufferlist *bl); -- 2.39.5