]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: pin Inode during readahead 1557/head
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 21:55:13 +0000 (14:55 -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>
src/client/Client.cc
src/client/Client.h

index 7a18a821eb8ff82da89150654acbe95123a66c2e..49c9c6f218c6c72e0c78a5a992bb07bb833813a7 100644 (file)
@@ -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;
+       }
       }
     }
   }
index d180aba9368d6998140ec6536e64089a3dd63334..458dd4c6e3e49de3cb0dcd303e042d93777b5ed7 100644 (file)
@@ -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);