summarylogtreecommitdiffstats
path: root/0003-Linux-Use-kernel_read-kernel_write-when-__vfs-varian.patch
blob: e9530743b81f969afb42bbc1fe7cee49c8f4051f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
From 8c11a97ec0991800c12311a123134f8b5fd59f5e Mon Sep 17 00:00:00 2001
From: Damien Diederen <ddiederen@sinenomine.net>
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 <buildbot@rampaginggeek.com>
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
(cherry picked from commit 5ee516b3789d3545f3d78fb3aba2480308359945)

Reviewed-on: https://gerrit.openafs.org/12737
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
(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 <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);])
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