From 8c11a97ec0991800c12311a123134f8b5fd59f5e Mon Sep 17 00:00:00 2001 From: Damien Diederen Date: Mon, 18 Sep 2017 12:18:39 +0200 Subject: [PATCH 3/3] Linux: Use kernel_read/kernel_write when __vfs variants are unavailable We hide the uses of set_fs/get_fs behind a macro, as those functions are likely to soon become unavailable: > Christoph Hellwig suggested removing all calls outside of the core > filesystem and architecture code; Andy Lutomirski went one step > further and said they should all go. https://lwn.net/Articles/722267/ Reviewed-on: https://gerrit.openafs.org/12729 Tested-by: BuildBot Reviewed-by: Mark Vitale Reviewed-by: Benjamin Kaduk (cherry picked from commit 5ee516b3789d3545f3d78fb3aba2480308359945) Reviewed-on: https://gerrit.openafs.org/12737 Tested-by: BuildBot Reviewed-by: Michael Meffie Reviewed-by: Mark Vitale Reviewed-by: Benjamin Kaduk (cherry picked from commit d93f80622370f50d7bce5c5b00cd062f15ee9eba) Change-Id: Ib4515c858d0a06d3706ec7de212c35551d3e7240 --- acinclude.m4 | 3 +++ src/afs/LINUX/osi_compat.h | 12 ++++++++++++ src/afs/LINUX/osi_file.c | 6 ++++++ src/afs/LINUX/osi_vnodeops.c | 2 +- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index 8353ca597..94b943622 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -942,6 +942,9 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) AC_CHECK_LINUX_FUNC([__vfs_write], [#include ], [__vfs_write(NULL, NULL, 0, NULL);]) + AC_CHECK_LINUX_FUNC([kernel_write], + [#include ], + [kernel_write(NULL, NULL, 0, NULL);]) AC_CHECK_LINUX_FUNC([bdi_init], [#include ], [bdi_init(NULL);]) diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h index 9ebe9c178..9871535f0 100644 --- a/src/afs/LINUX/osi_compat.h +++ b/src/afs/LINUX/osi_compat.h @@ -592,11 +592,21 @@ afs_d_invalidate(struct dentry *dp) #endif } +#if defined(HAVE_LINUX___VFS_WRITE) +# define AFS_FILE_NEEDS_SET_FS 1 +#elif defined(HAVE_LINUX_KERNEL_WRITE) +/* #undef AFS_FILE_NEEDS_SET_FS */ +#else +# define AFS_FILE_NEEDS_SET_FS 1 +#endif + static inline int afs_file_read(struct file *filp, char __user *buf, size_t len, loff_t *pos) { #if defined(HAVE_LINUX___VFS_WRITE) return __vfs_read(filp, buf, len, pos); +#elif defined(HAVE_LINUX_KERNEL_WRITE) + return kernel_read(filp, buf, len, pos); #else return filp->f_op->read(filp, buf, len, pos); #endif @@ -607,6 +617,8 @@ afs_file_write(struct file *filp, char __user *buf, size_t len, loff_t *pos) { #if defined(HAVE_LINUX___VFS_WRITE) return __vfs_write(filp, buf, len, pos); +#elif defined(HAVE_LINUX_KERNEL_WRITE) + return kernel_write(filp, buf, len, pos); #else return filp->f_op->write(filp, buf, len, pos); #endif diff --git a/src/afs/LINUX/osi_file.c b/src/afs/LINUX/osi_file.c index f889fd16b..a028ee740 100644 --- a/src/afs/LINUX/osi_file.c +++ b/src/afs/LINUX/osi_file.c @@ -357,7 +357,9 @@ int osi_rdwr(struct osi_file *osifile, struct uio *uiop, int rw) { struct file *filp = osifile->filp; +#ifdef AFS_FILE_NEEDS_SET_FS mm_segment_t old_fs = {0}; +#endif /* AFS_FILE_NEEDS_SET_FS */ int code = 0; struct iovec *iov; size_t count; @@ -367,11 +369,13 @@ osi_rdwr(struct osi_file *osifile, struct uio *uiop, int rw) savelim = current->TASK_STRUCT_RLIM[RLIMIT_FSIZE].rlim_cur; current->TASK_STRUCT_RLIM[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; +#ifdef AFS_FILE_NEEDS_SET_FS if (uiop->uio_seg == AFS_UIOSYS) { /* Switch into user space */ old_fs = get_fs(); set_fs(get_ds()); } +#endif /* AFS_FILE_NEEDS_SET_FS */ while (code == 0 && uiop->uio_resid > 0 && uiop->uio_iovcnt > 0) { iov = uiop->uio_iov; @@ -408,10 +412,12 @@ osi_rdwr(struct osi_file *osifile, struct uio *uiop, int rw) code = 0; } +#ifdef AFS_FILE_NEEDS_SET_FS if (uiop->uio_seg == AFS_UIOSYS) { /* Switch back into kernel space */ set_fs(old_fs); } +#endif /* AFS_FILE_NEEDS_SET_FS */ current->TASK_STRUCT_RLIM[RLIMIT_FSIZE].rlim_cur = savelim; diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 3d9d71791..051452b34 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -807,7 +807,7 @@ struct file_operations afs_file_fops = { #ifdef STRUCT_FILE_OPERATIONS_HAS_READ_ITER .read_iter = afs_linux_read_iter, .write_iter = afs_linux_write_iter, -# if !defined(HAVE_LINUX___VFS_WRITE) +# if !defined(HAVE_LINUX___VFS_WRITE) && !defined(HAVE_LINUX_KERNEL_WRITE) .read = new_sync_read, .write = new_sync_write, # endif -- 2.15.0