[PATCH 3/5] tcm: Unify READ_CAPACITY_* subsystem plugin handling

From: Nicholas A. Bellinger
Date: Wed Oct 13 2010 - 04:48:26 EST


From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>

This patch adds the following struct se_subsystem_api function pointer
op for READ_CAPACITY and SA READ_CAPACITY_16 emulation reponse payload
blocks:

/*
* Get the sector_t from a subsystem backstore..
*/
sector_t (*get_blocks)(struct se_device *);

and updates IBLOCK, FILEIO and RAMDISK_[DR,MCP] to return their
respective sector_t blocks for READ_CAPACITY_* emulation processing.

Signed-off-by: Nicholas A. Bellinger <nab@xxxxxxxxxxxxxxx>
Reported-by: Christoph Hellwig <hch@xxxxxx>
---
drivers/target/target_core_file.c | 41 +++++++-----------------------
drivers/target/target_core_iblock.c | 43 +++++++------------------------
drivers/target/target_core_rd.c | 39 +++++++---------------------
drivers/target/target_core_transport.c | 10 ++++++-
include/target/target_core_transport.h | 6 +++-
5 files changed, 42 insertions(+), 97 deletions(-)

diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index 97e068f..dd7abef 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -358,35 +358,6 @@ static void *fd_allocate_request(
return (void *)fd_req;
}

-/* fd_emulate_read_cap():
- *
- *
- */
-static int fd_emulate_read_cap(struct se_task *task)
-{
- struct fd_dev *fd_dev = task->se_dev->dev_ptr;
- unsigned long long blocks_long = div_u64(fd_dev->fd_dev_size,
- DEV_ATTRIB(task->se_dev)->block_size);
- u32 blocks;
-
- if (blocks_long >= 0x00000000ffffffff)
- blocks = 0xffffffff;
- else
- blocks = (u32)blocks_long;
-
- return transport_generic_emulate_readcapacity(TASK_CMD(task), blocks);
-}
-
-static int fd_emulate_read_cap16(struct se_task *task)
-{
- struct fd_dev *fd_dev = task->se_dev->dev_ptr;
- unsigned long long blocks_long = div_u64(fd_dev->fd_dev_size,
- DEV_ATTRIB(task->se_dev)->block_size);
-
- return transport_generic_emulate_readcapacity_16(TASK_CMD(task),
- blocks_long);
-}
-
static int fd_emulate_unmap(struct se_task *task)
{
struct se_cmd *cmd = TASK_CMD(task);
@@ -1137,6 +1108,15 @@ static u32 fd_get_max_sectors(struct se_device *dev)
return FD_MAX_SECTORS;
}

+static sector_t fd_get_blocks(struct se_device *dev)
+{
+ struct fd_dev *fd_dev = dev->dev_ptr;
+ unsigned long long blocks_long = div_u64(fd_dev->fd_dev_size,
+ DEV_ATTRIB(dev)->block_size);
+
+ return blocks_long;
+}
+
/* fd_get_queue_depth(): (Part of se_subsystem_api_t template)
*
*
@@ -1196,14 +1176,13 @@ static struct se_subsystem_api fileio_template = {
.get_inquiry_rev = fd_get_inquiry_rev,
.get_dma_length = fd_get_dma_length,
.get_max_sectors = fd_get_max_sectors,
+ .get_blocks = fd_get_blocks,
.get_queue_depth = fd_get_queue_depth,
.get_max_queue_depth = fd_get_max_queue_depth,
.write_pending = NULL,
};

static struct se_subsystem_api_cdb fileio_cdb_template = {
- .emulate_read_cap = fd_emulate_read_cap,
- .emulate_read_cap16 = fd_emulate_read_cap16,
.emulate_unmap = fd_emulate_unmap,
.emulate_write_same = fd_emulate_write_same_unmap,
.emulate_sync_cache = fd_emulate_sync_cache,
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 4880891..cb53fbf 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -419,37 +419,6 @@ static unsigned long long iblock_emulate_read_cap_with_block_size(
return blocks_long;
}

-static int iblock_emulate_read_cap(struct se_task *task)
-{
- struct iblock_dev *ibd = task->se_dev->dev_ptr;
- struct block_device *bd = ibd->ibd_bd;
- struct request_queue *q = bdev_get_queue(bd);
- unsigned long long blocks_long = 0;
- u32 blocks = 0;
-
- blocks_long = iblock_emulate_read_cap_with_block_size(
- task->se_dev, bd, q);
- if (blocks_long >= 0x00000000ffffffff)
- blocks = 0xffffffff;
- else
- blocks = (u32)blocks_long;
-
- return transport_generic_emulate_readcapacity(TASK_CMD(task), blocks);
-}
-
-static int iblock_emulate_read_cap16(struct se_task *task)
-{
- struct iblock_dev *ibd = task->se_dev->dev_ptr;
- struct block_device *bd = ibd->ibd_bd;
- struct request_queue *q = bdev_get_queue(bd);
- unsigned long long blocks_long;
-
- blocks_long = iblock_emulate_read_cap_with_block_size(
- task->se_dev, bd, q);
- return transport_generic_emulate_readcapacity_16(
- TASK_CMD(task), blocks_long);
-}
-
static int iblock_emulate_unmap(struct se_task *task)
{
struct iblock_dev *ibd = task->se_dev->dev_ptr;
@@ -1034,6 +1003,15 @@ static u32 iblock_get_max_sectors(struct se_device *dev)
return q->limits.max_sectors;
}

+static sector_t iblock_get_blocks(struct se_device *dev)
+{
+ struct iblock_dev *ibd = dev->dev_ptr;
+ struct block_device *bd = ibd->ibd_bd;
+ struct request_queue *q = bdev_get_queue(bd);
+
+ return iblock_emulate_read_cap_with_block_size(dev, bd, q);
+}
+
static u32 iblock_get_queue_depth(struct se_device *dev)
{
return IBLOCK_DEVICE_QUEUE_DEPTH;
@@ -1119,14 +1097,13 @@ static struct se_subsystem_api iblock_template = {
.get_inquiry_rev = iblock_get_inquiry_rev,
.get_dma_length = iblock_get_dma_length,
.get_max_sectors = iblock_get_max_sectors,
+ .get_blocks = iblock_get_blocks,
.get_queue_depth = iblock_get_queue_depth,
.get_max_queue_depth = iblock_get_max_queue_depth,
.write_pending = NULL,
};

static struct se_subsystem_api_cdb iblock_cdb_template = {
- .emulate_read_cap = iblock_emulate_read_cap,
- .emulate_read_cap16 = iblock_emulate_read_cap16,
.emulate_unmap = iblock_emulate_unmap,
.emulate_write_same = iblock_emulate_write_same_unmap,
.emulate_sync_cache = iblock_emulate_sync_cache,
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c
index e29fd09..c84213f 100644
--- a/drivers/target/target_core_rd.c
+++ b/drivers/target/target_core_rd.c
@@ -385,33 +385,6 @@ static void *rd_allocate_request(
return (void *)rd_req;
}

-/* rd_emulate_read_cap():
- *
- *
- */
-static int rd_emulate_read_cap(struct se_task *task)
-{
- struct rd_dev *rd_dev = task->se_dev->dev_ptr;
- u32 blocks = ((rd_dev->rd_page_count * PAGE_SIZE) /
- DEV_ATTRIB(task->se_dev)->block_size) - 1;
-
- if ((((rd_dev->rd_page_count * PAGE_SIZE) /
- DEV_ATTRIB(task->se_dev)->block_size) - 1) >= 0x00000000ffffffff)
- blocks = 0xffffffff;
-
- return transport_generic_emulate_readcapacity(TASK_CMD(task), blocks);
-}
-
-static int rd_emulate_read_cap16(struct se_task *task)
-{
- struct rd_dev *rd_dev = task->se_dev->dev_ptr;
- unsigned long long blocks_long = ((rd_dev->rd_page_count * PAGE_SIZE) /
- DEV_ATTRIB(task->se_dev)->block_size) - 1;
-
- return transport_generic_emulate_readcapacity_16(TASK_CMD(task),
- blocks_long);
-}
-
/* rd_get_sg_table():
*
*
@@ -1348,6 +1321,15 @@ static u32 rd_get_max_sectors(struct se_device *dev)
return RD_MAX_SECTORS;
}

+static sector_t rd_get_blocks(struct se_device *dev)
+{
+ struct rd_dev *rd_dev = dev->dev_ptr;
+ unsigned long long blocks_long = ((rd_dev->rd_page_count * PAGE_SIZE) /
+ DEV_ATTRIB(dev)->block_size) - 1;
+
+ return blocks_long;
+}
+
/* rd_get_queue_depth(): (Part of se_subsystem_api_t template)
*
*
@@ -1402,6 +1384,7 @@ static struct se_subsystem_api rd_dr_template = {
.get_inquiry_rev = rd_get_inquiry_rev,
.get_dma_length = rd_get_dma_length,
.get_max_sectors = rd_get_max_sectors,
+ .get_blocks = rd_get_blocks,
.get_queue_depth = rd_get_queue_depth,
.get_max_queue_depth = rd_get_max_queue_depth,
.do_se_mem_map = rd_DIRECT_do_se_mem_map,
@@ -1451,8 +1434,6 @@ static struct se_subsystem_api rd_mcp_template = {
};

static struct se_subsystem_api_cdb rd_cdb_template = {
- .emulate_read_cap = rd_emulate_read_cap,
- .emulate_read_cap16 = rd_emulate_read_cap16,
.emulate_unmap = NULL,
};

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index a49c190..3fb56d5 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -5548,6 +5548,8 @@ int transport_emulate_control_cdb(struct se_task *task)
struct se_cmd *cmd = TASK_CMD(task);
struct se_device *dev = SE_DEV(cmd);
struct se_subsystem_api_cdb *api_cdb = TRANSPORT(dev)->sub_cdb;
+ sector_t blocks_long;
+ unsigned int blocks;
int ret;
unsigned short service_action;

@@ -5561,7 +5563,9 @@ int transport_emulate_control_cdb(struct se_task *task)
return ret;
break;
case READ_CAPACITY:
- ret = api_cdb->emulate_read_cap(task);
+ blocks = TRANSPORT(dev)->get_blocks(dev);
+ ret = transport_generic_emulate_readcapacity(cmd,
+ blocks);
if (ret < 0)
return ret;
break;
@@ -5584,7 +5588,9 @@ int transport_emulate_control_cdb(struct se_task *task)
case SERVICE_ACTION_IN:
switch (T_TASK(cmd)->t_task_cdb[1] & 0x1f) {
case SAI_READ_CAPACITY_16:
- ret = api_cdb->emulate_read_cap16(task);
+ blocks_long = TRANSPORT(dev)->get_blocks(dev);
+ ret = transport_generic_emulate_readcapacity_16(cmd,
+ blocks_long);
if (ret < 0)
return ret;
break;
diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h
index a949dab..1c62d8c 100644
--- a/include/target/target_core_transport.h
+++ b/include/target/target_core_transport.h
@@ -318,8 +318,6 @@ struct se_mem {
* subsystem plugins.for those CDBs that cannot be emulated generically.
*/
struct se_subsystem_api_cdb {
- int (*emulate_read_cap)(struct se_task *);
- int (*emulate_read_cap16)(struct se_task *);
int (*emulate_unmap)(struct se_task *);
int (*emulate_write_same)(struct se_task *);
void (*emulate_sync_cache)(struct se_task *);
@@ -572,6 +570,10 @@ struct se_subsystem_api {
*/
u32 (*get_max_sectors)(struct se_device *);
/*
+ * Get the sector_t from a subsystem backstore..
+ */
+ sector_t (*get_blocks)(struct se_device *);
+ /*
* get_queue_depth():
*
*/
--
1.5.6.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/