From a94c8eaf0f68ce931c3ac31fe1fbc3ec1cfaa092 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 21 Mar 2019 02:56:46 +0000 Subject: [PATCH] scst: Move the set_fs() calls into scst_{read,write}v() This patch does not change any functionality. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8066 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/nthread.c | 4 --- scst/src/dev_handlers/scst_vdisk.c | 58 +++++++----------------------- scst/src/scst_lib.c | 56 ++++++++++++++++------------- 3 files changed, 44 insertions(+), 74 deletions(-) diff --git a/iscsi-scst/kernel/nthread.c b/iscsi-scst/kernel/nthread.c index 729324b26..e36727230 100644 --- a/iscsi-scst/kernel/nthread.c +++ b/iscsi-scst/kernel/nthread.c @@ -1099,7 +1099,6 @@ out: static int write_data(struct iscsi_conn *conn) { - mm_segment_t oldfs; struct file *file; struct iovec *iop; struct socket *sock; @@ -1142,10 +1141,7 @@ static int write_data(struct iscsi_conn *conn) sBUG_ON(count > ARRAY_SIZE(conn->write_iov)); retry: - oldfs = get_fs(); - set_fs(KERNEL_DS); res = scst_writev(file, iop, count, &off); - set_fs(oldfs); TRACE_WRITE("sid %#Lx, cid %u, res %d, iov_len %zd", (unsigned long long)conn->session->sid, conn->cid, res, iop->iov_len); diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index d602c9237..d17df0968 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -1677,7 +1677,6 @@ static int vdisk_format_dif(struct scst_cmd *cmd, uint64_t start_lba, struct scst_device *dev = cmd->dev; struct scst_vdisk_dev *virt_dev = dev->dh_priv; loff_t loff; - mm_segment_t old_fs; loff_t err = 0; ssize_t full_len; struct file *fd = virt_dev->dif_fd; @@ -1719,9 +1718,6 @@ static int vdisk_format_dif(struct scst_cmd *cmd, uint64_t start_lba, for (i = 0; i < max_iv_count; i++) iv[i].iov_base = (uint8_t __force __user *)data_buf; - old_fs = get_fs(); - set_fs(KERNEL_DS); - loff = start_lba << SCST_DIF_TAG_SHIFT; left = blocks << SCST_DIF_TAG_SHIFT; done = 0; @@ -1757,7 +1753,7 @@ static int vdisk_format_dif(struct scst_cmd *cmd, uint64_t start_lba, scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_write_error)); res = err; - goto out_set_fs; + goto out_free_data_page; } else if (err < full_len) { /* * If a write() is interrupted by a signal handler before @@ -1773,9 +1769,7 @@ static int vdisk_format_dif(struct scst_cmd *cmd, uint64_t start_lba, virt_dev->format_progress_done = done; } -out_set_fs: - set_fs(old_fs); - +out_free_data_page: __free_page(data_page); out_free_iv: @@ -5335,7 +5329,6 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) int res = 0; struct scst_cmd *cmd = p->cmd; loff_t loff; - mm_segment_t old_fs; loff_t err = 0; ssize_t length, full_len; uint8_t *address; @@ -5378,9 +5371,6 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) } max_iv_count = p->sync.iv_count; - old_fs = get_fs(); - set_fs(KERNEL_DS); - tags_sg = NULL; loff = (p->loff >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; while (1) { @@ -5428,7 +5418,7 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) } spin_unlock_irqrestore(&vdev_err_lock, flags); res = err; - goto out_set_fs; + goto out_put_dif_buf; } for (i = 0; i < iv_count; i++) @@ -5438,14 +5428,11 @@ static int vdev_read_dif_tags(struct vdisk_cmd_params *p) break; } - set_fs(old_fs); - out: TRACE_EXIT_RES(res); return res; -out_set_fs: - set_fs(old_fs); +out_put_dif_buf: for (i = 0; i < iv_count; i++) scst_put_dif_buf(cmd, (void __force *)(iv[i].iov_base)); goto out; @@ -5456,7 +5443,6 @@ static int vdev_write_dif_tags(struct vdisk_cmd_params *p) int res = 0; struct scst_cmd *cmd = p->cmd; loff_t loff; - mm_segment_t old_fs; loff_t err = 0; ssize_t length, full_len; uint8_t *address; @@ -5499,9 +5485,6 @@ static int vdev_write_dif_tags(struct vdisk_cmd_params *p) } max_iv_count = p->sync.iv_count; - old_fs = get_fs(); - set_fs(KERNEL_DS); - tags_sg = NULL; loff = (p->loff >> cmd->dev->block_shift) << SCST_DIF_TAG_SHIFT; while (1) { @@ -5550,7 +5533,7 @@ restart: } spin_unlock_irqrestore(&vdev_err_lock, flags); res = err; - goto out_set_fs; + goto out_put_dif_buf; } else if (err < full_len) { /* * Probably that's wrong, but sometimes write() returns @@ -5588,14 +5571,11 @@ restart: break; } - set_fs(old_fs); - out: TRACE_EXIT_RES(res); return res; -out_set_fs: - set_fs(old_fs); +out_put_dif_buf: for (i = 0; i < iv_count; i++) scst_put_dif_buf(cmd, (void __force *)(iv[i].iov_base)); goto out; @@ -5650,7 +5630,6 @@ static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p) struct scst_cmd *cmd = p->cmd; struct scst_device *dev = cmd->dev; loff_t loff = p->loff; - mm_segment_t old_fs; loff_t err = 0; ssize_t length, full_len; uint8_t *address; @@ -5685,9 +5664,6 @@ static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p) goto out; } - old_fs = get_fs(); - set_fs(KERNEL_DS); - while (1) { iv_count = 0; full_len = 0; @@ -5710,7 +5686,7 @@ static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p) PRINT_ERROR("scst_get_buf_next() failed: %zd", length); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_internal_failure)); - goto out_set_fs; + goto out_put_buf; } eiv = iv; @@ -5733,7 +5709,7 @@ restart: } else scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_write_error)); - goto out_set_fs; + goto out_put_buf; } else if (err < full_len) { /* * Probably that's wrong, but sometimes write() returns @@ -5772,8 +5748,6 @@ restart: length = scst_get_buf_next(cmd, &address); } - set_fs(old_fs); - if ((dev->dev_dif_mode & SCST_DIF_MODE_DEV_STORE) && (scst_get_dif_action(scst_get_dev_dif_actions(cmd->cmd_dif_actions)) != SCST_DIF_ACTION_NONE)) { err = vdev_write_dif_tags(p); @@ -5790,8 +5764,7 @@ out: TRACE_EXIT(); return CMD_SUCCEEDED; -out_set_fs: - set_fs(old_fs); +out_put_buf: for (i = 0; i < iv_count; i++) scst_put_buf(cmd, (void __force *)(iv[i].iov_base)); goto out_sync; @@ -6367,7 +6340,6 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) { struct scst_cmd *cmd = p->cmd; loff_t loff = p->loff; - mm_segment_t old_fs; loff_t err = 0; ssize_t length, full_len; uint8_t __user *address; @@ -6399,9 +6371,6 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) goto out; } - old_fs = get_fs(); - set_fs(KERNEL_DS); - while (1) { iv_count = 0; full_len = 0; @@ -6425,7 +6394,7 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) PRINT_ERROR("scst_get_buf_next() failed: %zd", length); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_internal_failure)); - goto out_set_fs; + goto out_put_buf; } TRACE_DBG("Reading iv_count %d, full_len %zd", iv_count, full_len); @@ -6442,7 +6411,7 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_read_error)); } - goto out_set_fs; + goto out_put_buf; } for (i = 0; i < iv_count; i++) @@ -6454,8 +6423,6 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p) length = scst_get_buf_next(cmd, (uint8_t __force **)&address); } - set_fs(old_fs); - if ((dev->dev_dif_mode & SCST_DIF_MODE_DEV_STORE) && (scst_get_dif_action(scst_get_dev_dif_actions(cmd->cmd_dif_actions)) != SCST_DIF_ACTION_NONE)) { err = vdev_read_dif_tags(p); @@ -6469,8 +6436,7 @@ out: TRACE_EXIT(); return CMD_SUCCEEDED; -out_set_fs: - set_fs(old_fs); +out_put_buf: for (i = 0; i < iv_count; i++) scst_put_buf(cmd, (void __force *)(iv[i].iov_base)); goto out; diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 2979789a1..f8287e598 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -5962,33 +5962,37 @@ EXPORT_SYMBOL(kernel_write); ssize_t scst_readv(struct file *file, const struct iovec *vec, unsigned long vlen, loff_t *pos) { + mm_segment_t old_fs = get_fs(); + ssize_t result; #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov = iovstack; struct iov_iter iter; - ssize_t ret; WARN_ON_ONCE(scst_cmp_fs_ds() != 0); - ret = import_iovec(READ, (const struct iovec __force __user *)vec, vlen, - ARRAY_SIZE(iovstack), &iov, &iter); - if (ret < 0) - return ret; - ret = vfs_iter_read(file, &iter, pos, 0); - BUG_ON(iov == iovstack); - kfree(iov); - return ret; + result = import_iovec(READ, (const struct iovec __force __user *)vec, + vlen, ARRAY_SIZE(iovstack), &iov, &iter); + if (result >= 0) { + result = vfs_iter_read(file, &iter, pos, 0); + BUG_ON(iov == iovstack); + kfree(iov); + } #elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) || \ (defined(CONFIG_SUSE_KERNEL) && \ LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) WARN_ON_ONCE(scst_cmp_fs_ds() != 0); - return vfs_readv(file, (const struct iovec __user *)vec, vlen, pos, 0); + result = vfs_readv(file, (const struct iovec __user *)vec, vlen, pos, + 0); #else WARN_ON_ONCE(scst_cmp_fs_ds() != 0); - return vfs_readv(file, (const struct iovec __user *)vec, vlen, pos); + result = vfs_readv(file, (const struct iovec __user *)vec, vlen, pos); #endif + set_fs(old_fs); + + return result; } EXPORT_SYMBOL(scst_readv); @@ -6005,31 +6009,35 @@ EXPORT_SYMBOL(scst_readv); ssize_t scst_writev(struct file *file, const struct iovec *vec, unsigned long vlen, loff_t *pos) { + mm_segment_t old_fs = get_fs(); + ssize_t result; #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov = iovstack; struct iov_iter iter; - ssize_t ret; WARN_ON_ONCE(scst_cmp_fs_ds() != 0); - ret = import_iovec(WRITE, (const struct iovec __force __user *)vec, - vlen, ARRAY_SIZE(iovstack), &iov, &iter); - if (ret < 0) - return ret; - file_start_write(file); - ret = vfs_iter_write(file, &iter, pos, 0); - file_end_write(file); - BUG_ON(iov == iovstack); - kfree(iov); - return ret; + result = import_iovec(WRITE, (const struct iovec __force __user *)vec, + vlen, ARRAY_SIZE(iovstack), &iov, &iter); + if (result >= 0) { + file_start_write(file); + result = vfs_iter_write(file, &iter, pos, 0); + file_end_write(file); + BUG_ON(iov == iovstack); + kfree(iov); + } #elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) || \ (defined(CONFIG_SUSE_KERNEL) && \ LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) - return vfs_writev(file, (const struct iovec __user *)vec, vlen, pos, 0); + result = vfs_writev(file, (const struct iovec __user *)vec, vlen, pos, + 0); #else - return vfs_writev(file, (const struct iovec __user *)vec, vlen, pos); + result = vfs_writev(file, (const struct iovec __user *)vec, vlen, pos); #endif + set_fs(old_fs); + + return result; } EXPORT_SYMBOL(scst_writev);