git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@5521 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2014-05-16 02:05:38 +00:00
parent 416958ee4b
commit 36f98ec6df
3 changed files with 51 additions and 93 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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;
}