diff options
author | Olaf Kirch <olaf.kirch@oracle.com> | 2007-12-13 13:43:25 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-11 19:28:27 -0500 |
commit | 6320377fd94316e58f75d0be6f6e7a644950a4ee (patch) | |
tree | 7c7b47e6bafae9f25cfd9e1416494b6406c2d0b9 /drivers/scsi | |
parent | 38ad03de3fd350e683213ddf898a7049534628a8 (diff) |
[SCSI] libiscsi, iscsi_tcp: iscsi pool cleanup
iscsi_pool_init simplified
iscsi_pool_init currently has a lot of duplicate kfree() calls it does
when some allocation fails. This patch simplifies the code a little by
using iscsi_pool_free to tear down the pool in case of an error.
iscsi_pool_init also returns a copy of the item array to the caller.
Not all callers use this array, so we make it optional.
Instead of allocating a second array and return that, allocate just one
array, of twice the size.
Update users of iscsi_pool_{init,free}
This patch drops the (now useless) second argument to
iscsi_pool_free, and updates all callers.
It also removes the ctask->r2ts array, which was never
used anyway. Since the items argument to iscsi_pool_init
is now optional, we can pass NULL instead.
Signed-off-by: Olaf Kirch <olaf.kirch@oracle.com>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 12 | ||||
-rw-r--r-- | drivers/scsi/iscsi_tcp.h | 3 | ||||
-rw-r--r-- | drivers/scsi/libiscsi.c | 75 |
3 files changed, 45 insertions, 45 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 491845f18710..f79a457099e6 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -1998,8 +1998,7 @@ iscsi_r2tpool_alloc(struct iscsi_session *session) | |||
1998 | */ | 1998 | */ |
1999 | 1999 | ||
2000 | /* R2T pool */ | 2000 | /* R2T pool */ |
2001 | if (iscsi_pool_init(&tcp_ctask->r2tpool, session->max_r2t * 4, | 2001 | if (iscsi_pool_init(&tcp_ctask->r2tpool, session->max_r2t * 4, NULL, |
2002 | (void***)&tcp_ctask->r2ts, | ||
2003 | sizeof(struct iscsi_r2t_info))) { | 2002 | sizeof(struct iscsi_r2t_info))) { |
2004 | goto r2t_alloc_fail; | 2003 | goto r2t_alloc_fail; |
2005 | } | 2004 | } |
@@ -2008,8 +2007,7 @@ iscsi_r2tpool_alloc(struct iscsi_session *session) | |||
2008 | tcp_ctask->r2tqueue = kfifo_alloc( | 2007 | tcp_ctask->r2tqueue = kfifo_alloc( |
2009 | session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL); | 2008 | session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL); |
2010 | if (tcp_ctask->r2tqueue == ERR_PTR(-ENOMEM)) { | 2009 | if (tcp_ctask->r2tqueue == ERR_PTR(-ENOMEM)) { |
2011 | iscsi_pool_free(&tcp_ctask->r2tpool, | 2010 | iscsi_pool_free(&tcp_ctask->r2tpool); |
2012 | (void**)tcp_ctask->r2ts); | ||
2013 | goto r2t_alloc_fail; | 2011 | goto r2t_alloc_fail; |
2014 | } | 2012 | } |
2015 | } | 2013 | } |
@@ -2022,8 +2020,7 @@ r2t_alloc_fail: | |||
2022 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 2020 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
2023 | 2021 | ||
2024 | kfifo_free(tcp_ctask->r2tqueue); | 2022 | kfifo_free(tcp_ctask->r2tqueue); |
2025 | iscsi_pool_free(&tcp_ctask->r2tpool, | 2023 | iscsi_pool_free(&tcp_ctask->r2tpool); |
2026 | (void**)tcp_ctask->r2ts); | ||
2027 | } | 2024 | } |
2028 | return -ENOMEM; | 2025 | return -ENOMEM; |
2029 | } | 2026 | } |
@@ -2038,8 +2035,7 @@ iscsi_r2tpool_free(struct iscsi_session *session) | |||
2038 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 2035 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
2039 | 2036 | ||
2040 | kfifo_free(tcp_ctask->r2tqueue); | 2037 | kfifo_free(tcp_ctask->r2tqueue); |
2041 | iscsi_pool_free(&tcp_ctask->r2tpool, | 2038 | iscsi_pool_free(&tcp_ctask->r2tpool); |
2042 | (void**)tcp_ctask->r2ts); | ||
2043 | } | 2039 | } |
2044 | } | 2040 | } |
2045 | 2041 | ||
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h index eb3784f949fd..d49d87611e82 100644 --- a/drivers/scsi/iscsi_tcp.h +++ b/drivers/scsi/iscsi_tcp.h | |||
@@ -175,9 +175,8 @@ struct iscsi_tcp_cmd_task { | |||
175 | uint32_t exp_datasn; /* expected target's R2TSN/DataSN */ | 175 | uint32_t exp_datasn; /* expected target's R2TSN/DataSN */ |
176 | int data_offset; | 176 | int data_offset; |
177 | struct iscsi_r2t_info *r2t; /* in progress R2T */ | 177 | struct iscsi_r2t_info *r2t; /* in progress R2T */ |
178 | struct iscsi_queue r2tpool; | 178 | struct iscsi_pool r2tpool; |
179 | struct kfifo *r2tqueue; | 179 | struct kfifo *r2tqueue; |
180 | struct iscsi_r2t_info **r2ts; | ||
181 | int digest_count; | 180 | int digest_count; |
182 | uint32_t immdigest; /* for imm data */ | 181 | uint32_t immdigest; /* for imm data */ |
183 | struct iscsi_buf immbuf; /* for imm data digest */ | 182 | struct iscsi_buf immbuf; /* for imm data digest */ |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 59365864c989..d43f909a022c 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -1413,59 +1413,64 @@ done: | |||
1413 | } | 1413 | } |
1414 | EXPORT_SYMBOL_GPL(iscsi_eh_device_reset); | 1414 | EXPORT_SYMBOL_GPL(iscsi_eh_device_reset); |
1415 | 1415 | ||
1416 | /* | ||
1417 | * Pre-allocate a pool of @max items of @item_size. By default, the pool | ||
1418 | * should be accessed via kfifo_{get,put} on q->queue. | ||
1419 | * Optionally, the caller can obtain the array of object pointers | ||
1420 | * by passing in a non-NULL @items pointer | ||
1421 | */ | ||
1416 | int | 1422 | int |
1417 | iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size) | 1423 | iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size) |
1418 | { | 1424 | { |
1419 | int i; | 1425 | int i, num_arrays = 1; |
1420 | 1426 | ||
1421 | *items = kmalloc(max * sizeof(void*), GFP_KERNEL); | 1427 | memset(q, 0, sizeof(*q)); |
1422 | if (*items == NULL) | ||
1423 | return -ENOMEM; | ||
1424 | 1428 | ||
1425 | q->max = max; | 1429 | q->max = max; |
1426 | q->pool = kmalloc(max * sizeof(void*), GFP_KERNEL); | 1430 | |
1427 | if (q->pool == NULL) { | 1431 | /* If the user passed an items pointer, he wants a copy of |
1428 | kfree(*items); | 1432 | * the array. */ |
1429 | return -ENOMEM; | 1433 | if (items) |
1430 | } | 1434 | num_arrays++; |
1435 | q->pool = kzalloc(num_arrays * max * sizeof(void*), GFP_KERNEL); | ||
1436 | if (q->pool == NULL) | ||
1437 | goto enomem; | ||
1431 | 1438 | ||
1432 | q->queue = kfifo_init((void*)q->pool, max * sizeof(void*), | 1439 | q->queue = kfifo_init((void*)q->pool, max * sizeof(void*), |
1433 | GFP_KERNEL, NULL); | 1440 | GFP_KERNEL, NULL); |
1434 | if (q->queue == ERR_PTR(-ENOMEM)) { | 1441 | if (q->queue == ERR_PTR(-ENOMEM)) |
1435 | kfree(q->pool); | 1442 | goto enomem; |
1436 | kfree(*items); | ||
1437 | return -ENOMEM; | ||
1438 | } | ||
1439 | 1443 | ||
1440 | for (i = 0; i < max; i++) { | 1444 | for (i = 0; i < max; i++) { |
1441 | q->pool[i] = kmalloc(item_size, GFP_KERNEL); | 1445 | q->pool[i] = kzalloc(item_size, GFP_KERNEL); |
1442 | if (q->pool[i] == NULL) { | 1446 | if (q->pool[i] == NULL) { |
1443 | int j; | 1447 | q->max = i; |
1444 | 1448 | goto enomem; | |
1445 | for (j = 0; j < i; j++) | ||
1446 | kfree(q->pool[j]); | ||
1447 | |||
1448 | kfifo_free(q->queue); | ||
1449 | kfree(q->pool); | ||
1450 | kfree(*items); | ||
1451 | return -ENOMEM; | ||
1452 | } | 1449 | } |
1453 | memset(q->pool[i], 0, item_size); | ||
1454 | (*items)[i] = q->pool[i]; | ||
1455 | __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*)); | 1450 | __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*)); |
1456 | } | 1451 | } |
1452 | |||
1453 | if (items) { | ||
1454 | *items = q->pool + max; | ||
1455 | memcpy(*items, q->pool, max * sizeof(void *)); | ||
1456 | } | ||
1457 | |||
1457 | return 0; | 1458 | return 0; |
1459 | |||
1460 | enomem: | ||
1461 | iscsi_pool_free(q); | ||
1462 | return -ENOMEM; | ||
1458 | } | 1463 | } |
1459 | EXPORT_SYMBOL_GPL(iscsi_pool_init); | 1464 | EXPORT_SYMBOL_GPL(iscsi_pool_init); |
1460 | 1465 | ||
1461 | void iscsi_pool_free(struct iscsi_queue *q, void **items) | 1466 | void iscsi_pool_free(struct iscsi_pool *q) |
1462 | { | 1467 | { |
1463 | int i; | 1468 | int i; |
1464 | 1469 | ||
1465 | for (i = 0; i < q->max; i++) | 1470 | for (i = 0; i < q->max; i++) |
1466 | kfree(items[i]); | 1471 | kfree(q->pool[i]); |
1467 | kfree(q->pool); | 1472 | if (q->pool) |
1468 | kfree(items); | 1473 | kfree(q->pool); |
1469 | } | 1474 | } |
1470 | EXPORT_SYMBOL_GPL(iscsi_pool_free); | 1475 | EXPORT_SYMBOL_GPL(iscsi_pool_free); |
1471 | 1476 | ||
@@ -1610,9 +1615,9 @@ module_put: | |||
1610 | cls_session_fail: | 1615 | cls_session_fail: |
1611 | scsi_remove_host(shost); | 1616 | scsi_remove_host(shost); |
1612 | add_host_fail: | 1617 | add_host_fail: |
1613 | iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); | 1618 | iscsi_pool_free(&session->mgmtpool); |
1614 | mgmtpool_alloc_fail: | 1619 | mgmtpool_alloc_fail: |
1615 | iscsi_pool_free(&session->cmdpool, (void**)session->cmds); | 1620 | iscsi_pool_free(&session->cmdpool); |
1616 | cmdpool_alloc_fail: | 1621 | cmdpool_alloc_fail: |
1617 | scsi_host_put(shost); | 1622 | scsi_host_put(shost); |
1618 | return NULL; | 1623 | return NULL; |
@@ -1635,8 +1640,8 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) | |||
1635 | iscsi_unblock_session(cls_session); | 1640 | iscsi_unblock_session(cls_session); |
1636 | scsi_remove_host(shost); | 1641 | scsi_remove_host(shost); |
1637 | 1642 | ||
1638 | iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); | 1643 | iscsi_pool_free(&session->mgmtpool); |
1639 | iscsi_pool_free(&session->cmdpool, (void**)session->cmds); | 1644 | iscsi_pool_free(&session->cmdpool); |
1640 | 1645 | ||
1641 | kfree(session->password); | 1646 | kfree(session->password); |
1642 | kfree(session->password_in); | 1647 | kfree(session->password_in); |