Move block_size and block_shift into struct scst_device and by it simplify and cleanup processing

git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4246 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2012-04-27 20:31:57 +00:00
parent e119078248
commit 4a344f5674
11 changed files with 217 additions and 366 deletions
+16 -15
View File
@@ -1998,6 +1998,8 @@ struct scst_cmd {
int expected_transfer_len;
int expected_out_transfer_len; /* for bidi writes */
int64_t lba; /* LBA of this cmd in blocks */
/*
* Cmd data length. Could be different from bufflen for commands like
* VERIFY, which transfer different amount of data (if any), than
@@ -2010,7 +2012,6 @@ struct scst_cmd {
enum scst_exec_context pref_context);
struct sgv_pool_obj *sgv; /* sgv object */
int64_t lba; /* LBA of this cmd in blocks */
int bufflen; /* cmd buffer length */
int sg_cnt; /* SG segments count */
struct scatterlist *sg; /* cmd data buffer SG vector */
@@ -2323,6 +2324,13 @@ struct scst_device {
*/
int pr_readers_count;
/*
* Device block size and block shift if fixed size blocks used. Supposed
* to be read-only or serialized the same way as MODE pages changes.
*/
int block_size;
int block_shift;
/*
* Set if dev is persistently reserved. Protected by dev_pr_mutex.
* Modified independently to the above field, hence the alignment.
@@ -4154,20 +4162,13 @@ struct scatterlist *scst_alloc(int size, gfp_t gfp_mask, int *count);
void scst_free(struct scatterlist *sg, int count);
int scst_calc_block_shift(int sector_size);
int scst_sbc_generic_parse(struct scst_cmd *cmd,
int (*get_block_shift)(struct scst_cmd *cmd));
int scst_cdrom_generic_parse(struct scst_cmd *cmd,
int (*get_block_shift)(struct scst_cmd *cmd));
int scst_modisk_generic_parse(struct scst_cmd *cmd,
int (*get_block_shift)(struct scst_cmd *cmd));
int scst_tape_generic_parse(struct scst_cmd *cmd,
int (*get_block_size)(struct scst_cmd *cmd));
int scst_changer_generic_parse(struct scst_cmd *cmd,
int (*nothing)(struct scst_cmd *cmd));
int scst_processor_generic_parse(struct scst_cmd *cmd,
int (*nothing)(struct scst_cmd *cmd));
int scst_raid_generic_parse(struct scst_cmd *cmd,
int (*nothing)(struct scst_cmd *cmd));
int scst_sbc_generic_parse(struct scst_cmd *cmd);
int scst_cdrom_generic_parse(struct scst_cmd *cmd);
int scst_modisk_generic_parse(struct scst_cmd *cmd);
int scst_tape_generic_parse(struct scst_cmd *cmd);
int scst_changer_generic_parse(struct scst_cmd *cmd);
int scst_processor_generic_parse(struct scst_cmd *cmd);
int scst_raid_generic_parse(struct scst_cmd *cmd);
int scst_block_generic_dev_done(struct scst_cmd *cmd,
void (*set_block_shift)(struct scst_cmd *cmd, int block_shift));
+13 -49
View File
@@ -37,10 +37,6 @@
#define CDROM_DEF_BLOCK_SHIFT 11
struct cdrom_params {
int block_shift;
};
static int cdrom_attach(struct scst_device *);
static void cdrom_detach(struct scst_device *);
static int cdrom_parse(struct scst_cmd *);
@@ -71,7 +67,6 @@ static int cdrom_attach(struct scst_device *dev)
int retries;
unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE];
enum dma_data_direction data_dir;
struct cdrom_params *params;
TRACE_ENTRY();
@@ -82,20 +77,12 @@ static int cdrom_attach(struct scst_device *dev)
goto out;
}
params = kzalloc(sizeof(*params), GFP_KERNEL);
if (params == NULL) {
PRINT_ERROR("Unable to allocate struct cdrom_params (size %zd)",
sizeof(*params));
res = -ENOMEM;
goto out;
}
buffer = kmalloc(buffer_size, GFP_KERNEL);
if (!buffer) {
PRINT_ERROR("Buffer memory allocation (size %d) failure",
buffer_size);
res = -ENOMEM;
goto out_free_params;
goto out;
}
/* Clear any existing UA's and get cdrom capacity (cdrom block size) */
@@ -129,7 +116,7 @@ static int cdrom_attach(struct scst_device *dev)
if (!--retries) {
PRINT_ERROR("UA not cleared after %d retries",
SCST_DEV_UA_RETRIES);
params->block_shift = CDROM_DEF_BLOCK_SHIFT;
dev->block_shift = CDROM_DEF_BLOCK_SHIFT;
res = -ENODEV;
goto out_free_buf;
}
@@ -138,19 +125,19 @@ static int cdrom_attach(struct scst_device *dev)
if (rc == 0) {
uint32_t sector_size = get_unaligned_be32(&buffer[4]);
if (sector_size == 0)
params->block_shift = CDROM_DEF_BLOCK_SHIFT;
dev->block_shift = CDROM_DEF_BLOCK_SHIFT;
else
params->block_shift =
scst_calc_block_shift(sector_size);
dev->block_shift = scst_calc_block_shift(sector_size);
TRACE_DBG("Sector size is %i scsi_level %d(SCSI_2 %d)",
sector_size, dev->scsi_dev->scsi_level, SCSI_2);
} else {
params->block_shift = CDROM_DEF_BLOCK_SHIFT;
dev->block_shift = CDROM_DEF_BLOCK_SHIFT;
TRACE(TRACE_MINOR, "Read capacity failed: %x, using default "
"sector size %d", rc, params->block_shift);
"sector size %d", rc, dev->block_shift);
PRINT_BUFF_FLAG(TRACE_MINOR, "Returned sense", sense_buffer,
sizeof(sense_buffer));
}
dev->block_size = 1 << dev->block_shift;
res = scst_obtain_device_parameters(dev);
if (res != 0) {
@@ -162,12 +149,6 @@ static int cdrom_attach(struct scst_device *dev)
out_free_buf:
kfree(buffer);
out_free_params:
if (res == 0)
dev->dh_priv = params;
else
kfree(params);
out:
TRACE_EXIT();
return res;
@@ -175,33 +156,15 @@ out:
static void cdrom_detach(struct scst_device *dev)
{
struct cdrom_params *params =
(struct cdrom_params *)dev->dh_priv;
TRACE_ENTRY();
kfree(params);
dev->dh_priv = NULL;
TRACE_EXIT();
/* Nothing to do */
return;
}
static int cdrom_get_block_shift(struct scst_cmd *cmd)
{
struct cdrom_params *params = (struct cdrom_params *)cmd->dev->dh_priv;
/*
* No need for locks here, since *_detach() can not be
* called, when there are existing commands.
*/
return params->block_shift;
}
static int cdrom_parse(struct scst_cmd *cmd)
{
int res = SCST_CMD_STATE_DEFAULT, rc;
rc = scst_cdrom_generic_parse(cmd, cdrom_get_block_shift);
rc = scst_cdrom_generic_parse(cmd);
if (rc != 0) {
res = scst_get_cmd_abnormal_done_state(cmd);
goto out;
@@ -214,15 +177,16 @@ out:
static void cdrom_set_block_shift(struct scst_cmd *cmd, int block_shift)
{
struct cdrom_params *params = (struct cdrom_params *)cmd->dev->dh_priv;
struct scst_device *dev = cmd->dev;
/*
* No need for locks here, since *_detach() can not be
* called, when there are existing commands.
*/
if (block_shift != 0)
params->block_shift = block_shift;
dev->block_shift = block_shift;
else
params->block_shift = CDROM_DEF_BLOCK_SHIFT;
dev->block_shift = CDROM_DEF_BLOCK_SHIFT;
dev->block_size = 1 << dev->block_shift;
return;
}
+1 -1
View File
@@ -124,7 +124,7 @@ static int changer_parse(struct scst_cmd *cmd)
{
int res = SCST_CMD_STATE_DEFAULT, rc;
rc = scst_changer_generic_parse(cmd, NULL);
rc = scst_changer_generic_parse(cmd);
if (rc != 0) {
res = scst_get_cmd_abnormal_done_state(cmd);
goto out;
+23 -59
View File
@@ -43,10 +43,6 @@
#define DISK_DEF_BLOCK_SHIFT 9
struct disk_params {
int block_shift;
};
static int disk_attach(struct scst_device *dev);
static void disk_detach(struct scst_device *dev);
static int disk_parse(struct scst_cmd *cmd);
@@ -168,7 +164,6 @@ static int disk_attach(struct scst_device *dev)
int retries;
unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE];
enum dma_data_direction data_dir;
struct disk_params *params;
TRACE_ENTRY();
@@ -179,20 +174,12 @@ static int disk_attach(struct scst_device *dev)
goto out;
}
params = kzalloc(sizeof(*params), GFP_KERNEL);
if (params == NULL) {
PRINT_ERROR("Unable to allocate struct disk_params (size %zd)",
sizeof(*params));
res = -ENOMEM;
goto out;
}
buffer = kmalloc(buffer_size, GFP_KERNEL);
if (!buffer) {
PRINT_ERROR("Buffer memory allocation (size %d) failure",
buffer_size);
res = -ENOMEM;
goto out_free_params;
goto out;
}
/* Clear any existing UA's and get disk capacity (disk block size) */
@@ -232,17 +219,17 @@ static int disk_attach(struct scst_device *dev)
if (rc == 0) {
uint32_t sector_size = get_unaligned_be32(&buffer[4]);
if (sector_size == 0)
params->block_shift = DISK_DEF_BLOCK_SHIFT;
dev->block_shift = DISK_DEF_BLOCK_SHIFT;
else
params->block_shift =
scst_calc_block_shift(sector_size);
dev->block_shift = scst_calc_block_shift(sector_size);
} else {
params->block_shift = DISK_DEF_BLOCK_SHIFT;
dev->block_shift = DISK_DEF_BLOCK_SHIFT;
TRACE(TRACE_MINOR, "Read capacity failed: %x, using default "
"sector size %d", rc, params->block_shift);
"sector size %d", rc, dev->block_shift);
PRINT_BUFF_FLAG(TRACE_MINOR, "Returned sense", sense_buffer,
sizeof(sense_buffer));
}
dev->block_size = 1 << dev->block_shift;
res = scst_obtain_device_parameters(dev);
if (res != 0) {
@@ -254,12 +241,6 @@ static int disk_attach(struct scst_device *dev)
out_free_buf:
kfree(buffer);
out_free_params:
if (res == 0)
dev->dh_priv = params;
else
kfree(params);
out:
TRACE_EXIT_RES(res);
return res;
@@ -267,33 +248,15 @@ out:
static void disk_detach(struct scst_device *dev)
{
struct disk_params *params =
(struct disk_params *)dev->dh_priv;
TRACE_ENTRY();
kfree(params);
dev->dh_priv = NULL;
TRACE_EXIT();
/* Nothing to do */
return;
}
static int disk_get_block_shift(struct scst_cmd *cmd)
{
struct disk_params *params = (struct disk_params *)cmd->dev->dh_priv;
/*
* No need for locks here, since *_detach() can not be
* called, when there are existing commands.
*/
return params->block_shift;
}
static int disk_parse(struct scst_cmd *cmd)
{
int res = SCST_CMD_STATE_DEFAULT, rc;
rc = scst_sbc_generic_parse(cmd, disk_get_block_shift);
rc = scst_sbc_generic_parse(cmd);
if (rc != 0) {
res = scst_get_cmd_abnormal_done_state(cmd);
goto out;
@@ -306,15 +269,16 @@ out:
static void disk_set_block_shift(struct scst_cmd *cmd, int block_shift)
{
struct disk_params *params = (struct disk_params *)cmd->dev->dh_priv;
struct scst_device *dev = cmd->dev;
/*
* No need for locks here, since *_detach() can not be
* called, when there are existing commands.
*/
if (block_shift != 0)
params->block_shift = block_shift;
dev->block_shift = block_shift;
else
params->block_shift = DISK_DEF_BLOCK_SHIFT;
dev->block_shift = DISK_DEF_BLOCK_SHIFT;
dev->block_size = 1 << dev->block_shift;
return;
}
@@ -412,14 +376,14 @@ out_complete:
static int disk_exec(struct scst_cmd *cmd)
{
int res, rc;
struct disk_params *params = (struct disk_params *)cmd->dev->dh_priv;
struct disk_work work;
struct scst_device *dev = cmd->dev;
unsigned int offset, cur_len; /* in blocks */
struct scatterlist *sg, *start_sg;
int cur_sg_cnt;
int sg_tablesize = cmd->dev->scsi_dev->host->sg_tablesize;
int max_sectors;
int num, j;
int num, j, block_shift = dev->block_shift;
TRACE_ENTRY();
@@ -427,21 +391,21 @@ static int disk_exec(struct scst_cmd *cmd)
* For PC requests we are going to submit max_hw_sectors used instead
* of max_sectors.
*/
max_sectors = queue_max_hw_sectors(cmd->dev->scsi_dev->request_queue);
max_sectors = queue_max_hw_sectors(dev->scsi_dev->request_queue);
if (unlikely(((max_sectors << params->block_shift) & ~PAGE_MASK) != 0)) {
int mlen = max_sectors << params->block_shift;
if (unlikely(((max_sectors << block_shift) & ~PAGE_MASK) != 0)) {
int mlen = max_sectors << block_shift;
int pg = ((mlen >> PAGE_SHIFT) + ((mlen & ~PAGE_MASK) != 0)) - 1;
int adj_len = pg << PAGE_SHIFT;
max_sectors = adj_len >> params->block_shift;
max_sectors = adj_len >> block_shift;
if (max_sectors == 0) {
PRINT_ERROR("Too low max sectors %d", max_sectors);
goto out_error;
}
}
if (unlikely((cmd->bufflen >> params->block_shift) > max_sectors)) {
if ((cmd->out_bufflen >> params->block_shift) > max_sectors) {
if (unlikely((cmd->bufflen >> block_shift) > max_sectors)) {
if ((cmd->out_bufflen >> block_shift) > max_sectors) {
PRINT_ERROR("Too limited max_sectors %d for "
"bidirectional cmd %x (out_bufflen %d)",
max_sectors, cmd->cdb[0], cmd->out_bufflen);
@@ -459,7 +423,7 @@ static int disk_exec(struct scst_cmd *cmd)
split:
sBUG_ON(cmd->out_sg_cnt > sg_tablesize);
sBUG_ON((cmd->out_bufflen >> params->block_shift) > max_sectors);
sBUG_ON((cmd->out_bufflen >> block_shift) > max_sectors);
/*
* We don't support changing BIDI CDBs (see disk_on_sg_tablesize_low()),
@@ -484,7 +448,7 @@ split:
"save_len %d (sg_tablesize %d, max_sectors %d, block_shift %d, "
"sizeof(*sg) 0x%zx)", cmd, work.save_sg, work.save_sg_cnt,
(unsigned long long)work.save_lba, work.save_len,
sg_tablesize, max_sectors, params->block_shift, sizeof(*sg));
sg_tablesize, max_sectors, block_shift, sizeof(*sg));
/*
* If we submit all chunks async'ly, it will be very not trivial what
@@ -510,7 +474,7 @@ split:
start_sg = sg;
}
l = sg[j].length >> params->block_shift;
l = sg[j].length >> block_shift;
cur_len += l;
cur_sg_cnt++;
+15 -51
View File
@@ -42,10 +42,6 @@
#define MODISK_DEF_BLOCK_SHIFT 10
struct modisk_params {
int block_shift;
};
static int modisk_attach(struct scst_device *);
static void modisk_detach(struct scst_device *);
static int modisk_parse(struct scst_cmd *);
@@ -156,7 +152,6 @@ static int modisk_attach(struct scst_device *dev)
int retries;
unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE];
enum dma_data_direction data_dir;
struct modisk_params *params;
TRACE_ENTRY();
@@ -167,14 +162,8 @@ static int modisk_attach(struct scst_device *dev)
goto out;
}
params = kzalloc(sizeof(*params), GFP_KERNEL);
if (params == NULL) {
PRINT_ERROR("Unable to allocate struct modisk_params (size %zd)",
sizeof(*params));
res = -ENOMEM;
goto out;
}
params->block_shift = MODISK_DEF_BLOCK_SHIFT;
dev->block_shift = MODISK_DEF_BLOCK_SHIFT;
dev->block_size = 1 << dev->block_shift;
/*
* If the device is offline, don't try to read capacity or any
@@ -183,7 +172,7 @@ static int modisk_attach(struct scst_device *dev)
if (dev->scsi_dev->sdev_state == SDEV_OFFLINE) {
TRACE_DBG("%s", "Device is offline");
res = -ENODEV;
goto out_free_params;
goto out;
}
buffer = kmalloc(buffer_size, GFP_KERNEL);
@@ -191,7 +180,7 @@ static int modisk_attach(struct scst_device *dev)
PRINT_ERROR("Buffer memory allocation (size %d) failure",
buffer_size);
res = -ENOMEM;
goto out_free_params;
goto out;
}
/*
@@ -235,19 +224,19 @@ static int modisk_attach(struct scst_device *dev)
if (rc == 0) {
uint32_t sector_size = get_unaligned_be32(&buffer[4]);
if (sector_size == 0)
params->block_shift = MODISK_DEF_BLOCK_SHIFT;
dev->block_shift = MODISK_DEF_BLOCK_SHIFT;
else
params->block_shift =
scst_calc_block_shift(sector_size);
dev->block_shift = scst_calc_block_shift(sector_size);
TRACE_DBG("Sector size is %i scsi_level %d(SCSI_2 %d)",
sector_size, dev->scsi_dev->scsi_level, SCSI_2);
} else {
params->block_shift = MODISK_DEF_BLOCK_SHIFT;
dev->block_shift = MODISK_DEF_BLOCK_SHIFT;
TRACE(TRACE_MINOR, "Read capacity failed: %x, using default "
"sector size %d", rc, params->block_shift);
"sector size %d", rc, dev->block_shift);
PRINT_BUFF_FLAG(TRACE_MINOR, "Returned sense", sense_buffer,
sizeof(sense_buffer));
}
dev->block_size = 1 << dev->block_shift;
res = scst_obtain_device_parameters(dev);
if (res != 0) {
@@ -259,12 +248,6 @@ static int modisk_attach(struct scst_device *dev)
out_free_buf:
kfree(buffer);
out_free_params:
if (res == 0)
dev->dh_priv = params;
else
kfree(params);
out:
TRACE_EXIT_RES(res);
return res;
@@ -272,34 +255,15 @@ out:
static void modisk_detach(struct scst_device *dev)
{
struct modisk_params *params =
(struct modisk_params *)dev->dh_priv;
TRACE_ENTRY();
kfree(params);
dev->dh_priv = NULL;
TRACE_EXIT();
/* Nothing to do */
return;
}
static int modisk_get_block_shift(struct scst_cmd *cmd)
{
struct modisk_params *params =
(struct modisk_params *)cmd->dev->dh_priv;
/*
* No need for locks here, since *_detach() can not be
* called, when there are existing commands.
*/
return params->block_shift;
}
static int modisk_parse(struct scst_cmd *cmd)
{
int res = SCST_CMD_STATE_DEFAULT, rc;
rc = scst_modisk_generic_parse(cmd, modisk_get_block_shift);
rc = scst_modisk_generic_parse(cmd);
if (rc != 0) {
res = scst_get_cmd_abnormal_done_state(cmd);
goto out;
@@ -312,16 +276,16 @@ out:
static void modisk_set_block_shift(struct scst_cmd *cmd, int block_shift)
{
struct modisk_params *params =
(struct modisk_params *)cmd->dev->dh_priv;
struct scst_device *dev = cmd->dev;
/*
* No need for locks here, since *_detach() can not be
* called, when there are existing commands.
*/
if (block_shift != 0)
params->block_shift = block_shift;
dev->block_shift = block_shift;
else
params->block_shift = MODISK_DEF_BLOCK_SHIFT;
dev->block_shift = MODISK_DEF_BLOCK_SHIFT;
dev->block_size = 1 << dev->block_shift;
return;
}
+1 -1
View File
@@ -124,7 +124,7 @@ static int processor_parse(struct scst_cmd *cmd)
{
int res = SCST_CMD_STATE_DEFAULT, rc;
rc = scst_processor_generic_parse(cmd, NULL);
rc = scst_processor_generic_parse(cmd);
if (rc != 0) {
res = scst_get_cmd_abnormal_done_state(cmd);
goto out;
+1 -1
View File
@@ -124,7 +124,7 @@ static int raid_parse(struct scst_cmd *cmd)
{
int res = SCST_CMD_STATE_DEFAULT, rc;
rc = scst_raid_generic_parse(cmd, NULL);
rc = scst_raid_generic_parse(cmd);
if (rc != 0) {
res = scst_get_cmd_abnormal_done_state(cmd);
goto out;
+15 -49
View File
@@ -37,8 +37,8 @@
#endif
#include "scst_dev_handler.h"
# define TAPE_NAME "dev_tape"
# define TAPE_PERF_NAME "dev_tape_perf"
#define TAPE_NAME "dev_tape"
#define TAPE_PERF_NAME "dev_tape_perf"
#define TAPE_RETRIES 2
@@ -47,10 +47,6 @@
/* The fixed bit in READ/WRITE/VERIFY */
#define SILI_BIT 2
struct tape_params {
int block_size;
};
static int tape_attach(struct scst_device *);
static void tape_detach(struct scst_device *);
static int tape_parse(struct scst_cmd *);
@@ -159,7 +155,6 @@ static int tape_attach(struct scst_device *dev)
struct scsi_mode_data data;
const int buffer_size = 512;
uint8_t *buffer = NULL;
struct tape_params *params;
TRACE_ENTRY();
@@ -170,22 +165,15 @@ static int tape_attach(struct scst_device *dev)
goto out;
}
params = kzalloc(sizeof(*params), GFP_KERNEL);
if (params == NULL) {
PRINT_ERROR("Unable to allocate struct tape_params (size %zd)",
sizeof(*params));
res = -ENOMEM;
goto out;
}
params->block_size = TAPE_DEF_BLOCK_SIZE;
dev->block_size = TAPE_DEF_BLOCK_SIZE;
dev->block_shift = scst_calc_block_shift(dev->block_size);
buffer = kmalloc(buffer_size, GFP_KERNEL);
if (!buffer) {
PRINT_ERROR("Buffer memory allocation (size %d) failure",
buffer_size);
res = -ENOMEM;
goto out_free_req;
goto out;
}
retries = SCST_DEV_UA_RETRIES;
@@ -220,21 +208,22 @@ static int tape_attach(struct scst_device *dev)
if (rc == 0) {
int medium_type, mode, speed, density;
if (buffer[3] == 8) {
params->block_size = get_unaligned_be24(&buffer[9]);
dev->block_size = get_unaligned_be24(&buffer[9]);
} else
params->block_size = TAPE_DEF_BLOCK_SIZE;
dev->block_size = TAPE_DEF_BLOCK_SIZE;
medium_type = buffer[1];
mode = (buffer[2] & 0x70) >> 4;
speed = buffer[2] & 0x0f;
density = buffer[4];
TRACE_DBG("Tape: lun %d. bs %d. type 0x%02x mode 0x%02x "
"speed 0x%02x dens 0x%02x", dev->scsi_dev->lun,
params->block_size, medium_type, mode, speed, density);
dev->block_size, medium_type, mode, speed, density);
} else {
PRINT_ERROR("MODE_SENSE failed: %x", rc);
res = -ENODEV;
goto out_free_buf;
}
dev->block_shift = scst_calc_block_shift(dev->block_size);
obtain:
res = scst_obtain_device_parameters(dev);
@@ -247,12 +236,6 @@ obtain:
out_free_buf:
kfree(buffer);
out_free_req:
if (res == 0)
dev->dh_priv = params;
else
kfree(params);
out:
TRACE_EXIT_RES(res);
return res;
@@ -260,33 +243,15 @@ out:
static void tape_detach(struct scst_device *dev)
{
struct tape_params *params =
(struct tape_params *)dev->dh_priv;
TRACE_ENTRY();
kfree(params);
dev->dh_priv = NULL;
TRACE_EXIT();
/* Nothing to do */
return;
}
static int tape_get_block_size(struct scst_cmd *cmd)
{
struct tape_params *params = (struct tape_params *)cmd->dev->dh_priv;
/*
* No need for locks here, since *_detach() can not be called,
* when there are existing commands.
*/
return params->block_size;
}
static int tape_parse(struct scst_cmd *cmd)
{
int res = SCST_CMD_STATE_DEFAULT, rc;
rc = scst_tape_generic_parse(cmd, tape_get_block_size);
rc = scst_tape_generic_parse(cmd);
if (rc != 0) {
res = scst_get_cmd_abnormal_done_state(cmd);
goto out;
@@ -299,12 +264,13 @@ out:
static void tape_set_block_size(struct scst_cmd *cmd, int block_size)
{
struct tape_params *params = (struct tape_params *)cmd->dev->dh_priv;
struct scst_device *dev = cmd->dev;
/*
* No need for locks here, since *_detach() can not be called, when
* there are existing commands.
*/
params->block_size = block_size;
dev->block_size = block_size;
dev->block_shift = scst_calc_block_shift(dev->block_size);
return;
}
@@ -357,7 +323,7 @@ static int tape_done(struct scst_cmd *cmd)
*/
params = (struct tape_params *)
cmd->dev->dh_priv;
resp_data_len *= params->block_size;
resp_data_len *= cmd->dev->block_size;
}
scst_set_resp_data_len(cmd, resp_data_len);
}
+53 -34
View File
@@ -69,11 +69,9 @@ struct scst_user_dev {
unsigned int d_sense:1;
unsigned int has_own_order_mgmt:1;
int (*generic_parse)(struct scst_cmd *cmd,
int (*get_block)(struct scst_cmd *cmd));
int (*generic_parse)(struct scst_cmd *cmd);
int block;
int def_block;
int def_block_size;
struct scst_mem_lim udev_mem_lim;
struct sgv_pool *pool;
@@ -724,17 +722,6 @@ out:
return ucmd;
}
static int dev_user_get_block(struct scst_cmd *cmd)
{
struct scst_user_dev *dev = cmd->dev->dh_priv;
/*
* No need for locks here, since *_detach() can not be
* called, when there are existing commands.
*/
TRACE_EXIT_RES(dev->block);
return dev->block;
}
static int dev_user_parse(struct scst_cmd *cmd)
{
int rc, res = SCST_CMD_STATE_DEFAULT;
@@ -775,7 +762,7 @@ static int dev_user_parse(struct scst_cmd *cmd)
switch (dev->parse_type) {
case SCST_USER_PARSE_STANDARD:
TRACE_DBG("PARSE STANDARD: ucmd %p", ucmd);
rc = dev->generic_parse(cmd, dev_user_get_block);
rc = dev->generic_parse(cmd);
if (rc != 0) {
PRINT_ERROR("PARSE failed (ucmd %p, rc %d)", ucmd, rc);
goto out_error;
@@ -784,7 +771,7 @@ static int dev_user_parse(struct scst_cmd *cmd)
case SCST_USER_PARSE_EXCEPTION:
TRACE_DBG("PARSE EXCEPTION: ucmd %p", ucmd);
rc = dev->generic_parse(cmd, dev_user_get_block);
rc = dev->generic_parse(cmd);
if ((rc == 0) && (cmd->op_flags & SCST_INFO_VALID))
break;
else if (rc == SCST_CMD_STATE_NEED_THREAD_CTX) {
@@ -1021,18 +1008,49 @@ out_reply:
goto out;
}
static void dev_user_set_block(struct scst_cmd *cmd, int block)
static void dev_user_set_block_shift(struct scst_cmd *cmd, int block_shift)
{
struct scst_user_dev *dev = cmd->dev->dh_priv;
struct scst_device *dev = cmd->dev;
TRACE_ENTRY();
/*
* No need for locks here, since *_detach() can not be
* called, when there are existing commands.
*/
TRACE_DBG("dev %p, new block %d", dev, block);
if (block != 0)
dev->block = block;
else
dev->block = dev->def_block;
TRACE_DBG("dev %p, new block shift %d", dev, block_shift);
if (block_shift != 0)
dev->block_shift = block_shift;
else {
struct scst_user_dev *udev = cmd->dev->dh_priv;
dev->block_shift = scst_calc_block_shift(udev->def_block_size);
}
dev->block_size = 1 << dev->block_shift;
TRACE_EXIT();
return;
}
static void dev_user_set_block_size(struct scst_cmd *cmd, int block_size)
{
struct scst_device *dev = cmd->dev;
TRACE_ENTRY();
/*
* No need for locks here, since *_detach() can not be
* called, when there are existing commands.
*/
TRACE_DBG("dev %p, new block size %d", dev, block_size);
if (block_size != 0)
dev->block_size = block_size;
else {
struct scst_user_dev *udev = cmd->dev->dh_priv;
dev->block_size = udev->def_block_size;
}
dev->block_shift = scst_calc_block_shift(dev->block_size);
TRACE_EXIT();
return;
}
@@ -1042,7 +1060,7 @@ static int dev_user_disk_done(struct scst_cmd *cmd)
TRACE_ENTRY();
res = scst_block_generic_dev_done(cmd, dev_user_set_block);
res = scst_block_generic_dev_done(cmd, dev_user_set_block_shift);
TRACE_EXIT_RES(res);
return res;
@@ -1054,7 +1072,7 @@ static int dev_user_tape_done(struct scst_cmd *cmd)
TRACE_ENTRY();
res = scst_tape_generic_dev_done(cmd, dev_user_set_block);
res = scst_tape_generic_dev_done(cmd, dev_user_set_block_size);
TRACE_EXIT_RES(res);
return res;
@@ -2567,6 +2585,9 @@ static int dev_user_attach(struct scst_device *sdev)
goto out;
}
sdev->block_size = dev->def_block_size;
sdev->block_shift = scst_calc_block_shift(sdev->block_size);
sdev->dh_priv = dev;
sdev->tst = dev->tst;
sdev->queue_alg = dev->queue_alg;
@@ -2872,7 +2893,7 @@ static int dev_user_register_dev(struct file *file,
{
int res, i;
struct scst_user_dev *dev, *d;
int block;
int block_size;
TRACE_ENTRY();
@@ -2885,19 +2906,18 @@ static int dev_user_register_dev(struct file *file,
case TYPE_ROM:
case TYPE_MOD:
if (dev_desc->block_size == 0) {
PRINT_ERROR("Wrong block size %d",
dev_desc->block_size);
PRINT_ERROR("Wrong block size %d", dev_desc->block_size);
res = -EINVAL;
goto out;
}
block = scst_calc_block_shift(dev_desc->block_size);
if (block == -1) {
block_size = dev_desc->block_size;
if (scst_calc_block_shift(block_size) == -1) {
res = -EINVAL;
goto out;
}
break;
default:
block = dev_desc->block_size;
block_size = dev_desc->block_size;
break;
}
@@ -2988,8 +3008,7 @@ static int dev_user_register_dev(struct file *file,
dev->devtype.pr_cmds_notifications = 1;
init_completion(&dev->cleanup_cmpl);
dev->block = block;
dev->def_block = block;
dev->def_block_size = block_size;
res = __dev_user_set_opt(dev, &dev_desc->opt);
if (res != 0)
+64 -79
View File
@@ -98,10 +98,8 @@ static struct scst_trace_log vdisk_local_trace_tbl[] = {
#define SP 0x01 /* save pages */
#define PS 0x80 /* parameter saveable */
#define DEF_DISK_BLOCKSIZE_SHIFT 9
#define DEF_DISK_BLOCKSIZE (1 << DEF_DISK_BLOCKSIZE_SHIFT)
#define DEF_CDROM_BLOCKSIZE_SHIFT 11
#define DEF_CDROM_BLOCKSIZE (1 << DEF_CDROM_BLOCKSIZE_SHIFT)
#define DEF_DISK_BLOCK_SHIFT 9
#define DEF_CDROM_BLOCK_SHIFT 11
#define DEF_SECTORS 56
#define DEF_HEADS 255
#define LEN_MEM (32 * 1024)
@@ -133,9 +131,7 @@ static struct scst_trace_log vdisk_local_trace_tbl[] = {
#endif
struct scst_vdisk_dev {
uint32_t block_size;
uint64_t nblocks;
int block_shift;
loff_t file_size; /* in bytes */
/*
@@ -165,6 +161,9 @@ struct scst_vdisk_dev {
unsigned int dev_thin_provisioned:1;
unsigned int rotational:1;
struct file *fd;
struct block_device *bdev;
int virt_id;
char name[16+1]; /* Name of the virtual device,
must be <= SCSI Model + 1 */
@@ -184,8 +183,9 @@ struct scst_vdisk_dev {
struct scst_dev_type *vdev_devt;
int tgt_dev_cnt;
struct file *fd;
struct block_device *bdev;
/* Only to pass it to attach() callback. Don't use it anywhere else! */
int blk_shift;
};
struct vdisk_cmd_params {
@@ -822,6 +822,9 @@ static int vdisk_attach(struct scst_device *dev)
goto out;
}
dev->block_shift = virt_dev->blk_shift;
dev->block_size = 1 << dev->block_shift;
if (virt_dev->zero_copy && virt_dev->o_direct_flag) {
PRINT_ERROR("%s: combining zero_copy with o_direct is not"
" supported", virt_dev->filename);
@@ -851,7 +854,7 @@ static int vdisk_attach(struct scst_device *dev)
} else
virt_dev->file_size = 0;
virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
virt_dev->nblocks = virt_dev->file_size >> dev->block_shift;
if (!virt_dev->cdrom_empty) {
PRINT_INFO("Attached SCSI target virtual %s %s "
@@ -859,7 +862,7 @@ static int vdisk_attach(struct scst_device *dev)
" cyln=%lld%s)",
(dev->type == TYPE_DISK) ? "disk" : "cdrom",
virt_dev->name, vdev_get_filename(virt_dev),
virt_dev->file_size >> 20, virt_dev->block_size,
virt_dev->file_size >> 20, dev->block_size,
(long long unsigned int)virt_dev->nblocks,
(long long unsigned int)virt_dev->nblocks/64/32,
virt_dev->nblocks < 64*32
@@ -986,7 +989,7 @@ static enum compl_status_e vdisk_synchronize_cache(struct vdisk_cmd_params *p)
if (data_len == 0) {
struct scst_vdisk_dev *virt_dev = dev->dh_priv;
data_len = virt_dev->file_size -
((loff_t)scst_cmd_get_lba(cmd) << virt_dev->block_shift);
((loff_t)scst_cmd_get_lba(cmd) << dev->block_shift);
}
if (immed) {
@@ -1172,7 +1175,7 @@ static bool vdisk_parse_offset(struct vdisk_cmd_params *p, struct scst_cmd *cmd)
lba_start = scst_cmd_get_lba(cmd);
data_len = scst_cmd_get_data_len(cmd);
loff = (loff_t)lba_start << virt_dev->block_shift;
loff = (loff_t)lba_start << dev->block_shift;
TRACE_DBG("cmd %p, lba_start %lld, loff %lld, data_len %lld", cmd,
(long long unsigned int)lba_start,
(long long unsigned int)loff,
@@ -1253,17 +1256,11 @@ out_err:
goto out;
}
static int vdisk_get_block_shift(struct scst_cmd *cmd)
{
struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv;
return virt_dev->block_shift;
}
static int vdisk_parse(struct scst_cmd *cmd)
{
int res, rc;
rc = scst_sbc_generic_parse(cmd, vdisk_get_block_shift);
rc = scst_sbc_generic_parse(cmd);
if (rc != 0) {
res = scst_get_cmd_abnormal_done_state(cmd);
goto out;
@@ -1277,7 +1274,7 @@ out:
static int vcdrom_parse(struct scst_cmd *cmd)
{
int res, rc;
rc = scst_cdrom_generic_parse(cmd, vdisk_get_block_shift);
rc = scst_cdrom_generic_parse(cmd);
if (rc != 0) {
res = scst_get_cmd_abnormal_done_state(cmd);
goto out;
@@ -1293,7 +1290,7 @@ static int non_fileio_parse(struct scst_cmd *cmd)
{
int res = SCST_CMD_STATE_DEFAULT, rc;
rc = scst_sbc_generic_parse(cmd, vdisk_get_block_shift);
rc = scst_sbc_generic_parse(cmd);
if (rc != 0) {
res = scst_get_cmd_abnormal_done_state(cmd);
goto out;
@@ -1916,7 +1913,8 @@ static int vdisk_unmap_range(struct scst_cmd *cmd,
#endif
} else {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
const int block_shift = virt_dev->block_shift;
struct scst_device *dev = cmd->dev;
const int block_shift = dev->block_shift;
const loff_t s = start << block_shift;
const loff_t l = len << block_shift;
@@ -2032,6 +2030,7 @@ static void vdev_blockio_get_unmap_params(struct scst_vdisk_dev *virt_dev,
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 32) || (defined(RHEL_MAJOR) && RHEL_MAJOR -0 >= 6)
struct file *fd;
struct request_queue *q;
int block_shift = virt_dev->dev->block_shift;
#endif
TRACE_ENTRY();
@@ -2040,7 +2039,7 @@ static void vdev_blockio_get_unmap_params(struct scst_vdisk_dev *virt_dev,
*unmap_gran = 1;
*unmap_alignment = 0;
*max_unmap_lba = min_t(loff_t, 0xFFFFFFFF, virt_dev->file_size >> virt_dev->block_shift);
*max_unmap_lba = min_t(loff_t, 0xFFFFFFFF, virt_dev->file_size >> block_shift);
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 32) || (defined(RHEL_MAJOR) && RHEL_MAJOR -0 >= 6)
fd = filp_open(virt_dev->filename, O_LARGEFILE, 0600);
@@ -2056,9 +2055,9 @@ static void vdev_blockio_get_unmap_params(struct scst_vdisk_dev *virt_dev,
goto out_close;
}
*unmap_gran = q->limits.discard_granularity >> virt_dev->block_shift;
*unmap_alignment = q->limits.discard_alignment >> virt_dev->block_shift;
*max_unmap_lba = q->limits.max_discard_sectors >> (virt_dev->block_shift - 9);
*unmap_gran = q->limits.discard_granularity >> block_shift;
*unmap_alignment = q->limits.discard_alignment >> block_shift;
*max_unmap_lba = q->limits.max_discard_sectors >> (block_shift - 9);
TRACE_DBG("unmap_gran %d, unmap_alignment %d, max_unmap_lba %u",
*unmap_gran, *unmap_alignment, *max_unmap_lba);
@@ -2078,7 +2077,8 @@ static enum compl_status_e vdisk_exec_inquiry(struct vdisk_cmd_params *p)
int32_t length, i, resp_len = 0;
uint8_t *address;
uint8_t *buf;
struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv;
struct scst_device *dev = cmd->dev;
struct scst_vdisk_dev *virt_dev = dev->dh_priv;
uint16_t tg_id;
TRACE_ENTRY();
@@ -2107,7 +2107,7 @@ static enum compl_status_e vdisk_exec_inquiry(struct vdisk_cmd_params *p)
goto out_put;
}
buf[0] = cmd->dev->type; /* type dev */
buf[0] = dev->type; /* type dev */
/* Vital Product */
if (cmd->cdb[1] & EVPD) {
if (0 == cmd->cdb[2]) {
@@ -2116,7 +2116,7 @@ static enum compl_status_e vdisk_exec_inquiry(struct vdisk_cmd_params *p)
buf[4] = 0x0; /* this page */
buf[5] = 0x80; /* unit serial number */
buf[6] = 0x83; /* device identification */
if (virt_dev->dev->type == TYPE_DISK) {
if (dev->type == TYPE_DISK) {
buf[3] += 2;
buf[7] = 0xB0; /* block limits */
buf[8] = 0xB1; /* block limits */
@@ -2181,7 +2181,7 @@ static enum compl_status_e vdisk_exec_inquiry(struct vdisk_cmd_params *p)
num += 4;
tg_id = scst_lookup_tg_id(cmd->dev, cmd->tgt);
tg_id = scst_lookup_tg_id(dev, cmd->tgt);
if (tg_id) {
/*
* Target port group designator
@@ -2222,20 +2222,17 @@ static enum compl_status_e vdisk_exec_inquiry(struct vdisk_cmd_params *p)
resp_len = num;
put_unaligned_be16(resp_len, &buf[2]);
resp_len += 4;
} else if ((0xB0 == cmd->cdb[2]) &&
(virt_dev->dev->type == TYPE_DISK)) {
} else if ((0xB0 == cmd->cdb[2]) && (dev->type == TYPE_DISK)) {
/* Block Limits */
int max_transfer;
buf[1] = 0xB0;
buf[3] = 0x3C;
/* Optimal transfer granuality is PAGE_SIZE */
put_unaligned_be16(max_t(int,
PAGE_SIZE/virt_dev->block_size, 1),
&buf[6]);
put_unaligned_be16(max_t(int, PAGE_SIZE/dev->block_size, 1), &buf[6]);
/* Max transfer len is min of sg limit and 8M */
max_transfer = min_t(int,
cmd->tgt_dev->max_sg_cnt << PAGE_SHIFT,
8*1024*1024) / virt_dev->block_size;
8*1024*1024) / dev->block_size;
put_unaligned_be32(max_transfer, &buf[8]);
/*
* Let's have optimal transfer len 512KB. Better to not
@@ -2245,9 +2242,8 @@ static enum compl_status_e vdisk_exec_inquiry(struct vdisk_cmd_params *p)
* because SGV cache supports only <4M buffers.
*/
put_unaligned_be32(min_t(int,
max_transfer,
512*1024 / virt_dev->block_size),
&buf[12]);
max_transfer, 512*1024 / dev->block_size),
&buf[12]);
if (virt_dev->thin_provisioned) {
/* MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT is UNLIMITED */
put_unaligned_be32(0xFFFFFFFF, &buf[24]);
@@ -2270,15 +2266,14 @@ static enum compl_status_e vdisk_exec_inquiry(struct vdisk_cmd_params *p)
/* MAXIMUM UNMAP LBA COUNT */
put_unaligned_be32(
min_t(loff_t, 0xFFFFFFFF,
virt_dev->file_size >> virt_dev->block_shift),
virt_dev->file_size >> dev->block_shift),
&buf[20]);
/* OPTIMAL UNMAP GRANULARITY */
put_unaligned_be32(1, &buf[28]);
}
}
resp_len = buf[3] + 4;
} else if ((0xB1 == cmd->cdb[2]) &&
(virt_dev->dev->type == TYPE_DISK)) {
} else if ((0xB1 == cmd->cdb[2]) && (dev->type == TYPE_DISK)) {
/* Block Device Characteristics */
buf[1] = 0xB1;
buf[3] = 0x3C;
@@ -2288,8 +2283,7 @@ static enum compl_status_e vdisk_exec_inquiry(struct vdisk_cmd_params *p)
} else
put_unaligned_be16(1, &buf[4]);
resp_len = buf[3] + 4;
} else if ((0xB2 == cmd->cdb[2]) &&
(virt_dev->dev->type == TYPE_DISK) &&
} else if ((0xB2 == cmd->cdb[2]) && (dev->type == TYPE_DISK) &&
virt_dev->thin_provisioned) {
/* Thin Provisioning */
buf[1] = 0xB2;
@@ -2320,7 +2314,7 @@ static enum compl_status_e vdisk_exec_inquiry(struct vdisk_cmd_params *p)
if (cmd->tgtt->fake_aca)
buf[3] |= 0x20;
buf[4] = 31;/* n - 4 = 35 - 4 = 31 for full 36 byte data */
if (scst_impl_alua_configured(cmd->dev))
if (scst_impl_alua_configured(dev))
buf[5] = SCST_INQ_TPGS_MODE_IMPLICIT;
buf[6] = 0x10; /* MultiP 1 */
buf[7] = 2; /* CMDQUE 1, BQue 0 => commands queuing supported */
@@ -2518,7 +2512,7 @@ static int vdisk_format_pg(unsigned char *p, int pcontrol,
memcpy(p, format_pg, sizeof(format_pg));
put_unaligned_be16(DEF_SECTORS, &p[10]);
put_unaligned_be16(virt_dev->block_size, &p[12]);
put_unaligned_be16(virt_dev->dev->block_size, &p[12]);
if (1 == pcontrol)
memset(p + 2, 0, sizeof(format_pg) - 2);
return sizeof(format_pg);
@@ -2616,7 +2610,7 @@ static enum compl_status_e vdisk_exec_mode_sense(struct vdisk_cmd_params *p)
}
virt_dev = cmd->dev->dh_priv;
blocksize = virt_dev->block_size;
blocksize = cmd->dev->block_size;
nblocks = virt_dev->nblocks;
type = cmd->dev->type; /* type dev */
@@ -2912,7 +2906,7 @@ static enum compl_status_e vdisk_exec_read_capacity(struct vdisk_cmd_params *p)
TRACE_ENTRY();
virt_dev = cmd->dev->dh_priv;
blocksize = virt_dev->block_size;
blocksize = cmd->dev->block_size;
nblocks = virt_dev->nblocks;
if ((cmd->cdb[8] & 1) == 0) {
@@ -2974,7 +2968,7 @@ static enum compl_status_e vdisk_exec_read_capacity16(struct vdisk_cmd_params *p
TRACE_ENTRY();
virt_dev = cmd->dev->dh_priv;
blocksize = virt_dev->block_size;
blocksize = cmd->dev->block_size;
nblocks = virt_dev->nblocks - 1;
if ((cmd->cdb[14] & 1) == 0) {
@@ -3636,6 +3630,7 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua)
struct scst_cmd *cmd = p->cmd;
u64 lba_start = scst_cmd_get_lba(cmd);
struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv;
int block_shift = cmd->dev->block_shift;
struct block_device *bdev = virt_dev->bdev;
struct request_queue *q = bdev_get_queue(bdev);
int length, max_nr_vecs = 0, offset;
@@ -3698,8 +3693,7 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua)
bios++;
need_new_bio = 0;
bio->bi_end_io = blockio_endio;
bio->bi_sector = lba_start0 <<
(virt_dev->block_shift - 9);
bio->bi_sector = lba_start0 << (block_shift - 9);
bio->bi_bdev = bdev;
bio->bi_private = blockio_work;
/*
@@ -3735,7 +3729,7 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua)
if (rc < bytes) {
sBUG_ON(rc != 0);
need_new_bio = 1;
lba_start0 += thislen >> virt_dev->block_shift;
lba_start0 += thislen >> block_shift;
thislen = 0;
continue;
}
@@ -3746,7 +3740,7 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua)
off = 0;
}
lba_start += length >> virt_dev->block_shift;
lba_start += length >> block_shift;
scst_put_sg_page(cmd, page, offset);
length = scst_get_sg_page_next(cmd, &page, &offset);
@@ -4072,12 +4066,12 @@ static int vdisk_resync_size(struct scst_vdisk_dev *virt_dev)
goto out;
virt_dev->file_size = file_size;
virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
virt_dev->nblocks = virt_dev->file_size >> virt_dev->dev->block_shift;
PRINT_INFO("New size of SCSI target virtual disk %s "
"(fs=%lldMB, bs=%d, nblocks=%lld, cyln=%lld%s)",
virt_dev->name, virt_dev->file_size >> 20,
virt_dev->block_size,
virt_dev->dev->block_size,
(long long unsigned int)virt_dev->nblocks,
(long long unsigned int)virt_dev->nblocks/64/32,
virt_dev->nblocks < 64*32 ? " !WARNING! cyln less "
@@ -4086,7 +4080,6 @@ static int vdisk_resync_size(struct scst_vdisk_dev *virt_dev)
scst_capacity_data_changed(virt_dev->dev);
scst_resume_activity();
out:
return res;
}
@@ -4118,8 +4111,7 @@ static int vdev_create(struct scst_dev_type *devt,
virt_dev->rotational = DEF_ROTATIONAL;
virt_dev->thin_provisioned = DEF_THIN_PROVISIONED;
virt_dev->block_size = DEF_DISK_BLOCKSIZE;
virt_dev->block_shift = DEF_DISK_BLOCKSIZE_SHIFT;
virt_dev->blk_shift = DEF_DISK_BLOCK_SHIFT;
if (strlen(name) >= sizeof(virt_dev->name)) {
PRINT_ERROR("Name %s is too long (max allowed %zd)", name,
@@ -4276,16 +4268,13 @@ static int vdev_parse_add_dev_params(struct scst_vdisk_dev *virt_dev,
} else if (!strcasecmp("zero_copy", p)) {
virt_dev->zero_copy = !!val;
} else if (!strcasecmp("blocksize", p)) {
virt_dev->block_size = val;
virt_dev->block_shift = scst_calc_block_shift(
virt_dev->block_size);
if (virt_dev->block_shift < 9) {
virt_dev->blk_shift = scst_calc_block_shift(val);
if (virt_dev->blk_shift < 9) {
res = -EINVAL;
goto out;
}
TRACE_DBG("block_size %d, block_shift %d",
virt_dev->block_size,
virt_dev->block_shift);
TRACE_DBG("block size %ld, block shift %d",
val, virt_dev->blk_shift);
} else {
PRINT_ERROR("Unknown parameter %s (device %s)", p,
virt_dev->name);
@@ -4601,8 +4590,7 @@ static ssize_t __vcdrom_add_device(const char *device_name, char *params)
virt_dev->removable = 1;
virt_dev->cdrom_empty = 1;
virt_dev->block_size = DEF_CDROM_BLOCKSIZE;
virt_dev->block_shift = DEF_CDROM_BLOCKSIZE_SHIFT;
virt_dev->blk_shift = DEF_CDROM_BLOCK_SHIFT;
res = vdev_parse_add_dev_params(virt_dev, params, allowed_params);
if (res != 0)
@@ -4756,7 +4744,7 @@ static int vcdrom_change(struct scst_vdisk_dev *virt_dev,
}
virt_dev->file_size = err;
virt_dev->nblocks = virt_dev->file_size >> virt_dev->block_shift;
virt_dev->nblocks = virt_dev->file_size >> virt_dev->dev->block_shift;
if (!virt_dev->cdrom_empty)
virt_dev->media_changed = 1;
@@ -4767,7 +4755,7 @@ static int vcdrom_change(struct scst_vdisk_dev *virt_dev,
"(file=\"%s\", fs=%lldMB, bs=%d, nblocks=%lld,"
" cyln=%lld%s)", virt_dev->name,
vdev_get_filename(virt_dev),
virt_dev->file_size >> 20, virt_dev->block_size,
virt_dev->file_size >> 20, virt_dev->dev->block_size,
(long long unsigned int)virt_dev->nblocks,
(long long unsigned int)virt_dev->nblocks/64/32,
virt_dev->nblocks < 64*32 ? " !WARNING! cyln less "
@@ -4882,15 +4870,13 @@ static ssize_t vdisk_sysfs_blocksize_show(struct kobject *kobj,
{
int pos = 0;
struct scst_device *dev;
struct scst_vdisk_dev *virt_dev;
TRACE_ENTRY();
dev = container_of(kobj, struct scst_device, dev_kobj);
virt_dev = dev->dh_priv;
pos = sprintf(buf, "%d\n%s", (int)virt_dev->block_size,
(virt_dev->block_size == DEF_DISK_BLOCKSIZE) ? "" :
pos = sprintf(buf, "%d\n%s", dev->block_size,
(dev->block_size == (1 << DEF_DISK_BLOCK_SHIFT)) ? "" :
SCST_SYSFS_KEY_MARK "\n");
TRACE_EXIT_RES(pos);
@@ -5381,7 +5367,7 @@ static int vdisk_read_proc(struct seq_file *seq, struct scst_dev_type *dev_type)
continue;
seq_printf(seq, "%-17s %-11d %-12d", virt_dev->name,
(uint32_t)(virt_dev->file_size >> 20),
virt_dev->block_size);
1 << virt_dev->blk_shift);
c = 0;
if (virt_dev->wt_flag) {
seq_printf(seq, "WT ");
@@ -5440,8 +5426,8 @@ static int vdisk_write_proc(char *buffer, char **start, off_t offset,
int res = 0, action;
char *p, *name, *filename, *i_buf, *t10_dev_id;
struct scst_vdisk_dev *virt_dev;
uint32_t block_size = DEF_DISK_BLOCKSIZE;
int block_shift = DEF_DISK_BLOCKSIZE_SHIFT;
int block_shift = DEF_DISK_BLOCK_SHIFT;
uint32_t block_size = 1 << block_shift;
size_t slen;
TRACE_ENTRY();
@@ -5543,8 +5529,7 @@ static int vdisk_write_proc(char *buffer, char **start, off_t offset,
goto out_free_vdev;
}
}
virt_dev->block_size = block_size;
virt_dev->block_shift = block_shift;
virt_dev->blk_shift = block_shift;
while (*p != '\0') {
if (!strncmp("WRITE_THROUGH", p, 13)) {
@@ -5623,7 +5608,7 @@ static int vdisk_write_proc(char *buffer, char **start, off_t offset,
"id %d, block size %d) to "
"vdev_list", virt_dev->name,
vdev_get_filename(virt_dev), virt_dev->virt_id,
virt_dev->block_size);
1 << virt_dev->blk_shift);
} else if (action == 0) { /* close */
virt_dev = vdev_find(name);
if (virt_dev == NULL) {
+15 -27
View File
@@ -6085,8 +6085,7 @@ EXPORT_SYMBOL_GPL(scst_calc_block_shift);
*
* Generic parse() for SBC (disk) devices
*/
int scst_sbc_generic_parse(struct scst_cmd *cmd,
int (*get_block_shift)(struct scst_cmd *cmd))
int scst_sbc_generic_parse(struct scst_cmd *cmd)
{
int res = 0;
@@ -6098,7 +6097,7 @@ int scst_sbc_generic_parse(struct scst_cmd *cmd,
*/
if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED) {
int block_shift = get_block_shift(cmd);
int block_shift = cmd->dev->block_shift;
/*
* No need for locks here, since *_detach() can not be
* called, when there are existing commands.
@@ -6128,8 +6127,7 @@ EXPORT_SYMBOL_GPL(scst_sbc_generic_parse);
*
* Generic parse() for MMC (cdrom) devices
*/
int scst_cdrom_generic_parse(struct scst_cmd *cmd,
int (*get_block_shift)(struct scst_cmd *cmd))
int scst_cdrom_generic_parse(struct scst_cmd *cmd)
{
int res = 0;
@@ -6143,7 +6141,7 @@ int scst_cdrom_generic_parse(struct scst_cmd *cmd,
cmd->cdb[1] &= 0x1f;
if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED) {
int block_shift = get_block_shift(cmd);
int block_shift = cmd->dev->block_shift;
cmd->bufflen = cmd->bufflen << block_shift;
cmd->data_len = cmd->data_len << block_shift;
cmd->out_bufflen = cmd->out_bufflen << block_shift;
@@ -6169,8 +6167,7 @@ EXPORT_SYMBOL_GPL(scst_cdrom_generic_parse);
*
* Generic parse() for MO disk devices
*/
int scst_modisk_generic_parse(struct scst_cmd *cmd,
int (*get_block_shift)(struct scst_cmd *cmd))
int scst_modisk_generic_parse(struct scst_cmd *cmd)
{
int res = 0;
@@ -6184,7 +6181,7 @@ int scst_modisk_generic_parse(struct scst_cmd *cmd,
cmd->cdb[1] &= 0x1f;
if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED) {
int block_shift = get_block_shift(cmd);
int block_shift = cmd->dev->block_shift;
cmd->bufflen = cmd->bufflen << block_shift;
cmd->data_len = cmd->data_len << block_shift;
cmd->out_bufflen = cmd->out_bufflen << block_shift;
@@ -6210,8 +6207,7 @@ EXPORT_SYMBOL_GPL(scst_modisk_generic_parse);
*
* Generic parse() for tape devices
*/
int scst_tape_generic_parse(struct scst_cmd *cmd,
int (*get_block_size)(struct scst_cmd *cmd))
int scst_tape_generic_parse(struct scst_cmd *cmd)
{
int res = 0;
@@ -6239,7 +6235,7 @@ int scst_tape_generic_parse(struct scst_cmd *cmd,
}
if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED & cmd->cdb[1]) {
int block_size = get_block_size(cmd);
int block_size = cmd->dev->block_size;
cmd->bufflen = cmd->bufflen * block_size;
cmd->data_len = cmd->data_len * block_size;
cmd->out_bufflen = cmd->out_bufflen * block_size;
@@ -6288,8 +6284,7 @@ static int scst_null_parse(struct scst_cmd *cmd)
*
* Generic parse() for changer devices
*/
int scst_changer_generic_parse(struct scst_cmd *cmd,
int (*nothing)(struct scst_cmd *cmd))
int scst_changer_generic_parse(struct scst_cmd *cmd)
{
int res = scst_null_parse(cmd);
@@ -6307,8 +6302,7 @@ EXPORT_SYMBOL_GPL(scst_changer_generic_parse);
*
* Generic parse() for SCSI processor devices
*/
int scst_processor_generic_parse(struct scst_cmd *cmd,
int (*nothing)(struct scst_cmd *cmd))
int scst_processor_generic_parse(struct scst_cmd *cmd)
{
int res = scst_null_parse(cmd);
@@ -6326,8 +6320,7 @@ EXPORT_SYMBOL_GPL(scst_processor_generic_parse);
*
* Generic parse() for RAID devices
*/
int scst_raid_generic_parse(struct scst_cmd *cmd,
int (*nothing)(struct scst_cmd *cmd))
int scst_raid_generic_parse(struct scst_cmd *cmd)
{
int res = scst_null_parse(cmd);
@@ -6366,10 +6359,8 @@ int scst_block_generic_dev_done(struct scst_cmd *cmd,
* therefore change them only if necessary
*/
if (likely((status == SAM_STAT_GOOD)) || (status == SAM_STAT_CONDITION_MET)) {
switch (opcode) {
case READ_CAPACITY:
{
if (unlikely(opcode == READ_CAPACITY)) {
if ((status == SAM_STAT_GOOD) || (status == SAM_STAT_CONDITION_MET)) {
/* Always keep track of disk capacity */
int buffer_size, sector_size, sh;
uint8_t *buffer;
@@ -6391,12 +6382,9 @@ int scst_block_generic_dev_done(struct scst_cmd *cmd,
sh = 0;
set_block_shift(cmd, sh);
TRACE_DBG("block_shift %d", sh);
break;
}
default:
/* It's all good */
break;
}
} else {
/* It's all good */
}
TRACE_DBG("cmd->is_send_status=%x, cmd->resp_data_len=%d, "