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/

Change-Id: Ib668f8fdb62ca01fe14321c07bd14d218744d909
Reviewed-on: https://gerrit.openafs.org/12729
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
This commit is contained in:
Damien Diederen 2017-09-18 12:18:39 +02:00 committed by Benjamin Kaduk
parent a71288a387
commit 5ee516b378
4 changed files with 22 additions and 1 deletions

View File

@ -1004,6 +1004,9 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*)
AC_CHECK_LINUX_FUNC([__vfs_write],
[#include <linux/fs.h>],
[__vfs_write(NULL, NULL, 0, NULL);])
AC_CHECK_LINUX_FUNC([kernel_write],
[#include <linux/fs.h>],
[kernel_write(NULL, NULL, 0, NULL);])
AC_CHECK_LINUX_FUNC([bdi_init],
[#include <linux/backing-dev.h>],
[bdi_init(NULL);])

View File

@ -645,11 +645,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
@ -660,6 +670,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

View File

@ -356,7 +356,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;
@ -366,11 +368,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;
@ -407,10 +411,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;

View File

@ -825,7 +825,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