bdev/iscsi: apply max_unmap and max_unmap_segments to bdev layer

The bdev layer can do the unmap split now based on the backend
device.  For now we only use 1 unmap descriptor, the bdev layer
can help us to do the split.

Fix issue #1888

Change-Id: Iaf740bafd4f2bb4b108133fee2aafd2f53da9b2b
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7519
Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Changpeng Liu 2021-04-21 17:59:33 +08:00 committed by Tomasz Zawadzki
parent 2594e757e5
commit b885e23b95

View File

@ -64,6 +64,13 @@ struct bdev_iscsi_lun;
*/
#define BDEV_ISCSI_DEFAULT_MAX_UNMAP_LBA_COUNT (32768)
/* MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT:
* indicates the maximum number of UNMAP block descriptors that
* shall be contained in the parameter data transferred to the
* device server for an UNMAP command.
*/
#define BDEV_ISCSI_MAX_UNMAP_BLOCK_DESCS_COUNT (1)
static int bdev_iscsi_initialize(void);
static TAILQ_HEAD(, bdev_iscsi_conn_req) g_iscsi_conn_req = TAILQ_HEAD_INITIALIZER(
g_iscsi_conn_req);
@ -90,6 +97,7 @@ struct bdev_iscsi_lun {
struct spdk_poller *no_main_ch_poller;
struct spdk_thread *no_main_ch_poller_td;
bool unmap_supported;
uint32_t max_unmap;
struct spdk_poller *poller;
};
@ -319,17 +327,41 @@ bdev_iscsi_unmap(struct bdev_iscsi_lun *lun, struct bdev_iscsi_io *iscsi_io,
uint64_t lba, uint64_t num_blocks)
{
struct scsi_task *task;
struct unmap_list list[1];
struct unmap_list list[BDEV_ISCSI_MAX_UNMAP_BLOCK_DESCS_COUNT] = {};
struct unmap_list *entry;
uint32_t num_unmap_list;
uint64_t offset, remaining, unmap_blocks;
list[0].lba = lba;
list[0].num = num_blocks;
task = iscsi_unmap_task(lun->context, 0, 0, 0, list, 1,
num_unmap_list = spdk_divide_round_up(num_blocks, lun->max_unmap);
if (num_unmap_list > BDEV_ISCSI_MAX_UNMAP_BLOCK_DESCS_COUNT) {
SPDK_ERRLOG("Too many unmap entries\n");
goto failed;
}
remaining = num_blocks;
offset = lba;
num_unmap_list = 0;
entry = &list[0];
do {
unmap_blocks = spdk_min(remaining, lun->max_unmap);
entry->lba = offset;
entry->num = unmap_blocks;
num_unmap_list++;
remaining -= unmap_blocks;
offset += unmap_blocks;
entry++;
} while (remaining > 0);
task = iscsi_unmap_task(lun->context, 0, 0, 0, list, num_unmap_list,
bdev_iscsi_command_cb, iscsi_io);
if (task == NULL) {
SPDK_ERRLOG("failed to get unmap_task\n");
bdev_iscsi_io_complete(iscsi_io, SPDK_BDEV_IO_STATUS_FAILED);
if (task != NULL) {
return;
}
SPDK_ERRLOG("failed to get unmap_task\n");
failed:
bdev_iscsi_io_complete(iscsi_io, SPDK_BDEV_IO_STATUS_FAILED);
}
static void
@ -655,6 +687,11 @@ create_iscsi_lun(struct bdev_iscsi_conn_req *req, uint64_t num_blocks,
lun->bdev.blockcnt = num_blocks;
lun->bdev.ctxt = lun;
lun->unmap_supported = req->unmap_supported;
if (lun->unmap_supported) {
lun->max_unmap = req->max_unmap;
lun->bdev.max_unmap = req->max_unmap;
lun->bdev.max_unmap_segments = BDEV_ISCSI_MAX_UNMAP_BLOCK_DESCS_COUNT;
}
lun->bdev.fn_table = &iscsi_fn_table;