]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: pin Inode during readahead
authorSage Weil <sage@inktank.com>
Thu, 27 Mar 2014 04:52:00 +0000 (21:52 -0700)
committerSage Weil <sage@inktank.com>
Fri, 28 Mar 2014 22:48:41 +0000 (15:48 -0700)
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 <sage@inktank.com>
(cherry picked from commit f1c7b4ef0cd064a9cb86757f17118d17913850db)

src/client/Client.cc
src/client/Client.h

index 8d3aafc1489fabfd3cae7809a4bc31d5134b2dfb..7f95a7f283d0af4405ecd351ff5272fe85afb131 100644 (file)
@@ -5787,8 +5787,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;
+       }
       }
     }
   }
index 1117ff3b0af40fd9a36d31e37d4e67de0a33a227..ff7e0eb9b0e37e6a58926c93b7d297a412ae9329 100644 (file)
@@ -529,6 +529,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);