diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index 58ba36dfd..3b590de0b 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -579,7 +579,6 @@ void req_cmnd_release_force(struct iscsi_cmnd *req) sBUG_ON(req->cmd_req); sBUG_ON(req->main_rsp != NULL); sBUG_ON(!list_empty(&req->rx_ddigest_cmd_list)); - sBUG_ON(!list_empty(&req->rsp_cmd_list)); sBUG_ON(req->pending); cmnd_put(req); @@ -2035,7 +2034,7 @@ static int scsi_cmnd_start(struct iscsi_cmnd *req) atomic_inc(&session->active_cmds); req->dec_active_cmds = 1; - sBUG_ON(session->scst_sess == NULL); + EXTRACHECKS_BUG_ON(session->scst_sess == NULL); scst_cmd = scst_rx_cmd(session->scst_sess, (uint8_t *)&req_hdr->lun, sizeof(req_hdr->lun), diff --git a/iscsi-scst/kernel/isert-scst/iser.h b/iscsi-scst/kernel/isert-scst/iser.h index ccf1bd66e..7b8c0536d 100644 --- a/iscsi-scst/kernel/isert-scst/iser.h +++ b/iscsi-scst/kernel/isert-scst/iser.h @@ -99,7 +99,7 @@ struct isert_wr { struct ib_sge *sge_list; union { struct ib_recv_wr recv_wr; -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) || defined(MOFED_MAJOR) struct ib_send_wr send_wr; #else struct ib_rdma_wr send_wr; diff --git a/iscsi-scst/kernel/isert-scst/iser_buf.c b/iscsi-scst/kernel/isert-scst/iser_buf.c index f6bc47fab..ae8b8c462 100644 --- a/iscsi-scst/kernel/isert-scst/iser_buf.c +++ b/iscsi-scst/kernel/isert-scst/iser_buf.c @@ -238,7 +238,7 @@ int isert_wr_init(struct isert_wr *wr, buff_offset = -EFAULT; goto out; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) || defined(MOFED_MAJOR) wr->send_wr.wr.rdma.remote_addr = pdu->rem_write_va + buff_offset; wr->send_wr.wr.rdma.rkey = pdu->rem_write_stag; @@ -255,7 +255,7 @@ int isert_wr_init(struct isert_wr *wr, buff_offset = -EFAULT; goto out; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) || defined(MOFED_MAJOR) wr->send_wr.wr.rdma.remote_addr = pdu->rem_read_va + buff_offset; wr->send_wr.wr.rdma.rkey = pdu->rem_read_stag; @@ -288,7 +288,7 @@ int isert_wr_init(struct isert_wr *wr, wr->recv_wr.sg_list = wr->sge_list; wr->recv_wr.num_sge = sg_cnt; } else { -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) || defined(MOFED_MAJOR) wr->send_wr.next = NULL; wr->send_wr.wr_id = _ptr_to_u64(wr); wr->send_wr.sg_list = wr->sge_list; diff --git a/iscsi-scst/kernel/isert-scst/iser_pdu.c b/iscsi-scst/kernel/isert-scst/iser_pdu.c index 177b71f3b..25ee75ddd 100644 --- a/iscsi-scst/kernel/isert-scst/iser_pdu.c +++ b/iscsi-scst/kernel/isert-scst/iser_pdu.c @@ -214,7 +214,7 @@ out: static inline void isert_link_send_wrs(struct isert_wr *from_wr, struct isert_wr *to_wr) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) || defined(MOFED_MAJOR) from_wr->send_wr.next = &to_wr->send_wr; #else from_wr->send_wr.wr.next = &to_wr->send_wr.wr; @@ -226,7 +226,7 @@ static inline void isert_link_send_pdu_wrs(struct isert_cmnd *from_pdu, int wr_cnt) { isert_link_send_wrs(&from_pdu->wr[wr_cnt - 1], &to_pdu->wr[0]); -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) || defined(MOFED_MAJOR) to_pdu->wr[0].send_wr.next = NULL; #else to_pdu->wr[0].send_wr.wr.next = NULL; @@ -289,7 +289,7 @@ int isert_prepare_rdma(struct isert_cmnd *isert_pdu, isert_link_send_wrs(&isert_pdu->wr[i - 1], &isert_pdu->wr[i]); if (op == ISER_WR_RDMA_READ) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) || defined(MOFED_MAJOR) isert_pdu->wr[wr_cnt - 1].send_wr.send_flags = IB_SEND_SIGNALED; isert_pdu->wr[wr_cnt - 1].send_wr.next = NULL; #else @@ -588,7 +588,7 @@ int isert_pdu_send(struct isert_connection *isert_conn, #endif wr = &tx_pdu->wr[0]; -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) || defined(MOFED_MAJOR) wr->send_wr.num_sge = isert_pdu_prepare_send(isert_conn, tx_pdu); #else wr->send_wr.wr.num_sge = isert_pdu_prepare_send(isert_conn, tx_pdu); @@ -613,7 +613,7 @@ int isert_pdu_post_rdma_write(struct isert_connection *isert_conn, TRACE_ENTRY(); -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) || defined(MOFED_MAJOR) isert_rsp->wr[0].send_wr.num_sge = isert_pdu_prepare_send(isert_conn, isert_rsp); #else diff --git a/iscsi-scst/kernel/isert-scst/iser_rdma.c b/iscsi-scst/kernel/isert-scst/iser_rdma.c index 65eba9816..52cbf8cc1 100644 --- a/iscsi-scst/kernel/isert-scst/iser_rdma.c +++ b/iscsi-scst/kernel/isert-scst/iser_rdma.c @@ -111,7 +111,7 @@ int isert_post_send(struct isert_connection *isert_conn, struct isert_wr *first_wr, int num_wr) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) || defined(MOFED_MAJOR) struct ib_send_wr *first_ib_wr = &first_wr->send_wr; #else struct ib_send_wr *first_ib_wr = &first_wr->send_wr.wr; @@ -150,7 +150,7 @@ static void isert_post_drain_sq(struct isert_connection* isert_conn) isert_wr_set_fields(drain_wr_sq, isert_conn, NULL); drain_wr_sq->wr_op = ISER_WR_SEND; -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) || defined(MOFED_MAJOR) drain_wr_sq->send_wr.wr_id = _ptr_to_u64(drain_wr_sq); drain_wr_sq->send_wr.opcode = IB_WR_SEND; err = ib_post_send(isert_conn->qp, @@ -703,7 +703,7 @@ static void isert_handle_wc_error(struct ib_wc *wc) switch (wr->wr_op) { case ISER_WR_SEND: -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) || defined(MOFED_MAJOR) num_sge = wr->send_wr.num_sge; #else num_sge = wr->send_wr.wr.num_sge; @@ -966,7 +966,7 @@ static struct isert_device *isert_device_create(struct ib_device *ib_dev) goto out; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0) || defined(MOFED_MAJOR) err = ib_query_device(ib_dev, &isert_dev->device_attr); if (unlikely(err)) { PRINT_ERROR("Failed to query device, err: %d", err); @@ -1777,7 +1777,7 @@ struct isert_portal *isert_portal_create(void) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0) && \ (!defined(RHEL_MAJOR) || RHEL_MAJOR -0 <= 5) cm_id = rdma_create_id(isert_cm_evt_handler, portal, RDMA_PS_TCP); -#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) +#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) || defined(MOFED_MAJOR) cm_id = rdma_create_id(isert_cm_evt_handler, portal, RDMA_PS_TCP, IB_QPT_RC); #else diff --git a/scst/README b/scst/README index 38ab73d5c..ad59ec8dc 100644 --- a/scst/README +++ b/scst/README @@ -2120,7 +2120,7 @@ IMPORTANT: Since data in BLOCKIO and FILEIO modes are not consistent between simultaneously, you will almost instantly corrupt your data on that device. -IMPORTANT: Some kernels starting from 2.6.32 have a problem, which prevents +IMPORTANT: Some kernels starting from 2.6.32 have a problem, which ========= prevents BLOCKIO from working correctly with RAID5/DM. See http://lkml.org/lkml/2010/7/28/315. That problem was fixed in 2.6.32.19, 2.6.34.4, 2.6.35.2 and 2.6.36-rc1. It is strongly @@ -2264,14 +2264,20 @@ help in many troubleshooting cases. So, if you may consider to keep CONFIG_SCST_TRACING, its performance impact is very limited. IMPORTANT: The development version of SCST in the SVN is optimized for -========= development and bug hunting, not for performance. To reconfigure - - it for performance you should run "make 2perf" or "make - 2release" (to keep CONFIG_SCST_TRACING) in the root of your - source code (e.g. trunk/). It will set the above options as - needed. The only option it doesn't set is +========= development and bug hunting, not for performance. This means + it is MUCH slower (multiple times). To reconfigure SCST for + release you should run "make 2release" command in the root of + your source code (e.g. trunk/). It will set the above options + as needed. The only option it doesn't set is CONFIG_SCST_TEST_IO_IN_SIRQ, so, if needed, you should change - it manually. + it manually. There is also so called "performance" build + mode, which you can activate by "make 2perf" command. The + only difference it has comparing to release build mode is + disabled CONFIG_SCST_TRACING option. Because of that, you + won't be able to see many important SCST run time logging + messages. This mode is intended to evaluate impact of + CONFIG_SCST_TRACING on performance and not recommended for + production. IMPORTANT: You can't use debug SCST drivers with non-debug SCST core. ========= So, after disabling both CONFIG_SCST_TRACING and CONFIG_SCST_DEBUG diff --git a/scst/README.drbd b/scst/README.drbd index dbb6cc6a5..c187f73bb 100644 --- a/scst/README.drbd +++ b/scst/README.drbd @@ -21,6 +21,8 @@ settings for each DRBD block device exported via SCST: * Caching MUST be disabled: set the nv_cache parameter to 0 in scst.conf. * Write-through MUST be enabled: set the write_through parameter to 1 in scst.conf. +* If SCSI reservations are used, their sync between nodes must be enabled, + see README.dlm. DRBD Configuration ------------------ diff --git a/scst/include/backport.h b/scst/include/backport.h index eec927283..98b21fd60 100644 --- a/scst/include/backport.h +++ b/scst/include/backport.h @@ -348,6 +348,24 @@ static inline int __must_check kref_get_unless_zero(struct kref *kref) } #endif +/* */ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)) && \ + (!defined(RHEL_MAJOR) || RHEL_MAJOR -0 < 7) +/** + * ktime_before - Compare if a ktime_t value is smaller than another one. + * @cmp1: comparable1 + * @cmp2: comparable2 + * + * Return: true if cmp1 happened before cmp2. + */ +static inline bool ktime_before(const ktime_t cmp1, const ktime_t cmp2) +{ + return ktime_compare(cmp1, cmp2) < 0; +} +#endif + /* */ #ifndef __list_for_each @@ -678,19 +696,4 @@ static inline int scsi_bidi_cmnd(struct scsi_cmnd *cmd) } #endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) && \ - (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)) -/** - * ktime_before - Compare if a ktime_t value is smaller than another one. - * @cmp1: comparable1 - * @cmp2: comparable2 - * - * Return: true if cmp1 happened before cmp2. - */ -static inline bool ktime_before(const ktime_t cmp1, const ktime_t cmp2) -{ - return ktime_compare(cmp1, cmp2) < 0; -} -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)) */ - #endif /* _SCST_BACKPORT_H_ */ diff --git a/scst/include/scst_const.h b/scst/include/scst_const.h index ca2b4c6f6..ed6b6fba3 100644 --- a/scst/include/scst_const.h +++ b/scst/include/scst_const.h @@ -656,8 +656,6 @@ enum scst_tg_sup { ** Misc SCSI constants *************************************************************/ #define SCST_SENSE_ASC_UA_RESET 0x29 -#define POSITION_LEN_SHORT 20 -#define POSITION_LEN_LONG 32 /************************************************************* ** Compatibility constants diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index a91ce88ce..850e48b2b 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -631,6 +631,7 @@ static const struct attribute *vdisk_nullio_attrs[] = { &vdev_dummy_attr.attr, &vdev_read_zero_attr.attr, &vdisk_removable_attr.attr, + &vdisk_cluster_mode_attr.attr, &vdev_t10_vend_id_attr.attr, &vdev_vend_specific_id_attr.attr, &vdev_prod_id_attr.attr, @@ -831,6 +832,7 @@ static struct scst_dev_type vdisk_null_devtype = { "dif_mode, " "dif_type, " "dif_static_app_tag, ", + "cluster_mode, " "read_only, " "removable, " "rotational, " @@ -6515,8 +6517,10 @@ static void blockio_endio(struct bio *bio) #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) if (bio->bi_rw & (1 << BIO_RW)) -#else +#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) if (bio->bi_rw & REQ_WRITE) +#else + if (op_is_write(bio_op(bio))) #endif scst_set_cmd_error(blockio_work->cmd, SCST_LOAD_SENSE(scst_sense_write_error)); @@ -6547,16 +6551,22 @@ static void vdisk_bio_set_failfast(struct bio *bio) bio->bi_rw |= (1 << BIO_RW_FAILFAST_DEV) | (1 << BIO_RW_FAILFAST_TRANSPORT) | (1 << BIO_RW_FAILFAST_DRIVER); -#else +#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) bio->bi_rw |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER; +#else + bio->bi_opf |= REQ_FAILFAST_DEV | + REQ_FAILFAST_TRANSPORT | + REQ_FAILFAST_DRIVER; #endif } static void vdisk_bio_set_hoq(struct bio *bio) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) || \ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + bio->bi_opf |= REQ_SYNC; +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) || \ (defined(RHEL_MAJOR) && \ (RHEL_MAJOR -0 > 6 || RHEL_MAJOR -0 == 6 && RHEL_MINOR -0 > 0)) bio->bi_rw |= REQ_SYNC; @@ -6565,7 +6575,9 @@ static void vdisk_bio_set_hoq(struct bio *bio) #else bio->bi_rw |= 1 << BIO_RW_SYNC; #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) || \ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) + bio->bi_opf |= REQ_META; +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) || \ (defined(RHEL_MAJOR) && \ (RHEL_MAJOR -0 > 6 || RHEL_MAJOR -0 == 6 && RHEL_MINOR -0 > 0)) bio->bi_rw |= REQ_META; @@ -6815,6 +6827,14 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua) bio->bi_private = blockio_work; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)) && (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 6, 0)) bio->bi_destructor = blockio_bio_destructor; +#endif + if (write) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) + bio->bi_rw |= (1 << BIO_RW); +#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + bio->bi_rw |= REQ_WRITE; +#else + bio_set_op_attrs(bio, REQ_OP_WRITE, 0); #endif /* * Better to fail fast w/o any local recovery @@ -6826,7 +6846,11 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua) bio->bi_rw |= REQ_SYNC; #endif if (fua) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) bio->bi_rw |= REQ_FUA; +#else + bio->bi_opf |= REQ_FUA; +#endif if (cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE) vdisk_bio_set_hoq(bio); @@ -6879,7 +6903,11 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua) hbio = hbio->bi_next; bio->bi_next = NULL; - submit_bio((write != 0), bio); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + submit_bio(bio->bi_rw, bio); +#else + submit_bio(bio); +#endif } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) @@ -6970,7 +6998,12 @@ static int vdisk_blockio_flush(struct block_device *bdev, gfp_t gfp_mask, bio->bi_end_io = vdev_flush_end_io; bio->bi_private = cmd; bio->bi_bdev = bdev; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) submit_bio(WRITE_FLUSH, bio); +#else + bio_set_op_attrs(bio, REQ_OP_FLUSH, 0); + submit_bio(bio); +#endif goto out; } else { #else @@ -7063,7 +7096,7 @@ static void blockio_end_sync_io(struct bio *bio) } /** - * blockio_rw_sync() - read or write up to @len bytes from a block I/O device + * blockio_read_sync() - read up to @len bytes from a block I/O device * * Returns: * - A negative value if an error occurred. @@ -7073,8 +7106,8 @@ static void blockio_end_sync_io(struct bio *bio) * Note: * Increments *@loff with the number of bytes transferred upon success. */ -static ssize_t blockio_rw_sync(struct scst_vdisk_dev *virt_dev, void *buf, - size_t len, loff_t *loff, unsigned int rw) +static ssize_t blockio_read_sync(struct scst_vdisk_dev *virt_dev, void *buf, + size_t len, loff_t *loff) { struct bio_priv_sync s = { COMPLETION_INITIALIZER_ONSTACK(s.c), 0, @@ -7110,7 +7143,11 @@ static ssize_t blockio_rw_sync(struct scst_vdisk_dev *virt_dev, void *buf, if (!bio) goto out; - bio->bi_rw = rw; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + bio->bi_rw = READ_SYNC; +#else + bio_set_op_attrs(bio, REQ_OP_READ, REQ_SYNC); +#endif bio->bi_bdev = bdev; bio->bi_end_io = blockio_end_sync_io; bio->bi_private = &s; @@ -7137,7 +7174,11 @@ static ssize_t blockio_rw_sync(struct scst_vdisk_dev *virt_dev, void *buf, } } } - submit_bio(rw, bio); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) + submit_bio(bio->bi_rw, bio); +#else + submit_bio(bio); +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)) && (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 6, 0)) submitted = true; #endif @@ -7184,8 +7225,8 @@ static ssize_t vdev_read_sync(struct scst_vdisk_dev *virt_dev, void *buf, return len; } else if (virt_dev->blockio) { for (read = 0; read < len; read += res) { - res = blockio_rw_sync(virt_dev, buf + read, len - read, - loff, READ_SYNC); + res = blockio_read_sync(virt_dev, buf + read, + len - read, loff); if (res < 0) return res; } @@ -8174,7 +8215,7 @@ static int vdev_nullio_add_device(const char *device_name, char *params) int res = 0; static const char *const allowed_params[] = { "read_only", "dummy", "removable", "blocksize", "rotational", - "dif_mode", "dif_type", "dif_static_app_tag", + "cluster_mode", "dif_mode", "dif_type", "dif_static_app_tag", "size", "size_mb", "tst", NULL }; struct scst_vdisk_dev *virt_dev; diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index b0ce5f2e0..8340abc19 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -7803,6 +7803,34 @@ static void bio_kmalloc_destructor(struct bio *bio) } #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) +static struct request *blk_make_request(struct request_queue *q, + struct bio *bio, + gfp_t gfp_mask) +{ + struct request *rq = blk_get_request(q, bio_data_dir(bio), gfp_mask); + + if (IS_ERR(rq)) + return rq; + + blk_rq_set_block_pc(rq); + + for_each_bio(bio) { + struct bio *bounce_bio = bio; + int ret; + + blk_queue_bounce(q, &bounce_bio); + ret = blk_rq_append_bio(rq, bounce_bio); + if (unlikely(ret)) { + blk_put_request(rq); + return ERR_PTR(ret); + } + } + + return rq; +} +#endif + /* __blk_map_kern_sg - map kernel data to a request for REQ_TYPE_BLOCK_PC */ static struct request *__blk_map_kern_sg(struct request_queue *q, struct scatterlist *sgl, int nents, struct blk_kern_sg_work *bw, @@ -7885,8 +7913,10 @@ static struct request *__blk_map_kern_sg(struct request_queue *q, if (!reading) #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) bio->bi_rw |= 1 << BIO_RW; -#else +#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) bio->bi_rw |= REQ_WRITE; +#else + bio_set_op_attrs(bio, REQ_OP_WRITE, 0); #endif bios++; bio->bi_private = bw; @@ -10654,8 +10684,6 @@ static int get_cdb_info_serv_act_in(struct scst_cmd *cmd, case SAI_READ_CAPACITY_16: cmd->op_name = "READ CAPACITY(16)"; cmd->bufflen = get_unaligned_be32(&cmd->cdb[10]); - if (unlikely(cmd->bufflen & SCST_MAX_VALID_BUFFLEN_MASK)) - goto out_inval_bufflen10; cmd->op_flags |= SCST_IMPLICIT_HQ | SCST_LBA_NOT_VALID | SCST_REG_RESERVE_ALLOWED | SCST_WRITE_EXCL_ALLOWED | @@ -10665,8 +10693,6 @@ static int get_cdb_info_serv_act_in(struct scst_cmd *cmd, cmd->op_name = "GET LBA STATUS"; cmd->lba = get_unaligned_be64(&cmd->cdb[2]); cmd->bufflen = get_unaligned_be32(&cmd->cdb[10]); - if (unlikely(cmd->bufflen & SCST_MAX_VALID_BUFFLEN_MASK)) - goto out_inval_bufflen10; cmd->op_flags |= SCST_WRITE_EXCL_ALLOWED; break; default: @@ -10676,16 +10702,8 @@ static int get_cdb_info_serv_act_in(struct scst_cmd *cmd, cmd->data_len = cmd->bufflen; -out: TRACE_EXIT_RES(res); return res; - -out_inval_bufflen10: - PRINT_ERROR("Too big bufflen %d (op %s)", cmd->bufflen, - scst_get_opcode_name(cmd)); - scst_set_invalid_field_in_cdb(cmd, 10, 0); - res = 1; - goto out; } static int get_cdb_info_single(struct scst_cmd *cmd, @@ -10708,19 +10726,6 @@ static int get_cdb_info_read_pos(struct scst_cmd *cmd, cmd->bufflen = get_unaligned_be16(cmd->cdb + sdbops->info_len_off); - switch (cmd->cdb[1] & 0x1f) { - case 0: - case 1: - case 6: - if (cmd->bufflen != 0) { - PRINT_ERROR("READ POSITION: Invalid non-zero (%d) " - "allocation length for service action %x", - cmd->bufflen, cmd->cdb[1] & 0x1f); - goto out_inval_field1; - } - break; - } - switch (cmd->cdb[1] & 0x1f) { case 0: case 1: @@ -10883,12 +10888,6 @@ static int get_cdb_info_verify12(struct scst_cmd *cmd, cmd->lba = get_unaligned_be32(cmd->cdb + sdbops->info_lba_off); if (cmd->cdb[1] & 2) { /* BYTCHK 01 */ cmd->bufflen = get_unaligned_be32(cmd->cdb + sdbops->info_len_off); - if (unlikely(cmd->bufflen & SCST_MAX_VALID_BUFFLEN_MASK)) { - PRINT_ERROR("Too big bufflen %d (op %s)", - cmd->bufflen, scst_get_opcode_name(cmd)); - scst_set_invalid_field_in_cdb(cmd, sdbops->info_len_off, 0); - return 1; - } cmd->data_len = cmd->bufflen; cmd->data_direction = SCST_DATA_WRITE; } else { @@ -10913,12 +10912,6 @@ static int get_cdb_info_verify16(struct scst_cmd *cmd, cmd->lba = get_unaligned_be64(cmd->cdb + sdbops->info_lba_off); if (cmd->cdb[1] & 2) { /* BYTCHK 01 */ cmd->bufflen = get_unaligned_be32(cmd->cdb + sdbops->info_len_off); - if (unlikely(cmd->bufflen & SCST_MAX_VALID_BUFFLEN_MASK)) { - PRINT_ERROR("Too big bufflen %d (op %s)", - cmd->bufflen, scst_get_opcode_name(cmd)); - scst_set_invalid_field_in_cdb(cmd, sdbops->info_len_off, 0); - return 1; - } cmd->data_len = cmd->bufflen; cmd->data_direction = SCST_DATA_WRITE; } else { @@ -10943,12 +10936,6 @@ static int get_cdb_info_verify32(struct scst_cmd *cmd, cmd->lba = get_unaligned_be64(cmd->cdb + sdbops->info_lba_off); if (cmd->cdb[10] & 2) { cmd->bufflen = get_unaligned_be32(cmd->cdb + sdbops->info_len_off); - if (unlikely(cmd->bufflen & SCST_MAX_VALID_BUFFLEN_MASK)) { - PRINT_ERROR("Too big bufflen %d (op %s)", - cmd->bufflen, scst_get_opcode_name(cmd)); - scst_set_invalid_field_in_cdb(cmd, sdbops->info_len_off, 0); - return 1; - } cmd->data_len = cmd->bufflen; cmd->data_direction = SCST_DATA_WRITE; } else { @@ -11055,12 +11042,6 @@ static int get_cdb_info_len_4(struct scst_cmd *cmd, cmd->op_flags |= SCST_LBA_NOT_VALID; cmd->lba = 0; cmd->bufflen = get_unaligned_be32(cmd->cdb + sdbops->info_len_off); - if (unlikely(cmd->bufflen & SCST_MAX_VALID_BUFFLEN_MASK)) { - PRINT_ERROR("Too big bufflen %d (op %s)", cmd->bufflen, - scst_get_opcode_name(cmd)); - scst_set_invalid_field_in_cdb(cmd, sdbops->info_len_off, 0); - return 1; - } cmd->data_len = cmd->bufflen; return 0; } @@ -11155,12 +11136,6 @@ static inline int get_cdb_info_lba_4_len_4(struct scst_cmd *cmd, { cmd->lba = get_unaligned_be32(cmd->cdb + sdbops->info_lba_off); cmd->bufflen = get_unaligned_be32(cmd->cdb + sdbops->info_len_off); - if (unlikely(cmd->bufflen & SCST_MAX_VALID_BUFFLEN_MASK)) { - PRINT_ERROR("Too big bufflen %d (op %s)", cmd->bufflen, - scst_get_opcode_name(cmd)); - scst_set_invalid_field_in_cdb(cmd, sdbops->info_len_off, 0); - return 1; - } cmd->data_len = cmd->bufflen; return 0; } @@ -11192,12 +11167,6 @@ static inline int get_cdb_info_lba_8_len_4(struct scst_cmd *cmd, { cmd->lba = get_unaligned_be64(cmd->cdb + sdbops->info_lba_off); cmd->bufflen = get_unaligned_be32(cmd->cdb + sdbops->info_len_off); - if (unlikely(cmd->bufflen & SCST_MAX_VALID_BUFFLEN_MASK)) { - PRINT_ERROR("Too big bufflen %d (op %s)", cmd->bufflen, - scst_get_opcode_name(cmd)); - scst_set_invalid_field_in_cdb(cmd, sdbops->info_len_off, 0); - return 1; - } cmd->data_len = cmd->bufflen; return 0; } @@ -11926,28 +11895,30 @@ int scst_tape_generic_parse(struct scst_cmd *cmd) * therefore change them only if necessary */ - if (cmd->cdb[0] == READ_POSITION) { - int tclp = cmd->cdb[1] & 4; - int long_bit = cmd->cdb[1] & 2; - int bt = cmd->cdb[1] & 1; - - if ((tclp == long_bit) && (!bt || !long_bit)) { - cmd->bufflen = - tclp ? POSITION_LEN_LONG : POSITION_LEN_SHORT; - cmd->data_direction = SCST_DATA_READ; - } else { - cmd->bufflen = 0; - cmd->data_direction = SCST_DATA_NONE; - } - cmd->data_len = cmd->bufflen; - } - if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED && cmd->cdb[1] & 1) { int block_size = cmd->dev->block_size; + unsigned int ob = cmd->bufflen, od = cmd->data_len, oo = cmd->out_bufflen; + bool overflow; cmd->bufflen = cmd->bufflen * block_size; cmd->data_len = cmd->data_len * block_size; cmd->out_bufflen = cmd->out_bufflen * block_size; + + overflow = (ob < (unsigned int)cmd->bufflen) || + (od < (unsigned int)cmd->data_len) || + (oo < (unsigned int)cmd->out_bufflen); + if (unlikely(overflow)) { + PRINT_WARNING("bufflen %u, data_len %llu or out_bufflen" + " %u too large for device %s (block size" + " %u)", cmd->bufflen, cmd->data_len, + cmd->out_bufflen, cmd->dev->virt_name, + block_size); + PRINT_BUFFER("CDB", cmd->cdb, cmd->cdb_len); + scst_set_cmd_error(cmd, SCST_LOAD_SENSE( + scst_sense_block_out_range_error)); + res = -EINVAL; + goto out; + } } if ((cmd->op_flags & (SCST_SMALL_TIMEOUT | SCST_LONG_TIMEOUT)) == 0) @@ -11957,6 +11928,7 @@ int scst_tape_generic_parse(struct scst_cmd *cmd) else if (cmd->op_flags & SCST_LONG_TIMEOUT) cmd->timeout = SCST_GENERIC_TAPE_LONG_TIMEOUT; +out: TRACE_EXIT_RES(res); return res; } diff --git a/scst/src/scst_sysfs.c b/scst/src/scst_sysfs.c index 7e2985b45..8bc922cc8 100644 --- a/scst/src/scst_sysfs.c +++ b/scst/src/scst_sysfs.c @@ -2192,7 +2192,7 @@ static int scst_process_ini_group_mgmt_store(char *buffer, TRACE_DBG("Creating group '%s'", p); if (acg != NULL) { PRINT_ERROR("acg name %s exist", p); - res = -EINVAL; + res = -EEXIST; goto out_unlock; } res = scst_alloc_add_acg(tgt, p, true, &acg); diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/lib/SCST/SCST.pm b/scstadmin/scstadmin.sysfs/scst-1.0.0/lib/SCST/SCST.pm index 5fca60f2e..dbfe3726d 100644 --- a/scstadmin/scstadmin.sysfs/scst-1.0.0/lib/SCST/SCST.pm +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/lib/SCST/SCST.pm @@ -622,6 +622,7 @@ sub groups { } } close $gHandle; + @groups = sort(@groups); return (\@groups, undef); } @@ -814,7 +815,7 @@ sub deviceGroups { } close $dHandle; - + @groups = sort(@groups); return (\@groups, undef); } diff --git a/usr/fileio/common.c b/usr/fileio/common.c index 6394f5087..8d0f1b9c8 100644 --- a/usr/fileio/common.c +++ b/usr/fileio/common.c @@ -702,7 +702,7 @@ static int process_cmd(struct vdisk_cmd *vcmd) TRACE_ENTRY(); - TRACE_BUFFER("Received cmd", &cmd, sizeof(cmd)); + TRACE_BUFFER("Received cmd", cmd, sizeof(*cmd)); switch(cmd->subcode) { case SCST_USER_EXEC: