]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
client: fix access violation
authorxie xingguo <xie.xingguo@zte.com.cn>
Sat, 18 Jun 2016 00:50:04 +0000 (08:50 +0800)
committerxie xingguo <xie.xingguo@zte.com.cn>
Tue, 21 Jun 2016 01:36:23 +0000 (09:36 +0800)
The MetaRequest is a refcounted object. On construction, it will default ref to 1.
The general process to make an MDS request will be:

  MetaRequest *req = new MetaRequest(op);
  // fill in something
  int r = make_request(req, uid, gid, target);
  return r;

As mentioned, make_request() will put the passed request before returning(and thereby
delete the request automatically).

To be more specific here, the make_request() will call "mds_requests[tid] = request->get();"
to keep the request well local tracked on entry(which raises the ref of request to 2).
And on error exit(especially for the following no reply is received case), by calling both

    unregister_request(request);
    put_request(request); // ours

, it will decrease the reference of the corresponding request to zero and thereby delete request.
Therefore the call to request thereafter is at risk of "access violation".

Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
src/client/Client.cc

index 0c3b7a614379d5ad8dfeb41ae8de22d538753dfe..8fc8ffbd70d22008959b4b0578e075d5f4fabcd2 100644 (file)
@@ -1706,10 +1706,11 @@ int Client::make_request(MetaRequest *request,
   if (!request->reply) {
     assert(request->aborted());
     assert(!request->got_unsafe);
+    r = request->get_abort_code();
     request->item.remove_myself();
     unregister_request(request);
     put_request(request); // ours
-    return request->get_abort_code();
+    return r;
   }
 
   // got it!