Merge branch 'svn-trunk'

This commit is contained in:
Bart Van Assche
2020-11-23 08:08:56 -08:00
6 changed files with 79 additions and 86 deletions
+22
View File
@@ -16,6 +16,28 @@
#ifndef _ISCSI_SCST_U_H
#define _ISCSI_SCST_U_H
#ifdef __KERNEL__
#include <linux/uaccess.h> /* mm_segment_t */
#include <linux/version.h>
/* <asm/uaccess.h> */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
/*
* With kernel 5.9 or older, certain kernel functions, e.g. setsockopt(),
* sock_recvmsg() only accept a pointer to a user space buffer. With kernel
* v5.10 these functions accept a sockptr_t, a data structure that includes
* information about the address space of a pointer. See also commit
* 47058bb54b57 ("x86: remove address space overrides using set_fs()"). See
* also https://lwn.net/Articles/832121/. The definitions below make it easy
* to write kernel code that is compatible with all kernel versions.
*/
#define KERNEL_DS ((mm_segment_t) { })
static inline mm_segment_t get_fs(void) { return ((mm_segment_t) { }); }
static inline void set_fs(mm_segment_t seg) { }
#endif
#endif
#ifdef __KERNEL__
#include <linux/types.h>
#else
+4
View File
@@ -1184,7 +1184,11 @@ typedef unsigned percpu_count_t;
#define READ_REF_COUNT(ref) atomic_read(&(ref)->count)
#else
typedef unsigned long percpu_count_t;
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
#define READ_REF_COUNT(ref) atomic_long_read(&(ref)->count)
#else
#define READ_REF_COUNT(ref) atomic_long_read(&(ref)->data->count)
#endif
#endif
/*
+2 -9
View File
@@ -10076,18 +10076,15 @@ static void init_ops(vdisk_op_fn *ops, int count)
static int __init vdev_check_mode_pages_path(void)
{
int res;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
struct nameidata nd;
#else
struct path path;
#endif
mm_segment_t old_fs = get_fs();
TRACE_ENTRY();
set_fs(KERNEL_DS);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
res = path_lookup(VDEV_MODE_PAGES_DIR, 0, &nd);
if (res == 0)
scst_path_put(&nd);
@@ -10101,12 +10098,8 @@ static int __init vdev_check_mode_pages_path(void)
"disabled. You should create this directory manually "
"or reinstall SCST", VDEV_MODE_PAGES_DIR, res);
vdev_saved_mode_pages_enabled = false;
goto out_setfs;
}
out_setfs:
set_fs(old_fs);
res = 0; /* always succeed */
TRACE_EXIT_RES(res);
+47 -72
View File
@@ -16,6 +16,7 @@
* GNU General Public License for more details.
*/
#include <linux/aio.h> /* struct kiocb for kernel v4.0 */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -5987,6 +5988,7 @@ static void scst_complete_request_sense(struct scst_cmd *req_cmd)
return;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
static int scst_cmp_fs_ds(void)
{
mm_segment_t fs = get_fs();
@@ -5994,30 +5996,18 @@ static int scst_cmp_fs_ds(void)
return memcmp(&fs, &ds, sizeof(fs));
}
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0) && !defined(RHEL_MAJOR)
ssize_t kernel_write(struct file *file, const void *buf, size_t count,
loff_t *pos)
{
mm_segment_t old_fs = get_fs();
ssize_t result;
set_fs(KERNEL_DS);
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
struct iovec iov = {
.iov_base = (void __force __user *)buf,
.iov_len = count
};
result = scst_writev(file, &iov, 1, pos);
#else
result = vfs_write(file, (void __force __user *)buf, count, pos);
#endif
}
set_fs(old_fs);
return result;
return scst_writev(file, &iov, 1, pos);
}
EXPORT_SYMBOL(kernel_write);
#endif
@@ -6025,38 +6015,35 @@ 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;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
struct iov_iter iter;
struct kiocb kiocb;
size_t count = 0;
int i;
set_fs(KERNEL_DS);
WARN_ON_ONCE(scst_cmp_fs_ds() != 0);
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))
set_fs(KERNEL_DS);
WARN_ON_ONCE(scst_cmp_fs_ds() != 0);
result = vfs_readv(file, (const struct iovec __user *)vec, vlen, pos,
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));
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);
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);
result = vfs_readv(file, (const struct iovec __user *)vec, vlen, pos);
#endif
set_fs(old_fs);
#endif
return result;
}
@@ -6075,38 +6062,31 @@ 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;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
struct iov_iter iter;
struct kiocb kiocb;
size_t count = 0;
int i;
set_fs(KERNEL_DS);
WARN_ON_ONCE(scst_cmp_fs_ds() != 0);
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))
set_fs(KERNEL_DS);
WARN_ON_ONCE(scst_cmp_fs_ds() != 0);
result = vfs_writev(file, (const struct iovec __user *)vec, vlen, pos,
0);
init_sync_kiocb(&kiocb, file);
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);
file_start_write(file);
result = call_write_iter(file, &kiocb, &iter);
file_end_write(file);
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);
result = vfs_writev(file, (const struct iovec __user *)vec, vlen, pos);
#endif
set_fs(old_fs);
#endif
return result;
}
@@ -15097,7 +15077,7 @@ out_unlock:
/* Abstract vfs_unlink() for different kernel versions (as possible) */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
void scst_vfs_unlink_and_put(struct nameidata *nd)
void scst_vfs_unlink_and_put_nd(struct nameidata *nd)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
vfs_unlink(nd->dentry->d_parent->d_inode, nd->dentry);
@@ -15109,7 +15089,8 @@ void scst_vfs_unlink_and_put(struct nameidata *nd)
path_put(&nd->path);
#endif
}
#else
#endif
void scst_vfs_unlink_and_put(struct path *path)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) && \
@@ -15122,7 +15103,6 @@ void scst_vfs_unlink_and_put(struct path *path)
#endif
path_put(path);
}
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
void scst_path_put(struct nameidata *nd)
@@ -15230,21 +15210,18 @@ out:
int scst_remove_file(const char *name)
{
int res = 0;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
struct nameidata nd;
#else
struct path path;
#endif
mm_segment_t old_fs = get_fs();
TRACE_ENTRY();
set_fs(KERNEL_DS);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
res = path_lookup(name, 0, &nd);
if (!res)
scst_vfs_unlink_and_put(&nd);
scst_vfs_unlink_and_put_nd(&nd);
else
TRACE_DBG("Unable to lookup file '%s' - error %d", name, res);
#else
@@ -15255,8 +15232,6 @@ int scst_remove_file(const char *name)
TRACE_DBG("Unable to lookup file '%s' - error %d", name, res);
#endif
set_fs(old_fs);
TRACE_EXIT_RES(res);
return res;
}
+2 -2
View File
@@ -1017,14 +1017,14 @@ write_error:
write_error_close:
filp_close(file, NULL);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
{
struct nameidata nd;
int rc;
rc = path_lookup(dev->pr_file_name, 0, &nd);
if (!rc)
scst_vfs_unlink_and_put(&nd);
scst_vfs_unlink_and_put_nd(&nd);
else
TRACE_PR("Unable to lookup '%s' - error %d",
dev->pr_file_name, rc);
+2 -3
View File
@@ -766,10 +766,9 @@ int scst_pr_init(struct scst_device *dev);
void scst_pr_cleanup(struct scst_device *dev);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
void scst_vfs_unlink_and_put(struct nameidata *nd);
#else
void scst_vfs_unlink_and_put(struct path *path);
void scst_vfs_unlink_and_put_nd(struct nameidata *nd);
#endif
void scst_vfs_unlink_and_put(struct path *path);
int scst_copy_file(const char *src, const char *dest);