Merge branch 'next/drivers' into next/late
[linux-2.6-microblaze.git] / net / rds / message.c
index 4b00b11..f139420 100644 (file)
@@ -308,16 +308,27 @@ out:
 /*
  * RDS ops use this to grab SG entries from the rm's sg pool.
  */
-struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents)
+struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents,
+                                         int *ret)
 {
        struct scatterlist *sg_first = (struct scatterlist *) &rm[1];
        struct scatterlist *sg_ret;
 
-       WARN_ON(rm->m_used_sgs + nents > rm->m_total_sgs);
-       WARN_ON(!nents);
+       if (WARN_ON(!ret))
+               return NULL;
 
-       if (rm->m_used_sgs + nents > rm->m_total_sgs)
+       if (nents <= 0) {
+               pr_warn("rds: alloc sgs failed! nents <= 0\n");
+               *ret = -EINVAL;
                return NULL;
+       }
+
+       if (rm->m_used_sgs + nents > rm->m_total_sgs) {
+               pr_warn("rds: alloc sgs failed! total %d used %d nents %d\n",
+                       rm->m_total_sgs, rm->m_used_sgs, nents);
+               *ret = -ENOMEM;
+               return NULL;
+       }
 
        sg_ret = &sg_first[rm->m_used_sgs];
        sg_init_table(sg_ret, nents);
@@ -332,6 +343,7 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in
        unsigned int i;
        int num_sgs = ceil(total_len, PAGE_SIZE);
        int extra_bytes = num_sgs * sizeof(struct scatterlist);
+       int ret;
 
        rm = rds_message_alloc(extra_bytes, GFP_NOWAIT);
        if (!rm)
@@ -340,10 +352,10 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in
        set_bit(RDS_MSG_PAGEVEC, &rm->m_flags);
        rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len);
        rm->data.op_nents = ceil(total_len, PAGE_SIZE);
-       rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs);
+       rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs, &ret);
        if (!rm->data.op_sg) {
                rds_message_put(rm);
-               return ERR_PTR(-ENOMEM);
+               return ERR_PTR(ret);
        }
 
        for (i = 0; i < rm->data.op_nents; ++i) {