diff --git a/scst/include/scst_const.h b/scst/include/scst_const.h index de3dd38be..da40be827 100644 --- a/scst/include/scst_const.h +++ b/scst/include/scst_const.h @@ -628,7 +628,8 @@ enum scst_tg_sup { *************************************************************/ #define SCST_SYSFS_BLOCK_SIZE PAGE_SIZE -#define SCST_PR_DIR "/var/lib/scst/pr" +#define SCST_VAR_DIR "/var/lib/scst" +#define SCST_PR_DIR (SCST_VAR_DIR "/pr") #define TID_COMMON_SIZE 24 diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index a4d4be285..e5e74ba18 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -964,7 +964,7 @@ static struct scst_vdisk_dev *vdev_find(const char *name) #define VDEV_WT_LABEL "WRITE_THROUGH" #define VDEV_MODE_PAGES_BUF_SIZE (64*1024) -#define VDEV_MODE_PAGES_DIR "/var/lib/scst/vdev_mode_pages" +#define VDEV_MODE_PAGES_DIR (SCST_VAR_DIR "/vdev_mode_pages") static int __vdev_save_mode_pages(const struct scst_vdisk_dev *virt_dev, uint8_t *buf, int size) @@ -2911,6 +2911,38 @@ static uint64_t vdisk_gen_dev_id_num(const char *virt_dev_name) #endif } +static int vdisk_unmap_file_range(struct scst_cmd *cmd, + struct scst_vdisk_dev *virt_dev, loff_t off, loff_t len, + struct file *fd) +{ + int res; + + TRACE_ENTRY(); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) + TRACE_DBG("Fallocating range %lld, len %lld", + (unsigned long long)off, (unsigned long long)len); + + res = fd->f_op->fallocate(fd, + FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, off, len); + if (unlikely(res != 0)) { + PRINT_ERROR("fallocate() for %lld, len %lld " + "failed: %d", (unsigned long long)off, + (unsigned long long)len, res); + scst_set_cmd_error(cmd, + SCST_LOAD_SENSE(scst_sense_write_error)); + res = -EIO; + goto out; + } +#else + res = 0; +#endif + +out: + TRACE_EXIT_RES(res); + return res; +} + static int vdisk_unmap_range(struct scst_cmd *cmd, struct scst_vdisk_dev *virt_dev, uint64_t start_lba, uint32_t blocks) { @@ -2969,29 +3001,12 @@ static int vdisk_unmap_range(struct scst_cmd *cmd, goto out; #endif } else { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) - struct scst_device *dev = cmd->dev; - const int block_shift = dev->block_shift; - const loff_t s = start_lba << block_shift; - const loff_t l = blocks << block_shift; + loff_t off = start_lba << cmd->dev->block_shift; + loff_t len = blocks << cmd->dev->block_shift; - TRACE_DBG("Fallocating range %lld, len %lld", - (unsigned long long)s, (unsigned long long)l); - - err = fd->f_op->fallocate(fd, - FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, s, l); - if (unlikely(err != 0)) { - PRINT_ERROR("fallocate() for LBA %lld len %lld " - "failed: %d", (unsigned long long)start_lba, - (unsigned long long)blocks, err); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_write_error)); - res = -EIO; + res = vdisk_unmap_file_range(cmd, virt_dev, off, len, fd); + if (unlikely(res != 0)) goto out; - } -#else - sBUG(); -#endif } success: @@ -5217,7 +5232,7 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua) rc = bio_add_page(bio, pg, bytes, off); if (rc < bytes) { - sBUG_ON(rc != 0); + WARN_ON(rc != 0); need_new_bio = 1; lba_start0 += thislen >> block_shift; thislen = 0; diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 0e7940cd8..f3f72a85f 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -4866,24 +4866,6 @@ out: return res; } -static void scst_prelim_finish_internal_cmd(struct scst_cmd *cmd) -{ - unsigned long flags; - - TRACE_ENTRY(); - - sBUG_ON(!cmd->internal); - - spin_lock_irqsave(&cmd->sess->sess_list_lock, flags); - list_del(&cmd->sess_cmd_list_entry); - spin_unlock_irqrestore(&cmd->sess->sess_list_lock, flags); - - __scst_cmd_put(cmd); - - TRACE_EXIT(); - return; -} - int scst_prepare_request_sense(struct scst_cmd *orig_cmd) { int res = 0; @@ -4994,16 +4976,15 @@ static int scst_ws_push_single_write(struct scst_write_same_priv *wsp, struct scst_cmd *ws_cmd = wsp->ws_orig_cmd; struct scatterlist *ws_sg = wsp->ws_sg; int ws_sg_cnt = wsp->ws_sg_cnt; - int res, i; + int res; uint8_t write16_cdb[16]; - struct scatterlist *sg; - int sg_cnt, len = blocks << ws_cmd->dev->block_shift; - struct sgv_pool_obj *sgv = NULL; + int len = blocks << ws_cmd->dev->block_shift; struct scst_cmd *cmd; - int64_t cur_lba; TRACE_ENTRY(); + EXTRACHECKS_BUG_ON(blocks > ws_sg_cnt); + if (unlikely(test_bit(SCST_CMD_ABORTED, &ws_cmd->cmd_flags)) || unlikely(ws_cmd->completed)) { TRACE_DBG("ws cmd %p aborted or completed (%d), aborting " @@ -5031,44 +5012,8 @@ static int scst_ws_push_single_write(struct scst_write_same_priv *wsp, cmd->tgt_i_priv = wsp; - if ((ws_cmd->cdb[1] & 0x6) == 0) { - TRACE_DBG("Using direct ws_sg %p (cnt %d)", ws_sg, ws_sg_cnt); - sg = ws_sg; - EXTRACHECKS_BUG_ON(blocks > ws_sg_cnt); - sg_cnt = blocks; - goto set_add; - } - - sg = sgv_pool_alloc(ws_cmd->tgt_dev->pool, len, GFP_KERNEL, 0, - &sg_cnt, &sgv, &cmd->dev->dev_mem_lim, NULL); - if (sg == NULL) { - PRINT_ERROR("Unable to alloc sg for %d blocks", blocks); - res = -ENOMEM; - goto out_free_cmd; - } - -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) - sg_copy(sg, ws_sg, ws_sg_cnt, len, KM_USER0, KM_USER1); -#else - sg_copy(sg, ws_sg, ws_sg_cnt, len); -#endif - - cur_lba = lba; - for (i = 0; i < sg_cnt; i++) { - int cur_offs = 0; - while (cur_offs < sg[i].length) { - uint8_t *q; - q = &((int8_t *)(page_address(sg_page(&sg[i]))))[cur_offs]; - *((uint64_t *)q) = cur_lba; - cur_offs += ws_cmd->dev->block_size; - cur_lba++; - } - } - -set_add: - cmd->tgt_i_sg = sg; - cmd->tgt_i_sg_cnt = sg_cnt; - cmd->out_sgv = sgv; /* hacky, but it isn't used for WRITE(16) */ + cmd->tgt_i_sg = ws_sg; + cmd->tgt_i_sg_cnt = blocks; cmd->tgt_i_data_buf_alloced = 1; wsp->ws_cur_lba += blocks; @@ -5086,9 +5031,6 @@ out: TRACE_EXIT_RES(res); return res; -out_free_cmd: - scst_prelim_finish_internal_cmd(cmd); - out_busy: scst_set_busy(ws_cmd); goto out; @@ -5126,9 +5068,6 @@ static void scst_ws_write_cmd_finished(struct scst_cmd *cmd) TRACE_DBG("Write cmd %p finished (ws cmd %p, ws_cur_in_flight %d)", cmd, ws_cmd, wsp->ws_cur_in_flight); - if ((ws_cmd->cdb[1] & 0x6) != 0) - sgv_pool_free(cmd->out_sgv, &cmd->dev->dev_mem_lim); - cmd->sg = NULL; cmd->sg_cnt = 0; @@ -5248,8 +5187,11 @@ void scst_write_same(struct scst_cmd *cmd) goto out_done; } - if (((cmd->cdb[1] & 0x6) == 0x6) || ((cmd->cdb[1] & 0xE0) != 0)) { - scst_set_invalid_field_in_cdb(cmd, 1, 0); + if (unlikely((cmd->cdb[1] & 0x6) != 0)) { + TRACE(TRACE_MINOR, "LBDATA and/or PBDATA (ctrl %x) are not " + "supported", cmd->cdb[1]); + scst_set_invalid_field_in_cdb(cmd, 1, + SCST_INVAL_FIELD_BIT_OFFS_VALID | 1); goto out_done; }