drm/xe/bo: Gracefully handle errors from ttm_bo_move_accel_cleanup().
[linux-2.6-microblaze.git] / net / ceph / messenger.c
index 5eb4898..3c8b78d 100644 (file)
@@ -459,8 +459,8 @@ int ceph_tcp_connect(struct ceph_connection *con)
        set_sock_callbacks(sock, con);
 
        con_sock_state_connecting(con);
-       ret = sock->ops->connect(sock, (struct sockaddr *)&ss, sizeof(ss),
-                                O_NONBLOCK);
+       ret = kernel_connect(sock, (struct sockaddr *)&ss, sizeof(ss),
+                            O_NONBLOCK);
        if (ret == -EINPROGRESS) {
                dout("connect %s EINPROGRESS sk_state = %u\n",
                     ceph_pr_addr(&con->peer_addr),
@@ -969,6 +969,62 @@ static bool ceph_msg_data_pagelist_advance(struct ceph_msg_data_cursor *cursor,
        return true;
 }
 
+static void ceph_msg_data_iter_cursor_init(struct ceph_msg_data_cursor *cursor,
+                                          size_t length)
+{
+       struct ceph_msg_data *data = cursor->data;
+
+       cursor->iov_iter = data->iter;
+       cursor->lastlen = 0;
+       iov_iter_truncate(&cursor->iov_iter, length);
+       cursor->resid = iov_iter_count(&cursor->iov_iter);
+}
+
+static struct page *ceph_msg_data_iter_next(struct ceph_msg_data_cursor *cursor,
+                                           size_t *page_offset, size_t *length)
+{
+       struct page *page;
+       ssize_t len;
+
+       if (cursor->lastlen)
+               iov_iter_revert(&cursor->iov_iter, cursor->lastlen);
+
+       len = iov_iter_get_pages2(&cursor->iov_iter, &page, PAGE_SIZE,
+                                 1, page_offset);
+       BUG_ON(len < 0);
+
+       cursor->lastlen = len;
+
+       /*
+        * FIXME: The assumption is that the pages represented by the iov_iter
+        *        are pinned, with the references held by the upper-level
+        *        callers, or by virtue of being under writeback. Eventually,
+        *        we'll get an iov_iter_get_pages2 variant that doesn't take
+        *        page refs. Until then, just put the page ref.
+        */
+       VM_BUG_ON_PAGE(!PageWriteback(page) && page_count(page) < 2, page);
+       put_page(page);
+
+       *length = min_t(size_t, len, cursor->resid);
+       return page;
+}
+
+static bool ceph_msg_data_iter_advance(struct ceph_msg_data_cursor *cursor,
+                                      size_t bytes)
+{
+       BUG_ON(bytes > cursor->resid);
+       cursor->resid -= bytes;
+
+       if (bytes < cursor->lastlen) {
+               cursor->lastlen -= bytes;
+       } else {
+               iov_iter_advance(&cursor->iov_iter, bytes - cursor->lastlen);
+               cursor->lastlen = 0;
+       }
+
+       return cursor->resid;
+}
+
 /*
  * Message data is handled (sent or received) in pieces, where each
  * piece resides on a single page.  The network layer might not
@@ -996,6 +1052,9 @@ static void __ceph_msg_data_cursor_init(struct ceph_msg_data_cursor *cursor)
        case CEPH_MSG_DATA_BVECS:
                ceph_msg_data_bvecs_cursor_init(cursor, length);
                break;
+       case CEPH_MSG_DATA_ITER:
+               ceph_msg_data_iter_cursor_init(cursor, length);
+               break;
        case CEPH_MSG_DATA_NONE:
        default:
                /* BUG(); */
@@ -1013,6 +1072,7 @@ void ceph_msg_data_cursor_init(struct ceph_msg_data_cursor *cursor,
 
        cursor->total_resid = length;
        cursor->data = msg->data;
+       cursor->sr_resid = 0;
 
        __ceph_msg_data_cursor_init(cursor);
 }
@@ -1042,6 +1102,9 @@ struct page *ceph_msg_data_next(struct ceph_msg_data_cursor *cursor,
        case CEPH_MSG_DATA_BVECS:
                page = ceph_msg_data_bvecs_next(cursor, page_offset, length);
                break;
+       case CEPH_MSG_DATA_ITER:
+               page = ceph_msg_data_iter_next(cursor, page_offset, length);
+               break;
        case CEPH_MSG_DATA_NONE:
        default:
                page = NULL;
@@ -1080,6 +1143,9 @@ void ceph_msg_data_advance(struct ceph_msg_data_cursor *cursor, size_t bytes)
        case CEPH_MSG_DATA_BVECS:
                new_piece = ceph_msg_data_bvecs_advance(cursor, bytes);
                break;
+       case CEPH_MSG_DATA_ITER:
+               new_piece = ceph_msg_data_iter_advance(cursor, bytes);
+               break;
        case CEPH_MSG_DATA_NONE:
        default:
                BUG();
@@ -1879,6 +1945,18 @@ void ceph_msg_data_add_bvecs(struct ceph_msg *msg,
 }
 EXPORT_SYMBOL(ceph_msg_data_add_bvecs);
 
+void ceph_msg_data_add_iter(struct ceph_msg *msg,
+                           struct iov_iter *iter)
+{
+       struct ceph_msg_data *data;
+
+       data = ceph_msg_data_add(msg);
+       data->type = CEPH_MSG_DATA_ITER;
+       data->iter = *iter;
+
+       msg->data_length += iov_iter_count(&data->iter);
+}
+
 /*
  * construct a new message with given type, size
  * the new msg has a ref count of 1.