Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

target: Merge sbc_verify_dif_read|write

Instead of providing DIF verify routines for read/write
that are almost identical and conditionally copy protection
information, just let the caller do the right thing.

Have a single sbc_dif_verify that handles an sgl (that
does NOT copy any data) and a protection information copy
routine used by rd_mcp and fileio backend.

In the WRITE case, call sbc_dif_verify with cmd->t_prot_sg
and then do the copy from it to local sgl (assuming the verify
succeeded of course). In the READ case, call sbc_dif_verify
with the local sgl and if it succeeds, copy it to t_prot_sg (or
not if we are stripping it).

(Fix apply breakage from commit c836777 - nab)

Tested-by: Akinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

authored by

Sagi Grimberg and committed by
Nicholas Bellinger
f75b6fae b2feda4f

+37 -112
+6 -4
drivers/target/target_core_file.c
··· 643 643 if (ret > 0 && cmd->prot_type && dev->dev_attrib.pi_prot_type) { 644 644 u32 sectors = cmd->data_length / dev->dev_attrib.block_size; 645 645 646 - rc = sbc_dif_verify_read(cmd, cmd->t_task_lba, sectors, 647 - 0, fd_prot.prot_sg, 0); 646 + rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 647 + 0, fd_prot.prot_sg, 0); 648 648 if (rc) { 649 649 kfree(fd_prot.prot_sg); 650 650 kfree(fd_prot.prot_buf); 651 651 return rc; 652 652 } 653 + sbc_dif_copy_prot(cmd, sectors, true, fd_prot.prot_sg, 0); 653 654 kfree(fd_prot.prot_sg); 654 655 kfree(fd_prot.prot_buf); 655 656 } ··· 664 663 if (ret < 0) 665 664 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 666 665 667 - rc = sbc_dif_verify_write(cmd, cmd->t_task_lba, sectors, 668 - 0, fd_prot.prot_sg, 0); 666 + rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 667 + 0, cmd->t_prot_sg, 0); 669 668 if (rc) { 670 669 kfree(fd_prot.prot_sg); 671 670 kfree(fd_prot.prot_buf); 672 671 return rc; 673 672 } 673 + sbc_dif_copy_prot(cmd, sectors, false, fd_prot.prot_sg, 0); 674 674 } 675 675 676 676 ret = fd_do_rw(cmd, sgl, sgl_nents, 1);
+13 -7
drivers/target/target_core_rd.c
··· 403 403 return NULL; 404 404 } 405 405 406 - typedef sense_reason_t (*dif_verify)(struct se_cmd *, sector_t, unsigned int, 407 - unsigned int, struct scatterlist *, int); 408 - 409 - static sense_reason_t rd_do_prot_rw(struct se_cmd *cmd, dif_verify dif_verify) 406 + static sense_reason_t rd_do_prot_rw(struct se_cmd *cmd, bool is_read) 410 407 { 411 408 struct se_device *se_dev = cmd->se_dev; 412 409 struct rd_dev *dev = RD_DEV(se_dev); ··· 463 466 464 467 #endif /* !CONFIG_ARCH_HAS_SG_CHAIN */ 465 468 466 - rc = dif_verify(cmd, cmd->t_task_lba, sectors, 0, prot_sg, prot_offset); 469 + if (is_read) 470 + rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 0, 471 + prot_sg, prot_offset); 472 + else 473 + rc = sbc_dif_verify(cmd, cmd->t_task_lba, sectors, 0, 474 + cmd->t_prot_sg, 0); 475 + 476 + if (!rc) 477 + sbc_dif_copy_prot(cmd, sectors, is_read, prot_sg, prot_offset); 478 + 467 479 if (need_to_release) 468 480 kfree(prot_sg); 469 481 ··· 518 512 519 513 if (cmd->prot_type && se_dev->dev_attrib.pi_prot_type && 520 514 data_direction == DMA_TO_DEVICE) { 521 - rc = rd_do_prot_rw(cmd, sbc_dif_verify_write); 515 + rc = rd_do_prot_rw(cmd, false); 522 516 if (rc) 523 517 return rc; 524 518 } ··· 586 580 587 581 if (cmd->prot_type && se_dev->dev_attrib.pi_prot_type && 588 582 data_direction == DMA_FROM_DEVICE) { 589 - rc = rd_do_prot_rw(cmd, sbc_dif_verify_read); 583 + rc = rd_do_prot_rw(cmd, true); 590 584 if (rc) 591 585 return rc; 592 586 }
+6 -88
drivers/target/target_core_sbc.c
··· 1266 1266 return 0; 1267 1267 } 1268 1268 1269 - static void 1270 - sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read, 1271 - struct scatterlist *sg, int sg_off) 1269 + void sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read, 1270 + struct scatterlist *sg, int sg_off) 1272 1271 { 1273 1272 struct se_device *dev = cmd->se_dev; 1274 1273 struct scatterlist *psg; ··· 1308 1309 kunmap_atomic(paddr); 1309 1310 } 1310 1311 } 1312 + EXPORT_SYMBOL(sbc_dif_copy_prot); 1311 1313 1312 1314 sense_reason_t 1313 - sbc_dif_verify_write(struct se_cmd *cmd, sector_t start, unsigned int sectors, 1314 - unsigned int ei_lba, struct scatterlist *sg, int sg_off) 1315 - { 1316 - struct se_device *dev = cmd->se_dev; 1317 - struct se_dif_v1_tuple *sdt; 1318 - struct scatterlist *dsg, *psg = cmd->t_prot_sg; 1319 - sector_t sector = start; 1320 - void *daddr, *paddr; 1321 - int i, j, offset = 0; 1322 - sense_reason_t rc; 1323 - 1324 - for_each_sg(cmd->t_data_sg, dsg, cmd->t_data_nents, i) { 1325 - daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; 1326 - paddr = kmap_atomic(sg_page(psg)) + psg->offset; 1327 - 1328 - for (j = 0; j < dsg->length; j += dev->dev_attrib.block_size) { 1329 - 1330 - if (offset >= psg->length) { 1331 - kunmap_atomic(paddr); 1332 - psg = sg_next(psg); 1333 - paddr = kmap_atomic(sg_page(psg)) + psg->offset; 1334 - offset = 0; 1335 - } 1336 - 1337 - sdt = paddr + offset; 1338 - 1339 - pr_debug("DIF WRITE sector: %llu guard_tag: 0x%04x" 1340 - " app_tag: 0x%04x ref_tag: %u\n", 1341 - (unsigned long long)sector, sdt->guard_tag, 1342 - sdt->app_tag, be32_to_cpu(sdt->ref_tag)); 1343 - 1344 - rc = sbc_dif_v1_verify(cmd, sdt, daddr + j, sector, 1345 - ei_lba); 1346 - if (rc) { 1347 - kunmap_atomic(paddr); 1348 - kunmap_atomic(daddr); 1349 - cmd->bad_sector = sector; 1350 - return rc; 1351 - } 1352 - 1353 - sector++; 1354 - ei_lba++; 1355 - offset += sizeof(struct se_dif_v1_tuple); 1356 - } 1357 - 1358 - kunmap_atomic(paddr); 1359 - kunmap_atomic(daddr); 1360 - } 1361 - if (!sg) 1362 - return 0; 1363 - 1364 - sbc_dif_copy_prot(cmd, sectors, false, sg, sg_off); 1365 - 1366 - return 0; 1367 - } 1368 - EXPORT_SYMBOL(sbc_dif_verify_write); 1369 - 1370 - static sense_reason_t 1371 - __sbc_dif_verify_read(struct se_cmd *cmd, sector_t start, unsigned int sectors, 1372 - unsigned int ei_lba, struct scatterlist *sg, int sg_off) 1315 + sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors, 1316 + unsigned int ei_lba, struct scatterlist *sg, int sg_off) 1373 1317 { 1374 1318 struct se_device *dev = cmd->se_dev; 1375 1319 struct se_dif_v1_tuple *sdt; ··· 1368 1426 1369 1427 return 0; 1370 1428 } 1371 - 1372 - sense_reason_t 1373 - sbc_dif_read_strip(struct se_cmd *cmd) 1374 - { 1375 - struct se_device *dev = cmd->se_dev; 1376 - u32 sectors = cmd->prot_length / dev->prot_length; 1377 - 1378 - return __sbc_dif_verify_read(cmd, cmd->t_task_lba, sectors, 0, 1379 - cmd->t_prot_sg, 0); 1380 - } 1381 - 1382 - sense_reason_t 1383 - sbc_dif_verify_read(struct se_cmd *cmd, sector_t start, unsigned int sectors, 1384 - unsigned int ei_lba, struct scatterlist *sg, int sg_off) 1385 - { 1386 - sense_reason_t rc; 1387 - 1388 - rc = __sbc_dif_verify_read(cmd, start, sectors, ei_lba, sg, sg_off); 1389 - if (rc) 1390 - return rc; 1391 - 1392 - sbc_dif_copy_prot(cmd, sectors, true, sg, sg_off); 1393 - return 0; 1394 - } 1395 - EXPORT_SYMBOL(sbc_dif_verify_read); 1429 + EXPORT_SYMBOL(sbc_dif_verify);
+9 -8
drivers/target/target_core_transport.c
··· 1766 1766 break; 1767 1767 1768 1768 sectors = cmd->data_length >> ilog2(cmd->se_dev->dev_attrib.block_size); 1769 - cmd->pi_err = sbc_dif_verify_write(cmd, cmd->t_task_lba, 1770 - sectors, 0, NULL, 0); 1769 + cmd->pi_err = sbc_dif_verify(cmd, cmd->t_task_lba, 1770 + sectors, 0, cmd->t_prot_sg, 0); 1771 1771 if (unlikely(cmd->pi_err)) { 1772 1772 spin_lock_irq(&cmd->t_state_lock); 1773 1773 cmd->transport_state &= ~(CMD_T_BUSY|CMD_T_SENT); ··· 1991 1991 1992 1992 static bool target_read_prot_action(struct se_cmd *cmd) 1993 1993 { 1994 - sense_reason_t rc; 1995 - 1996 1994 switch (cmd->prot_op) { 1997 1995 case TARGET_PROT_DIN_STRIP: 1998 1996 if (!(cmd->se_sess->sup_prot_ops & TARGET_PROT_DIN_STRIP)) { 1999 - rc = sbc_dif_read_strip(cmd); 2000 - if (rc) { 2001 - cmd->pi_err = rc; 1997 + u32 sectors = cmd->data_length >> 1998 + ilog2(cmd->se_dev->dev_attrib.block_size); 1999 + 2000 + cmd->pi_err = sbc_dif_verify(cmd, cmd->t_task_lba, 2001 + sectors, 0, cmd->t_prot_sg, 2002 + 0); 2003 + if (cmd->pi_err) 2002 2004 return true; 2003 - } 2004 2005 } 2005 2006 break; 2006 2007 case TARGET_PROT_DIN_INSERT:
+3 -5
include/target/target_core_backend.h
··· 84 84 sector_t lba, sector_t nolb), 85 85 void *priv); 86 86 void sbc_dif_generate(struct se_cmd *); 87 - sense_reason_t sbc_dif_verify_write(struct se_cmd *, sector_t, unsigned int, 87 + sense_reason_t sbc_dif_verify(struct se_cmd *, sector_t, unsigned int, 88 88 unsigned int, struct scatterlist *, int); 89 - sense_reason_t sbc_dif_verify_read(struct se_cmd *, sector_t, unsigned int, 90 - unsigned int, struct scatterlist *, int); 91 - sense_reason_t sbc_dif_read_strip(struct se_cmd *); 92 - 89 + void sbc_dif_copy_prot(struct se_cmd *, unsigned int, bool, 90 + struct scatterlist *, int); 93 91 void transport_set_vpd_proto_id(struct t10_vpd *, unsigned char *); 94 92 int transport_set_vpd_assoc(struct t10_vpd *, unsigned char *); 95 93 int transport_set_vpd_ident_type(struct t10_vpd *, unsigned char *);