]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/ceph/osd_client.c
libceph: unregister request in __map_request failed and nofail == false
[karo-tx-linux.git] / net / ceph / osd_client.c
index e0abb83b520e7478bb4eb73f9475f1fae6fe9c81..dbc0a7392d67b67b276e985453aa5e6d5ae8ee9f 100644 (file)
@@ -733,12 +733,14 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
 
        object_size = le32_to_cpu(layout->fl_object_size);
        object_base = off - objoff;
-       if (truncate_size <= object_base) {
-               truncate_size = 0;
-       } else {
-               truncate_size -= object_base;
-               if (truncate_size > object_size)
-                       truncate_size = object_size;
+       if (!(truncate_seq == 1 && truncate_size == -1ULL)) {
+               if (truncate_size <= object_base) {
+                       truncate_size = 0;
+               } else {
+                       truncate_size -= object_base;
+                       if (truncate_size > object_size)
+                               truncate_size = object_size;
+               }
        }
 
        osd_req_op_extent_init(req, 0, opcode, objoff, objlen,
@@ -1335,10 +1337,6 @@ static void __send_request(struct ceph_osd_client *osdc,
 
        ceph_msg_get(req->r_request); /* send consumes a ref */
 
-       /* Mark the request unsafe if this is the first timet's being sent. */
-
-       if (!req->r_sent && req->r_unsafe_callback)
-               req->r_unsafe_callback(req, true);
        req->r_sent = req->r_osd->o_incarnation;
 
        ceph_con_send(&req->r_osd->o_con, req->r_request);
@@ -1429,8 +1427,6 @@ static void handle_osds_timeout(struct work_struct *work)
 
 static void complete_request(struct ceph_osd_request *req)
 {
-       if (req->r_unsafe_callback)
-               req->r_unsafe_callback(req, false);
        complete_all(&req->r_safe_completion);  /* fsync waiter */
 }
 
@@ -1522,6 +1518,8 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
        for (i = 0; i < numops; i++)
                req->r_reply_op_result[i] = ceph_decode_32(&p);
 
+       already_completed = req->r_got_reply;
+
        if (!req->r_got_reply) {
 
                req->r_result = result;
@@ -1552,19 +1550,23 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
            ((flags & CEPH_OSD_FLAG_WRITE) == 0))
                __unregister_request(osdc, req);
 
-       already_completed = req->r_completed;
-       req->r_completed = 1;
        mutex_unlock(&osdc->request_mutex);
-       if (already_completed)
-               goto done;
 
-       if (req->r_callback)
-               req->r_callback(req, msg);
-       else
-               complete_all(&req->r_completion);
+       if (!already_completed) {
+               if (req->r_unsafe_callback &&
+                   result >= 0 && !(flags & CEPH_OSD_FLAG_ONDISK))
+                       req->r_unsafe_callback(req, true);
+               if (req->r_callback)
+                       req->r_callback(req, msg);
+               else
+                       complete_all(&req->r_completion);
+       }
 
-       if (flags & CEPH_OSD_FLAG_ONDISK)
+       if (flags & CEPH_OSD_FLAG_ONDISK) {
+               if (req->r_unsafe_callback && already_completed)
+                       req->r_unsafe_callback(req, false);
                complete_request(req);
+       }
 
 done:
        dout("req=%p req->r_linger=%d\n", req, req->r_linger);
@@ -2121,13 +2123,14 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc,
        __register_request(osdc, req);
        req->r_sent = 0;
        req->r_got_reply = 0;
-       req->r_completed = 0;
        rc = __map_request(osdc, req, 0);
        if (rc < 0) {
                if (nofail) {
                        dout("osdc_start_request failed map, "
                                " will retry %lld\n", req->r_tid);
                        rc = 0;
+               } else {
+                       __unregister_request(osdc, req);
                }
                goto out_unlock;
        }
@@ -2454,8 +2457,10 @@ static struct ceph_msg *get_reply(struct ceph_connection *con,
        ceph_msg_revoke_incoming(req->r_reply);
 
        if (front > req->r_reply->front.iov_len) {
-               pr_warning("get_reply front %d > preallocated %d\n",
-                          front, (int)req->r_reply->front.iov_len);
+               pr_warning("get_reply front %d > preallocated %d (%u#%llu)\n",
+                          front, (int)req->r_reply->front.iov_len,
+                          (unsigned int)con->peer_name.type,
+                          le64_to_cpu(con->peer_name.num));
                m = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, front, GFP_NOFS, false);
                if (!m)
                        goto out;