- Fixed crash introduced by r710 reported by andy yan <andyysj@gmail.com>

- Improve logging on write access on read-only devices
 - Make the same initiator coming through different sessions use shared IO context
 - Cleanups



git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@721 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2009-03-26 18:25:00 +00:00
parent 00b094c7fa
commit f8ba391aea
6 changed files with 114 additions and 46 deletions

View File

@@ -920,8 +920,10 @@ static int vdisk_do_job(struct scst_cmd *cmd)
if (do_fsync || fua)
vdisk_fsync(thr, loff, data_len, cmd);
} else {
TRACE(TRACE_MINOR, "Attempt to write to read-only "
"device %s", virt_dev->name);
PRINT_WARNING("Attempt of write access to read-only "
"device %s: initiator %s, op %x",
virt_dev->name, cmd->sess->initiator_name,
cmd->cdb[0]);
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_data_protect));
}
@@ -956,8 +958,10 @@ static int vdisk_do_job(struct scst_cmd *cmd)
else if (do_fsync)
vdisk_fsync(thr, loff, data_len, cmd);
} else {
TRACE(TRACE_MINOR, "Attempt to write to read-only "
"device %s", virt_dev->name);
PRINT_WARNING("Attempt of write access to read-only "
"device %s: initiator %s, op %x",
virt_dev->name, cmd->sess->initiator_name,
cmd->cdb[0]);
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_data_protect));
}

View File

@@ -936,11 +936,12 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
struct scst_acg_dev *acg_dev)
{
int ini_sg, ini_unchecked_isa_dma, ini_use_clustering;
struct scst_tgt_dev *tgt_dev;
struct scst_tgt_dev *tgt_dev, *t;
struct scst_device *dev = acg_dev->dev;
struct list_head *sess_tgt_dev_list_head;
struct scst_tgt_template *vtt = sess->tgt->tgtt;
int rc, i;
bool share_io_ctx = false;
uint8_t sense_buffer[SCST_STANDARD_SENSE_LEN];
TRACE_ENTRY();
@@ -1041,17 +1042,42 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
tm_dbg_init_tgt_dev(tgt_dev, acg_dev);
if (tgt_dev->sess->initiator_name != NULL) {
spin_lock_bh(&dev->dev_lock);
list_for_each_entry(t, &dev->dev_tgt_dev_list,
dev_tgt_dev_list_entry) {
TRACE_DBG("t name %s (tgt_dev name %s)",
t->sess->initiator_name,
tgt_dev->sess->initiator_name);
if (t->sess->initiator_name == NULL)
continue;
if (strcmp(t->sess->initiator_name,
tgt_dev->sess->initiator_name) == 0) {
share_io_ctx = true;
break;
}
}
spin_unlock_bh(&dev->dev_lock);
}
if (share_io_ctx) {
TRACE_MGMT_DBG("Sharing IO context %p (tgt_dev %p, ini %s)",
t->tgt_dev_io_ctx, tgt_dev,
tgt_dev->sess->initiator_name);
tgt_dev->tgt_dev_io_ctx = ioc_task_link(t->tgt_dev_io_ctx);
} else {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
#if defined(CONFIG_BLOCK) && defined(SCST_IO_CONTEXT)
tgt_dev->tgt_dev_io_ctx = alloc_io_context(GFP_KERNEL, -1);
if (tgt_dev->tgt_dev_io_ctx == NULL) {
TRACE(TRACE_OUT_OF_MEM, "Failed to alloc tgt_dev IO context "
"for dev %s (initiator %s)", dev->virt_name,
sess->initiator_name);
goto out_free;
tgt_dev->tgt_dev_io_ctx = alloc_io_context(GFP_KERNEL, -1);
if (tgt_dev->tgt_dev_io_ctx == NULL) {
TRACE(TRACE_OUT_OF_MEM, "Failed to alloc tgt_dev IO "
"context for dev %s (initiator %s)",
dev->virt_name, sess->initiator_name);
goto out_free;
}
#endif
#endif
}
#endif
#endif
if (vtt->threads_num > 0) {
rc = 0;

View File

@@ -179,37 +179,49 @@ struct scst_cmd_thread_t {
#if defined(SCST_IO_CONTEXT)
static inline void scst_set_io_context(struct scst_tgt_dev *tgt_dev)
static inline bool scst_set_io_context(struct scst_cmd *cmd,
struct io_context **old)
{
if (tgt_dev->dev->p_cmd_lists == &scst_main_cmd_lists) {
EXTRACHECKS_BUG_ON(current->io_context);
bool res;
if (cmd->cmd_lists == &scst_main_cmd_lists) {
EXTRACHECKS_BUG_ON(in_interrupt());
/*
* No need to call ioc_task_link(), because io_context
* supposed to be cleared in the end of the caller function.
*/
current->io_context = tgt_dev->tgt_dev_io_ctx;
TRACE_DBG("io_context %p", tgt_dev->tgt_dev_io_ctx);
}
current->io_context = cmd->tgt_dev->tgt_dev_io_ctx;
res = true;
TRACE_DBG("io_context %p", cmd->tgt_dev->tgt_dev_io_ctx);
} else
res = false;
return res;
}
static inline void scst_reset_io_context(struct scst_tgt_dev *tgt_dev)
static inline void scst_reset_io_context(struct scst_tgt_dev *tgt_dev,
struct io_context *old)
{
if (current->io_context == tgt_dev->tgt_dev_io_ctx) {
current->io_context = NULL;
TRACE_DBG("io_context %p reset", tgt_dev->tgt_dev_io_ctx);
}
current->io_context = old;
TRACE_DBG("io_context %p reset", current->io_context);
return;
}
#else
static inline void scst_set_io_context(struct scst_tgt_dev *tgt_dev) {}
static inline void scst_reset_io_context(struct scst_tgt_dev *tgt_dev) {}
static inline bool scst_set_io_context(struct scst_cmd *cmd,
struct io_context **old)
{
return false;
}
static inline void scst_reset_io_context(struct scst_tgt_dev *tgt_dev,
struct io_context *old) {}
static inline void __exit_io_context(struct io_context *ioc) {}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
static inline struct io_context *ioc_task_link(struct io_context *ioc)
{
return NULL;
};
}
#endif
#endif

View File

@@ -1858,18 +1858,21 @@ static int scst_do_real_exec(struct scst_cmd *cmd)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
int rc;
#endif
bool atomic = scst_cmd_atomic(cmd);
struct scst_device *dev = cmd->dev;
struct scst_dev_type *handler = dev->handler;
struct io_context *old_ctx = NULL;
bool ctx_changed = false;
TRACE_ENTRY();
scst_set_io_context(cmd->tgt_dev);
if (!atomic)
ctx_changed = scst_set_io_context(cmd, &old_ctx);
cmd->state = SCST_CMD_STATE_REAL_EXECUTING;
if (handler->exec) {
if (unlikely(!dev->handler->exec_atomic &&
scst_cmd_atomic(cmd))) {
if (unlikely(!dev->handler->exec_atomic && atomic)) {
/*
* It shouldn't be because of SCST_TGT_DEV_AFTER_*
* optimization.
@@ -1910,7 +1913,7 @@ static int scst_do_real_exec(struct scst_cmd *cmd)
goto out_done;
#ifndef CONFIG_SCST_ALLOW_PASSTHROUGH_IO_SUBMIT_IN_SIRQ
if (unlikely(scst_cmd_atomic(cmd))) {
if (unlikely(atomic)) {
TRACE_DBG("Pass-through exec() can not be called in atomic "
"context, rescheduling to the thread (handler %s)",
handler->name);
@@ -1921,7 +1924,7 @@ static int scst_do_real_exec(struct scst_cmd *cmd)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
if (unlikely(scst_alloc_request(cmd) != 0)) {
if (scst_cmd_atomic(cmd)) {
if (atomic) {
res = SCST_EXEC_NEED_THREAD;
goto out_restore;
} else {
@@ -1939,9 +1942,9 @@ static int scst_do_real_exec(struct scst_cmd *cmd)
rc = scst_exec_req(dev->scsi_dev, cmd->cdb, cmd->cdb_len,
cmd->data_direction, cmd->sg, cmd->bufflen, cmd->sg_cnt,
cmd->timeout, cmd->retries, cmd, scst_cmd_done,
scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL);
atomic ? GFP_ATOMIC : GFP_KERNEL);
if (unlikely(rc != 0)) {
if (scst_cmd_atomic(cmd)) {
if (atomic) {
res = SCST_EXEC_NEED_THREAD;
goto out_restore;
} else {
@@ -1954,8 +1957,9 @@ static int scst_do_real_exec(struct scst_cmd *cmd)
out_complete:
res = SCST_EXEC_COMPLETED;
out_reset:
scst_reset_io_context(cmd->tgt_dev);
out_reset_ctx:
if (ctx_changed)
scst_reset_io_context(cmd->tgt_dev, old_ctx);
TRACE_EXIT();
return res;
@@ -1963,7 +1967,7 @@ out_reset:
out_restore:
/* Restore the state */
cmd->state = SCST_CMD_STATE_REAL_EXEC;
goto out_reset;
goto out_reset_ctx;
out_error:
scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
@@ -2030,6 +2034,9 @@ static int scst_do_local_exec(struct scst_cmd *cmd)
cmd->cdb[0] == WRITE_VERIFY_16 ||
(cmd->dev->handler->type == TYPE_TAPE &&
(cmd->cdb[0] == ERASE || cmd->cdb[0] == WRITE_FILEMARKS)))) {
PRINT_WARNING("Attempt of write access to read-only device: "
"initiator %s, LUN %lld, op %x",
cmd->sess->initiator_name, cmd->lun, cmd->cdb[0]);
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_data_protect));
goto out_done;

View File

@@ -428,7 +428,7 @@ static int do_exec(struct vdisk_cmd *vcmd)
if (do_fsync || fua)
exec_fsync(vcmd);
} else {
TRACE(TRACE_MINOR, "Attempt to write to read-only "
PRINT_WARNING("Attempt to write to read-only "
"device %s", dev->name);
set_cmd_error(vcmd,
SCST_LOAD_SENSE(scst_sense_data_protect));
@@ -469,7 +469,7 @@ static int do_exec(struct vdisk_cmd *vcmd)
else if (do_fsync)
exec_fsync(vcmd);
} else {
TRACE(TRACE_MINOR, "Attempt to write to read-only "
PRINT_WARNING("Attempt to write to read-only "
"device %s", dev->name);
set_cmd_error(vcmd,
SCST_LOAD_SENSE(scst_sense_data_protect));

View File

@@ -163,13 +163,6 @@ do { \
} \
} while(0)
#define PRINT_ERROR(format, args...) \
do { \
debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \
__LINE__); \
PRINT("***ERROR*** " format, args); \
} while(0)
#define PRINT_INFO(format, args...) \
do { \
debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \
@@ -177,6 +170,20 @@ do { \
PRINT(format, args); \
} while(0)
#define PRINT_WARNING(format, args...) \
do { \
debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \
__LINE__); \
PRINT("***WARNING*** " format, args); \
} while(0)
#define PRINT_ERROR(format, args...) \
do { \
debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \
__LINE__); \
PRINT("***ERROR*** " format, args); \
} while(0)
#define TRACE_ENTRY() \
do { \
if (trace_flag & TRACE_ENTRYEXIT) \
@@ -264,6 +271,12 @@ do { \
PRINT("%s: " format, LOG_PREFIX, args); \
} while(0)
#define PRINT_WARNING(format, args...) \
do { \
PRINT("%s: ***WARNING*** " \
format, LOG_PREFIX, args); \
} while(0)
#define PRINT_ERROR(format, args...) \
do { \
PRINT("%s: ***ERROR*** " \
@@ -277,6 +290,12 @@ do { \
PRINT(format, args); \
} while(0)
#define PRINT_WARNING(format, args...) \
do { \
PRINT("***WARNING*** " format, args); \
} while(0)
#define PRINT_ERROR(format, args...) \
do { \
PRINT("***ERROR*** " format, args); \