diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-01-07 18:24:14 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-01-18 21:22:05 -0500 |
commit | d7e8eb5d9216c6a4f963aa6d07e29680af17d739 (patch) | |
tree | 2697c2a5e59174ce97e5e393b01edd32b8a55462 | |
parent | 4442dc8a92b8f9ad8ee9e7f8438f4c04c03a22dc (diff) |
target/rd: Add support for protection SGL setup + release
This patch adds rd_build_prot_space() + rd_release_prot_space() logic
to setup + release protection information scatterlists.
It also adds rd_init_prot() + rd_free_prot() se_subsystem_api
callbacks used by target core code for setup + release of
protection information.
v2 changes:
- Drop unused sg_table from rd_release_prot_space (Wei)
- Drop rd_release_prot_space call from rd_free_device
Cc: Martin K. Petersen <martin.petersen@oracle.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r-- | drivers/target/target_core_rd.c | 74 | ||||
-rw-r--r-- | drivers/target/target_core_rd.h | 4 |
2 files changed, 78 insertions, 0 deletions
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index e9fa879ac27f..660961d9e106 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c | |||
@@ -223,6 +223,61 @@ static int rd_build_device_space(struct rd_dev *rd_dev) | |||
223 | return 0; | 223 | return 0; |
224 | } | 224 | } |
225 | 225 | ||
226 | static void rd_release_prot_space(struct rd_dev *rd_dev) | ||
227 | { | ||
228 | u32 page_count; | ||
229 | |||
230 | if (!rd_dev->sg_prot_array || !rd_dev->sg_prot_count) | ||
231 | return; | ||
232 | |||
233 | page_count = rd_release_sgl_table(rd_dev, rd_dev->sg_prot_array, | ||
234 | rd_dev->sg_prot_count); | ||
235 | |||
236 | pr_debug("CORE_RD[%u] - Released protection space for Ramdisk" | ||
237 | " Device ID: %u, pages %u in %u tables total bytes %lu\n", | ||
238 | rd_dev->rd_host->rd_host_id, rd_dev->rd_dev_id, page_count, | ||
239 | rd_dev->sg_table_count, (unsigned long)page_count * PAGE_SIZE); | ||
240 | |||
241 | rd_dev->sg_prot_array = NULL; | ||
242 | rd_dev->sg_prot_count = 0; | ||
243 | } | ||
244 | |||
245 | static int rd_build_prot_space(struct rd_dev *rd_dev, int prot_length) | ||
246 | { | ||
247 | struct rd_dev_sg_table *sg_table; | ||
248 | u32 total_sg_needed, sg_tables; | ||
249 | u32 max_sg_per_table = (RD_MAX_ALLOCATION_SIZE / | ||
250 | sizeof(struct scatterlist)); | ||
251 | int rc; | ||
252 | |||
253 | if (rd_dev->rd_flags & RDF_NULLIO) | ||
254 | return 0; | ||
255 | |||
256 | total_sg_needed = rd_dev->rd_page_count / prot_length; | ||
257 | |||
258 | sg_tables = (total_sg_needed / max_sg_per_table) + 1; | ||
259 | |||
260 | sg_table = kzalloc(sg_tables * sizeof(struct rd_dev_sg_table), GFP_KERNEL); | ||
261 | if (!sg_table) { | ||
262 | pr_err("Unable to allocate memory for Ramdisk protection" | ||
263 | " scatterlist tables\n"); | ||
264 | return -ENOMEM; | ||
265 | } | ||
266 | |||
267 | rd_dev->sg_prot_array = sg_table; | ||
268 | rd_dev->sg_prot_count = sg_tables; | ||
269 | |||
270 | rc = rd_allocate_sgl_table(rd_dev, sg_table, total_sg_needed, 0xff); | ||
271 | if (rc) | ||
272 | return rc; | ||
273 | |||
274 | pr_debug("CORE_RD[%u] - Built Ramdisk Device ID: %u prot space of" | ||
275 | " %u pages in %u tables\n", rd_dev->rd_host->rd_host_id, | ||
276 | rd_dev->rd_dev_id, total_sg_needed, rd_dev->sg_prot_count); | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | |||
226 | static struct se_device *rd_alloc_device(struct se_hba *hba, const char *name) | 281 | static struct se_device *rd_alloc_device(struct se_hba *hba, const char *name) |
227 | { | 282 | { |
228 | struct rd_dev *rd_dev; | 283 | struct rd_dev *rd_dev; |
@@ -479,6 +534,23 @@ static sector_t rd_get_blocks(struct se_device *dev) | |||
479 | return blocks_long; | 534 | return blocks_long; |
480 | } | 535 | } |
481 | 536 | ||
537 | static int rd_init_prot(struct se_device *dev) | ||
538 | { | ||
539 | struct rd_dev *rd_dev = RD_DEV(dev); | ||
540 | |||
541 | if (!dev->dev_attrib.pi_prot_type) | ||
542 | return 0; | ||
543 | |||
544 | return rd_build_prot_space(rd_dev, dev->prot_length); | ||
545 | } | ||
546 | |||
547 | static void rd_free_prot(struct se_device *dev) | ||
548 | { | ||
549 | struct rd_dev *rd_dev = RD_DEV(dev); | ||
550 | |||
551 | rd_release_prot_space(rd_dev); | ||
552 | } | ||
553 | |||
482 | static struct sbc_ops rd_sbc_ops = { | 554 | static struct sbc_ops rd_sbc_ops = { |
483 | .execute_rw = rd_execute_rw, | 555 | .execute_rw = rd_execute_rw, |
484 | }; | 556 | }; |
@@ -504,6 +576,8 @@ static struct se_subsystem_api rd_mcp_template = { | |||
504 | .show_configfs_dev_params = rd_show_configfs_dev_params, | 576 | .show_configfs_dev_params = rd_show_configfs_dev_params, |
505 | .get_device_type = sbc_get_device_type, | 577 | .get_device_type = sbc_get_device_type, |
506 | .get_blocks = rd_get_blocks, | 578 | .get_blocks = rd_get_blocks, |
579 | .init_prot = rd_init_prot, | ||
580 | .free_prot = rd_free_prot, | ||
507 | }; | 581 | }; |
508 | 582 | ||
509 | int __init rd_module_init(void) | 583 | int __init rd_module_init(void) |
diff --git a/drivers/target/target_core_rd.h b/drivers/target/target_core_rd.h index 1789d1e14395..cc46a6a89b38 100644 --- a/drivers/target/target_core_rd.h +++ b/drivers/target/target_core_rd.h | |||
@@ -33,8 +33,12 @@ struct rd_dev { | |||
33 | u32 rd_page_count; | 33 | u32 rd_page_count; |
34 | /* Number of SG tables in sg_table_array */ | 34 | /* Number of SG tables in sg_table_array */ |
35 | u32 sg_table_count; | 35 | u32 sg_table_count; |
36 | /* Number of SG tables in sg_prot_array */ | ||
37 | u32 sg_prot_count; | ||
36 | /* Array of rd_dev_sg_table_t containing scatterlists */ | 38 | /* Array of rd_dev_sg_table_t containing scatterlists */ |
37 | struct rd_dev_sg_table *sg_table_array; | 39 | struct rd_dev_sg_table *sg_table_array; |
40 | /* Array of rd_dev_sg_table containing protection scatterlists */ | ||
41 | struct rd_dev_sg_table *sg_prot_array; | ||
38 | /* Ramdisk HBA device is connected to */ | 42 | /* Ramdisk HBA device is connected to */ |
39 | struct rd_host *rd_host; | 43 | struct rd_host *rd_host; |
40 | } ____cacheline_aligned; | 44 | } ____cacheline_aligned; |