diff options
Diffstat (limited to 'net/rds/message.c')
-rw-r--r-- | net/rds/message.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/net/rds/message.c b/net/rds/message.c index 4b00b1152a5f..f139420ba1f6 100644 --- a/net/rds/message.c +++ b/net/rds/message.c | |||
@@ -308,16 +308,27 @@ out: | |||
308 | /* | 308 | /* |
309 | * RDS ops use this to grab SG entries from the rm's sg pool. | 309 | * RDS ops use this to grab SG entries from the rm's sg pool. |
310 | */ | 310 | */ |
311 | struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents) | 311 | struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents, |
312 | int *ret) | ||
312 | { | 313 | { |
313 | struct scatterlist *sg_first = (struct scatterlist *) &rm[1]; | 314 | struct scatterlist *sg_first = (struct scatterlist *) &rm[1]; |
314 | struct scatterlist *sg_ret; | 315 | struct scatterlist *sg_ret; |
315 | 316 | ||
316 | WARN_ON(rm->m_used_sgs + nents > rm->m_total_sgs); | 317 | if (WARN_ON(!ret)) |
317 | WARN_ON(!nents); | 318 | return NULL; |
318 | 319 | ||
319 | if (rm->m_used_sgs + nents > rm->m_total_sgs) | 320 | if (nents <= 0) { |
321 | pr_warn("rds: alloc sgs failed! nents <= 0\n"); | ||
322 | *ret = -EINVAL; | ||
320 | return NULL; | 323 | return NULL; |
324 | } | ||
325 | |||
326 | if (rm->m_used_sgs + nents > rm->m_total_sgs) { | ||
327 | pr_warn("rds: alloc sgs failed! total %d used %d nents %d\n", | ||
328 | rm->m_total_sgs, rm->m_used_sgs, nents); | ||
329 | *ret = -ENOMEM; | ||
330 | return NULL; | ||
331 | } | ||
321 | 332 | ||
322 | sg_ret = &sg_first[rm->m_used_sgs]; | 333 | sg_ret = &sg_first[rm->m_used_sgs]; |
323 | sg_init_table(sg_ret, nents); | 334 | sg_init_table(sg_ret, nents); |
@@ -332,6 +343,7 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in | |||
332 | unsigned int i; | 343 | unsigned int i; |
333 | int num_sgs = ceil(total_len, PAGE_SIZE); | 344 | int num_sgs = ceil(total_len, PAGE_SIZE); |
334 | int extra_bytes = num_sgs * sizeof(struct scatterlist); | 345 | int extra_bytes = num_sgs * sizeof(struct scatterlist); |
346 | int ret; | ||
335 | 347 | ||
336 | rm = rds_message_alloc(extra_bytes, GFP_NOWAIT); | 348 | rm = rds_message_alloc(extra_bytes, GFP_NOWAIT); |
337 | if (!rm) | 349 | if (!rm) |
@@ -340,10 +352,10 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in | |||
340 | set_bit(RDS_MSG_PAGEVEC, &rm->m_flags); | 352 | set_bit(RDS_MSG_PAGEVEC, &rm->m_flags); |
341 | rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len); | 353 | rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len); |
342 | rm->data.op_nents = ceil(total_len, PAGE_SIZE); | 354 | rm->data.op_nents = ceil(total_len, PAGE_SIZE); |
343 | rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs); | 355 | rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs, &ret); |
344 | if (!rm->data.op_sg) { | 356 | if (!rm->data.op_sg) { |
345 | rds_message_put(rm); | 357 | rds_message_put(rm); |
346 | return ERR_PTR(-ENOMEM); | 358 | return ERR_PTR(ret); |
347 | } | 359 | } |
348 | 360 | ||
349 | for (i = 0; i < rm->data.op_nents; ++i) { | 361 | for (i = 0; i < rm->data.op_nents; ++i) { |