diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index 957c235ec..6d1a1e4a4 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -2912,7 +2912,7 @@ void cmnd_tx_start(struct iscsi_cmnd *cmnd) set_cork(conn->sock, 1); conn->write_iop = conn->write_iov; - conn->write_iop->iov_base = (void __force __user *)(&cmnd->pdu.bhs); + conn->write_iop->iov_base = &cmnd->pdu.bhs; conn->write_iop->iov_len = sizeof(cmnd->pdu.bhs); conn->write_iop_used = 1; conn->write_size = sizeof(cmnd->pdu.bhs) + cmnd->pdu.datasize; diff --git a/iscsi-scst/kernel/iscsi.h b/iscsi-scst/kernel/iscsi.h index a8a24b1ea..7a5895ec3 100644 --- a/iscsi-scst/kernel/iscsi.h +++ b/iscsi-scst/kernel/iscsi.h @@ -184,7 +184,7 @@ struct iscsi_session { u64 sid; }; -#define ISCSI_CONN_IOV_MAX (PAGE_SIZE/sizeof(struct iovec)) +#define ISCSI_CONN_IOV_MAX (PAGE_SIZE/sizeof(struct kvec)) #define ISCSI_CONN_RD_STATE_IDLE 0 #define ISCSI_CONN_RD_STATE_IN_LIST 1 @@ -243,9 +243,9 @@ struct iscsi_conn { * thread. */ struct iscsi_cmnd *write_cmnd; - struct iovec *write_iop; + struct kvec *write_iop; int write_iop_used; - struct iovec write_iov[2]; + struct kvec write_iov[2]; u32 write_size; u32 write_offset; int write_state; diff --git a/iscsi-scst/kernel/nthread.c b/iscsi-scst/kernel/nthread.c index c06f2cae2..575674bf4 100644 --- a/iscsi-scst/kernel/nthread.c +++ b/iscsi-scst/kernel/nthread.c @@ -1097,7 +1097,7 @@ out: static int write_data(struct iscsi_conn *conn) { struct file *file; - struct iovec *iop; + struct kvec *iop; struct socket *sock; ssize_t (*sock_sendpage)(struct socket *, struct page *, int, size_t, int); @@ -1381,7 +1381,7 @@ static int tx_ddigest(struct iscsi_cmnd *cmnd, int state) static void init_tx_hdigest(struct iscsi_cmnd *cmnd) { struct iscsi_conn *conn = cmnd->conn; - struct iovec *iop; + struct kvec *iop; iscsi_extracheck_is_wr_thread(conn); @@ -1391,7 +1391,7 @@ static void init_tx_hdigest(struct iscsi_cmnd *cmnd) iop = &conn->write_iop[conn->write_iop_used]; conn->write_iop_used++; - iop->iov_base = (void __force __user *)&(cmnd->hdigest); + iop->iov_base = &cmnd->hdigest; iop->iov_len = sizeof(u32); conn->write_size += sizeof(u32); diff --git a/scst/include/scst.h b/scst/include/scst.h index 8ee3fd808..a36053e43 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -5543,9 +5543,9 @@ struct scst_data_descriptor { uint64_t sdd_blocks; }; -ssize_t scst_readv(struct file *file, const struct iovec *vec, +ssize_t scst_readv(struct file *file, const struct kvec *vec, unsigned long vlen, loff_t *pos); -ssize_t scst_writev(struct file *file, const struct iovec *vec, +ssize_t scst_writev(struct file *file, const struct kvec *vec, unsigned long vlen, loff_t *pos); void scst_write_same(struct scst_cmd *cmd, struct scst_data_descriptor *where); /** diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index a5d391bc3..819977c99 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -257,9 +257,9 @@ struct scst_vdisk_dev { struct vdisk_cmd_params { union { struct { - struct iovec *iv; - int iv_count; - struct iovec small_iv[4]; + struct kvec *kvec; + int kvec_segs; + struct kvec small_kvec[4]; } sync; struct { struct kiocb iocb; @@ -1689,9 +1689,9 @@ static int vdisk_format_dif(struct scst_cmd *cmd, uint64_t start_lba, loff_t err = 0; ssize_t full_len; struct file *fd = virt_dev->dif_fd; - struct iovec *iv; - int max_iv_count, iv_count, i; - struct page *iv_page, *data_page; + struct kvec *kvec; + int max_kvec_segs, kvec_segs, i; + struct page *kvec_page, *data_page; uint8_t *data_buf; int64_t left, done; @@ -1702,9 +1702,9 @@ static int vdisk_format_dif(struct scst_cmd *cmd, uint64_t start_lba, EXTRACHECKS_BUG_ON(!(dev->dev_dif_mode & SCST_DIF_MODE_DEV_STORE)); - iv_page = alloc_page(GFP_KERNEL); - if (iv_page == NULL) { - PRINT_ERROR("Unable to allocate iv page"); + kvec_page = alloc_page(GFP_KERNEL); + if (kvec_page == NULL) { + PRINT_ERROR("Unable to allocate kvec page"); scst_set_busy(cmd); res = -ENOMEM; goto out; @@ -1715,23 +1715,23 @@ static int vdisk_format_dif(struct scst_cmd *cmd, uint64_t start_lba, PRINT_ERROR("Unable to allocate tags data page"); scst_set_busy(cmd); res = -ENOMEM; - goto out_free_iv; + goto out_free_kvec; } data_buf = page_address(data_page); memset(data_buf, 0xFF, PAGE_SIZE); - iv = page_address(iv_page); - max_iv_count = min_t(int, UIO_MAXIOV, (int)PAGE_SIZE/sizeof(*iv)); + kvec = page_address(kvec_page); + max_kvec_segs = min_t(int, UIO_MAXIOV, (int)PAGE_SIZE/sizeof(*kvec)); - for (i = 0; i < max_iv_count; i++) - iv[i].iov_base = (uint8_t __force __user *)data_buf; + for (i = 0; i < max_kvec_segs; i++) + kvec[i].iov_base = data_buf; loff = start_lba << SCST_DIF_TAG_SHIFT; left = blocks << SCST_DIF_TAG_SHIFT; done = 0; while (left > 0) { - iv_count = 0; + kvec_segs = 0; full_len = 0; i = -1; while (1) { @@ -1739,12 +1739,12 @@ static int vdisk_format_dif(struct scst_cmd *cmd, uint64_t start_lba, full_len += len; i++; - iv_count++; - iv[i].iov_len = len; + kvec_segs++; + kvec[i].iov_len = len; left -= len; done += len; EXTRACHECKS_BUG_ON(left < 0); - if ((iv_count == max_iv_count) || (left == 0)) + if (kvec_segs == max_kvec_segs || left == 0) break; } @@ -1752,7 +1752,7 @@ static int vdisk_format_dif(struct scst_cmd *cmd, uint64_t start_lba, full_len, (long long)loff); /* WRITE */ - err = scst_writev(fd, iv, iv_count, &loff); + err = scst_writev(fd, kvec, kvec_segs, &loff); if (err < 0) { PRINT_ERROR("Formatting DIF write() returned %lld from " "%zd", err, full_len); @@ -1781,8 +1781,8 @@ static int vdisk_format_dif(struct scst_cmd *cmd, uint64_t start_lba, out_free_data_page: __free_page(data_page); -out_free_iv: - __free_page(iv_page); +out_free_kvec: + __free_page(kvec_page); out: TRACE_EXIT_RES(res); @@ -3162,7 +3162,8 @@ static bool do_fileio_async(const struct vdisk_cmd_params *p) } } -static bool vdisk_alloc_async_kvec(struct scst_cmd *cmd, struct vdisk_cmd_params *p) +static bool vdisk_alloc_async_kvec(struct scst_cmd *cmd, + struct vdisk_cmd_params *p) { int n; @@ -3175,7 +3176,7 @@ static bool vdisk_alloc_async_kvec(struct scst_cmd *cmd, struct vdisk_cmd_params p->async.kvec = kmalloc_array(n, sizeof(*p->async.kvec), cmd->cmd_gfp_mask); if (p->async.kvec == NULL) { - PRINT_ERROR("Unable to allocate kvecv (%d)", n); + PRINT_ERROR("Unable to allocate kvec (%d)", n); return false; } @@ -3308,8 +3309,8 @@ static enum compl_status_e fileio_exec_async(struct vdisk_cmd_params *p) static void vdisk_on_free_cmd_params(const struct vdisk_cmd_params *p) { if (!p->execute_async) { - if (p->sync.iv != p->sync.small_iv) - kfree(p->sync.iv); + if (p->sync.kvec != p->sync.small_kvec) + kfree(p->sync.kvec); } } @@ -5195,30 +5196,30 @@ static enum compl_status_e vdisk_exec_prevent_allow_medium_removal(struct vdisk_ return CMD_SUCCEEDED; } -static struct iovec *vdisk_alloc_sync_kvec(struct scst_cmd *cmd, - struct vdisk_cmd_params *p) +static struct kvec *vdisk_alloc_sync_kvec(struct scst_cmd *cmd, + struct vdisk_cmd_params *p) { - int iv_count; + int kvec_segs; - iv_count = min_t(int, scst_get_buf_count(cmd), UIO_MAXIOV); - if (iv_count > p->sync.iv_count) { - if (p->sync.iv != p->sync.small_iv) - kfree(p->sync.iv); - p->sync.iv_count = 0; + kvec_segs = min_t(int, scst_get_buf_count(cmd), UIO_MAXIOV); + if (kvec_segs > p->sync.kvec_segs) { + if (p->sync.kvec != p->sync.small_kvec) + kfree(p->sync.kvec); + p->sync.kvec_segs = 0; /* It can't be called in atomic context */ - p->sync.iv = iv_count <= ARRAY_SIZE(p->sync.small_iv) ? - p->sync.small_iv : - kmalloc_array(iv_count, sizeof(*p->sync.iv), + p->sync.kvec = kvec_segs <= ARRAY_SIZE(p->sync.small_kvec) ? + p->sync.small_kvec : + kmalloc_array(kvec_segs, sizeof(*p->sync.kvec), cmd->cmd_gfp_mask); - if (p->sync.iv == NULL) { - PRINT_ERROR("Unable to allocate iv (%d)", iv_count); + if (p->sync.kvec == NULL) { + PRINT_ERROR("Unable to allocate kvec (%d)", kvec_segs); goto out; } - p->sync.iv_count = iv_count; + p->sync.kvec_segs = kvec_segs; } out: - return p->sync.iv; + return p->sync.kvec; } static enum compl_status_e nullio_exec_read(struct vdisk_cmd_params *p) @@ -5262,8 +5263,8 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) uint8_t *address; struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv; struct file *fd = virt_dev->dif_fd; - struct iovec *iv; - int iv_count, max_iv_count, i; + struct kvec *kvec; + int kvec_segs, max_kvec_segs, i; bool finished = false; int tags_num, l; struct scatterlist *tags_sg; @@ -5283,10 +5284,10 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) if (unlikely(tags_num == 0)) goto out; - iv = p->sync.iv; - if (iv == NULL) { - iv = vdisk_alloc_sync_kvec(cmd, p); - if (iv == NULL) { + kvec = p->sync.kvec; + if (kvec == NULL) { + kvec = vdisk_alloc_sync_kvec(cmd, p); + if (kvec == NULL) { unsigned long flags; /* To protect sense setting against blockio data reads */ @@ -5297,12 +5298,12 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) goto out; } } - max_iv_count = p->sync.iv_count; + max_kvec_segs = p->sync.kvec_segs; tags_sg = NULL; loff = (p->loff >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; while (1) { - iv_count = 0; + kvec_segs = 0; full_len = 0; i = -1; address = scst_get_dif_buf(cmd, &tags_sg, &l); @@ -5311,12 +5312,12 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) while (1) { full_len += length; i++; - iv_count++; - iv[i].iov_base = (uint8_t __force __user *)address; - iv[i].iov_len = length; + kvec_segs++; + kvec[i].iov_base = address; + kvec[i].iov_len = length; tags_num -= length >> SCST_DIF_TAG_SHIFT; EXTRACHECKS_BUG_ON(tags_num < 0); - if ((iv_count == max_iv_count) || (tags_num == 0)) + if (kvec_segs == max_kvec_segs || tags_num == 0) break; address = scst_get_dif_buf(cmd, &tags_sg, &l); length = l; @@ -5325,11 +5326,11 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) if (tags_num == 0) finished = true; - TRACE_DBG("Reading DIF iv_count %d, full_len %zd, loff %lld", - iv_count, full_len, (long long)loff); + TRACE_DBG("Reading DIF kvec_segs %d, full_len %zd, loff %lld", + kvec_segs, full_len, (long long)loff); /* READ */ - err = scst_readv(fd, iv, iv_count, &loff); + err = scst_readv(fd, kvec, kvec_segs, &loff); if ((err < 0) || (err < full_len)) { unsigned long flags; @@ -5349,8 +5350,8 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) goto out_put_dif_buf; } - for (i = 0; i < iv_count; i++) - scst_put_dif_buf(cmd, (void __force *)(iv[i].iov_base)); + for (i = 0; i < kvec_segs; i++) + scst_put_dif_buf(cmd, kvec[i].iov_base); if (finished) break; @@ -5361,8 +5362,8 @@ out: return res; out_put_dif_buf: - for (i = 0; i < iv_count; i++) - scst_put_dif_buf(cmd, (void __force *)(iv[i].iov_base)); + for (i = 0; i < kvec_segs; i++) + scst_put_dif_buf(cmd, kvec[i].iov_base); goto out; } @@ -5376,8 +5377,8 @@ static int vdev_write_dif_tags(struct vdisk_cmd_params *p) uint8_t *address; struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv; struct file *fd = virt_dev->dif_fd; - struct iovec *iv, *eiv; - int iv_count, eiv_count, max_iv_count, i; + struct kvec *kvec, *ekvec; + int kvec_segs, ekvec_segs, max_kvec_segs, i; bool finished = false; int tags_num, l; struct scatterlist *tags_sg; @@ -5397,10 +5398,10 @@ static int vdev_write_dif_tags(struct vdisk_cmd_params *p) if (unlikely(tags_num == 0)) goto out; - iv = p->sync.iv; - if (iv == NULL) { - iv = vdisk_alloc_sync_kvec(cmd, p); - if (iv == NULL) { + kvec = p->sync.kvec; + if (kvec == NULL) { + kvec = vdisk_alloc_sync_kvec(cmd, p); + if (kvec == NULL) { unsigned long flags; /* To protect sense setting against blockio data writes */ @@ -5411,12 +5412,12 @@ static int vdev_write_dif_tags(struct vdisk_cmd_params *p) goto out; } } - max_iv_count = p->sync.iv_count; + max_kvec_segs = p->sync.kvec_segs; tags_sg = NULL; loff = (p->loff >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; while (1) { - iv_count = 0; + kvec_segs = 0; full_len = 0; i = -1; address = scst_get_dif_buf(cmd, &tags_sg, &l); @@ -5425,12 +5426,12 @@ static int vdev_write_dif_tags(struct vdisk_cmd_params *p) while (1) { full_len += length; i++; - iv_count++; - iv[i].iov_base = (uint8_t __force __user *)address; - iv[i].iov_len = length; + kvec_segs++; + kvec[i].iov_base = address; + kvec[i].iov_len = length; tags_num -= length >> SCST_DIF_TAG_SHIFT; EXTRACHECKS_BUG_ON(tags_num < 0); - if ((iv_count == max_iv_count) || (tags_num == 0)) + if (kvec_segs == max_kvec_segs || tags_num == 0) break; address = scst_get_dif_buf(cmd, &tags_sg, &l); length = l; @@ -5439,13 +5440,13 @@ static int vdev_write_dif_tags(struct vdisk_cmd_params *p) if (tags_num == 0) finished = true; - eiv = iv; - eiv_count = iv_count; + ekvec = kvec; + ekvec_segs = kvec_segs; restart: - TRACE_DBG("Writing DIF: eiv_count %d, full_len %zd", eiv_count, full_len); + TRACE_DBG("Writing DIF: ekvec_segs %d, full_len %zd", ekvec_segs, full_len); /* WRITE */ - err = scst_writev(fd, eiv, eiv_count, &loff); + err = scst_writev(fd, ekvec, ekvec_segs, &loff); if (err < 0) { unsigned long flags; @@ -5467,33 +5468,32 @@ restart: * Probably that's wrong, but sometimes write() returns * value less, than requested. Let's restart. */ - int e = eiv_count; + int e = ekvec_segs; TRACE_MGMT_DBG("DIF write() returned %d from %zd " - "(iv_count=%d)", (int)err, full_len, - eiv_count); + "(kvec_segs=%d)", (int)err, full_len, + ekvec_segs); if (err == 0) { PRINT_INFO("Suspicious: DIF write() returned 0 from " - "%zd (iv_count=%d)", full_len, eiv_count); + "%zd (kvec_segs=%d)", full_len, ekvec_segs); } full_len -= err; for (i = 0; i < e; i++) { - if ((long long)eiv->iov_len < err) { - err -= eiv->iov_len; - eiv++; - eiv_count--; + if ((long long)ekvec->iov_len < err) { + err -= ekvec->iov_len; + ekvec++; + ekvec_segs--; } else { - eiv->iov_base = - (uint8_t __force __user *)eiv->iov_base + err; - eiv->iov_len -= err; + ekvec->iov_base = ekvec->iov_base + err; + ekvec->iov_len -= err; break; } } goto restart; } - for (i = 0; i < iv_count; i++) - scst_put_dif_buf(cmd, (void __force *)(iv[i].iov_base)); + for (i = 0; i < kvec_segs; i++) + scst_put_dif_buf(cmd, kvec[i].iov_base); if (finished) break; @@ -5504,8 +5504,8 @@ out: return res; out_put_dif_buf: - for (i = 0; i < iv_count; i++) - scst_put_dif_buf(cmd, (void __force *)(iv[i].iov_base)); + for (i = 0; i < kvec_segs; i++) + scst_put_dif_buf(cmd, kvec[i].iov_base); goto out; } @@ -5563,8 +5563,8 @@ static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p) uint8_t *address; struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv; struct file *fd = virt_dev->fd; - struct iovec *iv, *eiv; - int rc, i, iv_count, eiv_count, max_iv_count; + struct kvec *kvec, *ekvec; + int rc, i, kvec_segs, ekvec_segs, max_kvec_segs; bool finished = false; TRACE_ENTRY(); @@ -5578,11 +5578,11 @@ static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p) if (unlikely(rc != 0)) goto out; - iv = vdisk_alloc_sync_kvec(cmd, p); - if (iv == NULL) + kvec = vdisk_alloc_sync_kvec(cmd, p); + if (kvec == NULL) goto out_nomem; - max_iv_count = p->sync.iv_count; + max_kvec_segs = p->sync.kvec_segs; length = scst_get_buf_first(cmd, &address); if (unlikely(length < 0)) { @@ -5593,22 +5593,22 @@ static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p) } while (1) { - iv_count = 0; + kvec_segs = 0; full_len = 0; i = -1; while (length > 0) { full_len += length; i++; - iv_count++; - iv[i].iov_base = (uint8_t __force __user *)address; - iv[i].iov_len = length; - if (iv_count == max_iv_count) + kvec_segs++; + kvec[i].iov_base = address; + kvec[i].iov_len = length; + if (kvec_segs == max_kvec_segs) break; length = scst_get_buf_next(cmd, &address); } if (length == 0) { finished = true; - if (unlikely(iv_count == 0)) + if (unlikely(kvec_segs == 0)) break; } else if (unlikely(length < 0)) { PRINT_ERROR("scst_get_buf_next() failed: %zd", length); @@ -5617,13 +5617,13 @@ static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p) goto out_put_buf; } - eiv = iv; - eiv_count = iv_count; + ekvec = kvec; + ekvec_segs = kvec_segs; restart: - TRACE_DBG("Writing: eiv_count %d, full_len %zd", eiv_count, full_len); + TRACE_DBG("Writing: ekvec_segs %d, full_len %zd", ekvec_segs, full_len); /* WRITE */ - err = scst_writev(fd, eiv, eiv_count, &loff); + err = scst_writev(fd, ekvec, ekvec_segs, &loff); if (err < 0) { PRINT_ERROR("write() returned %lld from %zd", (unsigned long long)err, @@ -5643,32 +5643,32 @@ restart: * Probably that's wrong, but sometimes write() returns * value less, than requested. Let's restart. */ - int e = eiv_count; + int e = ekvec_segs; TRACE_MGMT_DBG("write() returned %d from %zd " - "(iv_count=%d)", (int)err, full_len, - eiv_count); + "(kvec_segs=%d)", (int)err, full_len, + ekvec_segs); if (err == 0) { PRINT_INFO("Suspicious: write() returned 0 from " - "%zd (iv_count=%d)", full_len, eiv_count); + "%zd (kvec_segs=%d)", full_len, ekvec_segs); } full_len -= err; for (i = 0; i < e; i++) { - if ((long long)eiv->iov_len < err) { - err -= eiv->iov_len; - eiv++; - eiv_count--; + if ((long long)ekvec->iov_len < err) { + err -= ekvec->iov_len; + ekvec++; + ekvec_segs--; } else { - eiv->iov_base += err; - eiv->iov_len -= err; + ekvec->iov_base += err; + ekvec->iov_len -= err; break; } } goto restart; } - for (i = 0; i < iv_count; i++) - scst_put_buf(cmd, (void __force *)(iv[i].iov_base)); + for (i = 0; i < kvec_segs; i++) + scst_put_buf(cmd, kvec[i].iov_base); if (finished) break; @@ -5693,8 +5693,8 @@ out: return CMD_SUCCEEDED; out_put_buf: - for (i = 0; i < iv_count; i++) - scst_put_buf(cmd, (void __force *)(iv[i].iov_base)); + for (i = 0; i < kvec_segs; i++) + scst_put_buf(cmd, kvec[i].iov_base); goto out_sync; out_nomem: @@ -6270,12 +6270,12 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) loff_t loff = p->loff; loff_t err = 0; ssize_t length, full_len; - uint8_t __user *address; + uint8_t *address; struct scst_device *dev = cmd->dev; struct scst_vdisk_dev *virt_dev = dev->dh_priv; struct file *fd = virt_dev->fd; - struct iovec *iv; - int iv_count, i, max_iv_count; + struct kvec *kvec; + int kvec_segs, i, max_kvec_segs; bool finished = false; TRACE_ENTRY(); @@ -6285,13 +6285,13 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) if (do_fileio_async(p)) return fileio_exec_async(p); - iv = vdisk_alloc_sync_kvec(cmd, p); - if (iv == NULL) + kvec = vdisk_alloc_sync_kvec(cmd, p); + if (kvec == NULL) goto out_nomem; - max_iv_count = p->sync.iv_count; + max_kvec_segs = p->sync.kvec_segs; - length = scst_get_buf_first(cmd, (uint8_t __force **)&address); + length = scst_get_buf_first(cmd, &address); if (unlikely(length < 0)) { PRINT_ERROR("scst_get_buf_first() failed: %zd", length); scst_set_cmd_error(cmd, @@ -6300,23 +6300,22 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) } while (1) { - iv_count = 0; + kvec_segs = 0; full_len = 0; i = -1; while (length > 0) { full_len += length; i++; - iv_count++; - iv[i].iov_base = address; - iv[i].iov_len = length; - if (iv_count == max_iv_count) + kvec_segs++; + kvec[i].iov_base = address; + kvec[i].iov_len = length; + if (kvec_segs == max_kvec_segs) break; - length = scst_get_buf_next(cmd, - (uint8_t __force **)&address); + length = scst_get_buf_next(cmd, &address); } if (length == 0) { finished = true; - if (unlikely(iv_count == 0)) + if (unlikely(kvec_segs == 0)) break; } else if (unlikely(length < 0)) { PRINT_ERROR("scst_get_buf_next() failed: %zd", length); @@ -6325,10 +6324,10 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) goto out_put_buf; } - TRACE_DBG("Reading iv_count %d, full_len %zd", iv_count, full_len); + TRACE_DBG("Reading kvec_segs %d, full_len %zd", kvec_segs, full_len); /* READ */ - err = scst_readv(fd, iv, iv_count, &loff); + err = scst_readv(fd, kvec, kvec_segs, &loff); if ((err < 0) || (err < full_len)) { PRINT_ERROR("readv() returned %lld from %zd", (unsigned long long)err, @@ -6342,13 +6341,13 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) goto out_put_buf; } - for (i = 0; i < iv_count; i++) - scst_put_buf(cmd, (void __force *)(iv[i].iov_base)); + for (i = 0; i < kvec_segs; i++) + scst_put_buf(cmd, kvec[i].iov_base); if (finished) break; - length = scst_get_buf_next(cmd, (uint8_t __force **)&address); + length = scst_get_buf_next(cmd, &address); } if ((dev->dev_dif_mode & SCST_DIF_MODE_DEV_STORE) && @@ -6365,8 +6364,8 @@ out: return CMD_SUCCEEDED; out_put_buf: - for (i = 0; i < iv_count; i++) - scst_put_buf(cmd, (void __force *)(iv[i].iov_base)); + for (i = 0; i < kvec_segs; i++) + scst_put_buf(cmd, kvec[i].iov_base); goto out; out_nomem: diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index aeafe2332..fb16059a0 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -6002,8 +6002,8 @@ static int scst_cmp_fs_ds(void) ssize_t kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) { - struct iovec iov = { - .iov_base = (void __force __user *)buf, + struct kvec iov = { + .iov_base = buf, .iov_len = count }; @@ -6012,7 +6012,14 @@ ssize_t kernel_write(struct file *file, const void *buf, size_t count, EXPORT_SYMBOL(kernel_write); #endif -ssize_t scst_readv(struct file *file, const struct iovec *vec, +/** + * scst_writev - read data from a file into a kernel buffer + * @file: File to read from. + * @vec: Pointer to first element of struct kvec array. + * @vlen: Number of elements of the kvec array. + * @pos: Position in @file where to start reading. + */ +ssize_t scst_readv(struct file *file, const struct kvec *vec, unsigned long vlen, loff_t *pos) { ssize_t result; @@ -6022,25 +6029,25 @@ ssize_t scst_readv(struct file *file, const struct iovec *vec, size_t count = 0; int i; - BUILD_BUG_ON(sizeof(struct kvec) != sizeof(struct iovec)); - BUILD_BUG_ON(offsetof(struct kvec, iov_base) != - offsetof(struct iovec, iov_base)); - BUILD_BUG_ON(offsetof(struct kvec, iov_len) != - offsetof(struct iovec, iov_len)); init_sync_kiocb(&kiocb, file); kiocb.ki_pos = *pos; for (i = 0; i < vlen; i++) count += vec[i].iov_len; - iov_iter_kvec(&iter, READ, (struct kvec *)vec, vlen, count); + iov_iter_kvec(&iter, READ, vec, vlen, count); result = call_read_iter(file, &kiocb, &iter); sBUG_ON(result == -EIOCBQUEUED); if (result > 0) *pos += result; #else mm_segment_t old_fs = get_fs(); + set_fs(KERNEL_DS); WARN_ON_ONCE(scst_cmp_fs_ds() != 0); - + BUILD_BUG_ON(sizeof(struct kvec) != sizeof(struct iovec)); + BUILD_BUG_ON(offsetof(struct kvec, iov_base) != + offsetof(struct iovec, iov_base)); + BUILD_BUG_ON(offsetof(struct kvec, iov_len) != + offsetof(struct iovec, iov_len)); result = vfs_readv(file, (const struct iovec __user *)vec, vlen, pos); set_fs(old_fs); #endif @@ -6050,16 +6057,13 @@ ssize_t scst_readv(struct file *file, const struct iovec *vec, EXPORT_SYMBOL(scst_readv); /** - * scst_writev - write a buffer to a file + * scst_writev - write kernel data to a file * @file: File to write to. - * @vec: Pointer to first element of struct iovec array. - * @vlen: Number of elements of the iovec array. + * @vec: Pointer to first element of struct kvec array. + * @vlen: Number of elements of the kvec array. * @pos: Position in @file where to start writing. - * - * Note: although @vec->iov_base has type void __user*, it points at kernel - * data and not at data in user space. */ -ssize_t scst_writev(struct file *file, const struct iovec *vec, +ssize_t scst_writev(struct file *file, const struct kvec *vec, unsigned long vlen, loff_t *pos) { ssize_t result; @@ -6073,7 +6077,7 @@ ssize_t scst_writev(struct file *file, const struct iovec *vec, kiocb.ki_pos = *pos; for (i = 0; i < vlen; i++) count += vec[i].iov_len; - iov_iter_kvec(&iter, WRITE, (struct kvec *)vec, vlen, count); + iov_iter_kvec(&iter, WRITE, vec, vlen, count); file_start_write(file); result = call_write_iter(file, &kiocb, &iter); file_end_write(file); @@ -6082,8 +6086,14 @@ ssize_t scst_writev(struct file *file, const struct iovec *vec, *pos += result; #else mm_segment_t old_fs = get_fs(); + set_fs(KERNEL_DS); WARN_ON_ONCE(scst_cmp_fs_ds() != 0); + BUILD_BUG_ON(sizeof(struct kvec) != sizeof(struct iovec)); + BUILD_BUG_ON(offsetof(struct kvec, iov_base) != + offsetof(struct iovec, iov_base)); + BUILD_BUG_ON(offsetof(struct kvec, iov_len) != + offsetof(struct iovec, iov_len)); result = vfs_writev(file, (const struct iovec __user *)vec, vlen, pos); set_fs(old_fs); #endif