Merge tag 'for-linus-4.9-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / net / sunrpc / xprtsock.c
index bf16883..0137af1 100644 (file)
@@ -473,7 +473,16 @@ static int xs_nospace(struct rpc_task *task)
        spin_unlock_bh(&xprt->transport_lock);
 
        /* Race breaker in case memory is freed before above code is called */
-       sk->sk_write_space(sk);
+       if (ret == -EAGAIN) {
+               struct socket_wq *wq;
+
+               rcu_read_lock();
+               wq = rcu_dereference(sk->sk_wq);
+               set_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags);
+               rcu_read_unlock();
+
+               sk->sk_write_space(sk);
+       }
        return ret;
 }
 
@@ -2533,35 +2542,38 @@ static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
  * we allocate pages instead doing a kmalloc like rpc_malloc is because we want
  * to use the server side send routines.
  */
-static void *bc_malloc(struct rpc_task *task, size_t size)
+static int bc_malloc(struct rpc_task *task)
 {
+       struct rpc_rqst *rqst = task->tk_rqstp;
+       size_t size = rqst->rq_callsize;
        struct page *page;
        struct rpc_buffer *buf;
 
-       WARN_ON_ONCE(size > PAGE_SIZE - sizeof(struct rpc_buffer));
-       if (size > PAGE_SIZE - sizeof(struct rpc_buffer))
-               return NULL;
+       if (size > PAGE_SIZE - sizeof(struct rpc_buffer)) {
+               WARN_ONCE(1, "xprtsock: large bc buffer request (size %zu)\n",
+                         size);
+               return -EINVAL;
+       }
 
        page = alloc_page(GFP_KERNEL);
        if (!page)
-               return NULL;
+               return -ENOMEM;
 
        buf = page_address(page);
        buf->len = PAGE_SIZE;
 
-       return buf->data;
+       rqst->rq_buffer = buf->data;
+       return 0;
 }
 
 /*
  * Free the space allocated in the bc_alloc routine
  */
-static void bc_free(void *buffer)
+static void bc_free(struct rpc_task *task)
 {
+       void *buffer = task->tk_rqstp->rq_buffer;
        struct rpc_buffer *buf;
 
-       if (!buffer)
-               return;
-
        buf = container_of(buffer, struct rpc_buffer, data);
        free_page((unsigned long)buf);
 }