Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm
[pandora-kernel.git] / net / ceph / osd_client.c
index 6b5dda1..7330c27 100644 (file)
@@ -124,7 +124,7 @@ static void calc_layout(struct ceph_osd_client *osdc,
        ceph_calc_raw_layout(osdc, layout, vino.snap, off,
                             plen, &bno, req, op);
 
-       sprintf(req->r_oid, "%llx.%08llx", vino.ino, bno);
+       snprintf(req->r_oid, sizeof(req->r_oid), "%llx.%08llx", vino.ino, bno);
        req->r_oid_len = strlen(req->r_oid);
 }
 
@@ -477,8 +477,9 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
        calc_layout(osdc, vino, layout, off, plen, req, ops);
        req->r_file_layout = *layout;  /* keep a copy */
 
-       /* in case it differs from natural alignment that calc_layout
-          filled in for us */
+       /* in case it differs from natural (file) alignment that
+          calc_layout filled in for us */
+       req->r_num_pages = calc_pages_for(page_align, *plen);
        req->r_page_alignment = page_align;
 
        ceph_osdc_build_request(req, off, plen, ops,
@@ -1144,6 +1145,13 @@ static void handle_osds_timeout(struct work_struct *work)
                              round_jiffies_relative(delay));
 }
 
+static void complete_request(struct ceph_osd_request *req)
+{
+       if (req->r_safe_callback)
+               req->r_safe_callback(req, NULL);
+       complete_all(&req->r_safe_completion);  /* fsync waiter */
+}
+
 /*
  * handle osd op reply.  either call the callback if it is specified,
  * or do the completion to wake up the waiting thread.
@@ -1226,11 +1234,8 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
        else
                complete_all(&req->r_completion);
 
-       if (flags & CEPH_OSD_FLAG_ONDISK) {
-               if (req->r_safe_callback)
-                       req->r_safe_callback(req, msg);
-               complete_all(&req->r_safe_completion);  /* fsync waiter */
-       }
+       if (flags & CEPH_OSD_FLAG_ONDISK)
+               complete_request(req);
 
 done:
        dout("req=%p req->r_linger=%d\n", req, req->r_linger);
@@ -1421,6 +1426,15 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
 done:
        downgrade_write(&osdc->map_sem);
        ceph_monc_got_osdmap(&osdc->client->monc, osdc->osdmap->epoch);
+
+       /*
+        * subscribe to subsequent osdmap updates if full to ensure
+        * we find out when we are no longer full and stop returning
+        * ENOSPC.
+        */
+       if (ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_FULL))
+               ceph_monc_request_next_osdmap(&osdc->client->monc);
+
        send_queued(osdc);
        up_read(&osdc->map_sem);
        wake_up_all(&osdc->client->auth_wq);
@@ -1677,8 +1691,14 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc,
         */
        if (req->r_sent == 0) {
                rc = __map_request(osdc, req);
-               if (rc < 0)
+               if (rc < 0) {
+                       if (nofail) {
+                               dout("osdc_start_request failed map, "
+                                    " will retry %lld\n", req->r_tid);
+                               rc = 0;
+                       }
                        goto out_unlock;
+               }
                if (req->r_osd == NULL) {
                        dout("send_request %p no up osds in pg\n", req);
                        ceph_monc_request_next_osdmap(&osdc->client->monc);
@@ -1717,6 +1737,7 @@ int ceph_osdc_wait_request(struct ceph_osd_client *osdc,
                __cancel_request(req);
                __unregister_request(osdc, req);
                mutex_unlock(&osdc->request_mutex);
+               complete_request(req);
                dout("wait_request tid %llu canceled/timed out\n", req->r_tid);
                return rc;
        }
@@ -2007,8 +2028,9 @@ static struct ceph_msg *get_reply(struct ceph_connection *con,
                int want = calc_pages_for(req->r_page_alignment, data_len);
 
                if (unlikely(req->r_num_pages < want)) {
-                       pr_warning("tid %lld reply %d > expected %d pages\n",
-                                  tid, want, m->nr_pages);
+                       pr_warning("tid %lld reply has %d bytes %d pages, we"
+                                  " had only %d pages ready\n", tid, data_len,
+                                  want, req->r_num_pages);
                        *skip = 1;
                        ceph_msg_put(m);
                        m = NULL;