]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Miklos Szeredi <mszeredi@suse.cz> |
2 | Subject: fix kabi breakage from i_mutex locking fix | |
3 | Patch-mainline: no | |
4 | References: bnc#495065 | |
5 | ||
6 | Splice splice_desc into two structures, splice_desc (the old version) | |
7 | and splice_desc_ext, containing the new fields. | |
8 | ||
9 | Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> | |
10 | --- | |
11 | fs/ocfs2/file.c | 18 +++++++++-------- | |
12 | fs/splice.c | 51 ++++++++++++++++++++++++++----------------------- | |
13 | include/linux/splice.h | 12 +++++++---- | |
14 | 3 files changed, 46 insertions(+), 35 deletions(-) | |
15 | ||
16 | --- a/fs/ocfs2/file.c | |
17 | +++ b/fs/ocfs2/file.c | |
18 | @@ -2077,9 +2077,10 @@ out_sems: | |
19 | ||
20 | static int ocfs2_splice_to_file(struct pipe_inode_info *pipe, | |
21 | struct file *out, | |
22 | - struct splice_desc *sd) | |
23 | + struct splice_desc_ext *esd) | |
24 | { | |
25 | int ret; | |
26 | + struct splice_desc *sd = esd->sd; | |
27 | ||
28 | ret = ocfs2_prepare_inode_for_write(out->f_path.dentry, &sd->pos, | |
29 | sd->total_len, 0, NULL); | |
30 | @@ -2088,7 +2089,7 @@ static int ocfs2_splice_to_file(struct p | |
31 | return ret; | |
32 | } | |
33 | ||
34 | - return splice_from_pipe_feed(pipe, sd, pipe_to_file); | |
35 | + return splice_from_pipe_feed(pipe, esd, pipe_to_file); | |
36 | } | |
37 | ||
38 | static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, | |
39 | @@ -2106,6 +2107,7 @@ static ssize_t ocfs2_file_splice_write(s | |
40 | .pos = *ppos, | |
41 | .u.file = out, | |
42 | }; | |
43 | + struct splice_desc_ext esd = { .sd = &sd }; | |
44 | ||
45 | mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", out, pipe, | |
46 | (unsigned int)len, | |
47 | @@ -2115,9 +2117,9 @@ static ssize_t ocfs2_file_splice_write(s | |
48 | if (pipe->inode) | |
49 | mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_PARENT); | |
50 | ||
51 | - splice_from_pipe_begin(&sd); | |
52 | + splice_from_pipe_begin(&esd); | |
53 | do { | |
54 | - ret = splice_from_pipe_next(pipe, &sd); | |
55 | + ret = splice_from_pipe_next(pipe, &esd); | |
56 | if (ret <= 0) | |
57 | break; | |
58 | ||
59 | @@ -2126,18 +2128,18 @@ static ssize_t ocfs2_file_splice_write(s | |
60 | if (ret < 0) | |
61 | mlog_errno(ret); | |
62 | else { | |
63 | - ret = ocfs2_splice_to_file(pipe, out, &sd); | |
64 | + ret = ocfs2_splice_to_file(pipe, out, &esd); | |
65 | ocfs2_rw_unlock(inode, 1); | |
66 | } | |
67 | mutex_unlock(&inode->i_mutex); | |
68 | } while (ret > 0); | |
69 | - splice_from_pipe_end(pipe, &sd); | |
70 | + splice_from_pipe_end(pipe, &esd); | |
71 | ||
72 | if (pipe->inode) | |
73 | mutex_unlock(&pipe->inode->i_mutex); | |
74 | ||
75 | - if (sd.num_spliced) | |
76 | - ret = sd.num_spliced; | |
77 | + if (esd.num_spliced) | |
78 | + ret = esd.num_spliced; | |
79 | ||
80 | if (ret > 0) { | |
81 | unsigned long nr_pages; | |
82 | --- a/fs/splice.c | |
83 | +++ b/fs/splice.c | |
84 | @@ -629,10 +629,11 @@ static void wakeup_pipe_writers(struct p | |
85 | * locking is required around copying the pipe buffers to the | |
86 | * destination. | |
87 | */ | |
88 | -int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_desc *sd, | |
89 | +int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_desc_ext *esd, | |
90 | splice_actor *actor) | |
91 | { | |
92 | int ret; | |
93 | + struct splice_desc *sd = esd->sd; | |
94 | ||
95 | while (pipe->nrbufs) { | |
96 | struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; | |
97 | @@ -651,7 +652,7 @@ int splice_from_pipe_feed(struct pipe_in | |
98 | buf->offset += ret; | |
99 | buf->len -= ret; | |
100 | ||
101 | - sd->num_spliced += ret; | |
102 | + esd->num_spliced += ret; | |
103 | sd->len -= ret; | |
104 | sd->pos += ret; | |
105 | sd->total_len -= ret; | |
106 | @@ -662,7 +663,7 @@ int splice_from_pipe_feed(struct pipe_in | |
107 | pipe->curbuf = (pipe->curbuf + 1) & (PIPE_BUFFERS - 1); | |
108 | pipe->nrbufs--; | |
109 | if (pipe->inode) | |
110 | - sd->need_wakeup = true; | |
111 | + esd->need_wakeup = true; | |
112 | } | |
113 | ||
114 | if (!sd->total_len) | |
115 | @@ -683,13 +684,15 @@ EXPORT_SYMBOL(splice_from_pipe_feed); | |
116 | * value (one) if pipe buffers are available. It will return zero | |
117 | * or -errno if no more data needs to be spliced. | |
118 | */ | |
119 | -int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_desc *sd) | |
120 | +int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_desc_ext *esd) | |
121 | { | |
122 | + struct splice_desc *sd = esd->sd; | |
123 | + | |
124 | while (!pipe->nrbufs) { | |
125 | if (!pipe->writers) | |
126 | return 0; | |
127 | ||
128 | - if (!pipe->waiting_writers && sd->num_spliced) | |
129 | + if (!pipe->waiting_writers && esd->num_spliced) | |
130 | return 0; | |
131 | ||
132 | if (sd->flags & SPLICE_F_NONBLOCK) | |
133 | @@ -698,9 +701,9 @@ int splice_from_pipe_next(struct pipe_in | |
134 | if (signal_pending(current)) | |
135 | return -ERESTARTSYS; | |
136 | ||
137 | - if (sd->need_wakeup) { | |
138 | + if (esd->need_wakeup) { | |
139 | wakeup_pipe_writers(pipe); | |
140 | - sd->need_wakeup = false; | |
141 | + esd->need_wakeup = false; | |
142 | } | |
143 | ||
144 | pipe_wait(pipe); | |
145 | @@ -719,10 +722,10 @@ EXPORT_SYMBOL(splice_from_pipe_next); | |
146 | * splice_from_pipe_next() and splice_from_pipe_feed() to | |
147 | * initialize the necessary fields of @sd. | |
148 | */ | |
149 | -void splice_from_pipe_begin(struct splice_desc *sd) | |
150 | +void splice_from_pipe_begin(struct splice_desc_ext *esd) | |
151 | { | |
152 | - sd->num_spliced = 0; | |
153 | - sd->need_wakeup = false; | |
154 | + esd->num_spliced = 0; | |
155 | + esd->need_wakeup = false; | |
156 | } | |
157 | EXPORT_SYMBOL(splice_from_pipe_begin); | |
158 | ||
159 | @@ -736,9 +739,9 @@ EXPORT_SYMBOL(splice_from_pipe_begin); | |
160 | * be called after a loop containing splice_from_pipe_next() and | |
161 | * splice_from_pipe_feed(). | |
162 | */ | |
163 | -void splice_from_pipe_end(struct pipe_inode_info *pipe, struct splice_desc *sd) | |
164 | +void splice_from_pipe_end(struct pipe_inode_info *pipe, struct splice_desc_ext *esd) | |
165 | { | |
166 | - if (sd->need_wakeup) | |
167 | + if (esd->need_wakeup) | |
168 | wakeup_pipe_writers(pipe); | |
169 | } | |
170 | EXPORT_SYMBOL(splice_from_pipe_end); | |
171 | @@ -760,16 +763,17 @@ ssize_t __splice_from_pipe(struct pipe_i | |
172 | splice_actor *actor) | |
173 | { | |
174 | int ret; | |
175 | + struct splice_desc_ext esd = { .sd = sd }; | |
176 | ||
177 | - splice_from_pipe_begin(sd); | |
178 | + splice_from_pipe_begin(&esd); | |
179 | do { | |
180 | - ret = splice_from_pipe_next(pipe, sd); | |
181 | + ret = splice_from_pipe_next(pipe, &esd); | |
182 | if (ret > 0) | |
183 | - ret = splice_from_pipe_feed(pipe, sd, actor); | |
184 | + ret = splice_from_pipe_feed(pipe, &esd, actor); | |
185 | } while (ret > 0); | |
186 | - splice_from_pipe_end(pipe, sd); | |
187 | + splice_from_pipe_end(pipe, &esd); | |
188 | ||
189 | - return sd->num_spliced ? sd->num_spliced : ret; | |
190 | + return esd.num_spliced ? esd.num_spliced : ret; | |
191 | } | |
192 | EXPORT_SYMBOL(__splice_from_pipe); | |
193 | ||
194 | @@ -892,30 +896,31 @@ generic_file_splice_write(struct pipe_in | |
195 | .pos = *ppos, | |
196 | .u.file = out, | |
197 | }; | |
198 | + struct splice_desc_ext esd = { .sd = &sd }; | |
199 | ssize_t ret; | |
200 | ||
201 | if (pipe->inode) | |
202 | mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_PARENT); | |
203 | ||
204 | - splice_from_pipe_begin(&sd); | |
205 | + splice_from_pipe_begin(&esd); | |
206 | do { | |
207 | - ret = splice_from_pipe_next(pipe, &sd); | |
208 | + ret = splice_from_pipe_next(pipe, &esd); | |
209 | if (ret <= 0) | |
210 | break; | |
211 | ||
212 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); | |
213 | ret = file_remove_suid(out); | |
214 | if (!ret) | |
215 | - ret = splice_from_pipe_feed(pipe, &sd, pipe_to_file); | |
216 | + ret = splice_from_pipe_feed(pipe, &esd, pipe_to_file); | |
217 | mutex_unlock(&inode->i_mutex); | |
218 | } while (ret > 0); | |
219 | - splice_from_pipe_end(pipe, &sd); | |
220 | + splice_from_pipe_end(pipe, &esd); | |
221 | ||
222 | if (pipe->inode) | |
223 | mutex_unlock(&pipe->inode->i_mutex); | |
224 | ||
225 | - if (sd.num_spliced) | |
226 | - ret = sd.num_spliced; | |
227 | + if (esd.num_spliced) | |
228 | + ret = esd.num_spliced; | |
229 | ||
230 | if (ret > 0) { | |
231 | unsigned long nr_pages; | |
232 | --- a/include/linux/splice.h | |
233 | +++ b/include/linux/splice.h | |
234 | @@ -36,6 +36,10 @@ struct splice_desc { | |
235 | void *data; /* cookie */ | |
236 | } u; | |
237 | loff_t pos; /* file position */ | |
238 | +}; | |
239 | + | |
240 | +struct splice_desc_ext { | |
241 | + struct splice_desc *sd; | |
242 | size_t num_spliced; /* number of bytes already spliced */ | |
243 | bool need_wakeup; /* need to wake up writer */ | |
244 | }; | |
245 | @@ -68,13 +72,13 @@ extern ssize_t splice_from_pipe(struct p | |
246 | splice_actor *); | |
247 | extern ssize_t __splice_from_pipe(struct pipe_inode_info *, | |
248 | struct splice_desc *, splice_actor *); | |
249 | -extern int splice_from_pipe_feed(struct pipe_inode_info *, struct splice_desc *, | |
250 | +extern int splice_from_pipe_feed(struct pipe_inode_info *, struct splice_desc_ext *, | |
251 | splice_actor *); | |
252 | extern int splice_from_pipe_next(struct pipe_inode_info *, | |
253 | - struct splice_desc *); | |
254 | -extern void splice_from_pipe_begin(struct splice_desc *); | |
255 | + struct splice_desc_ext *); | |
256 | +extern void splice_from_pipe_begin(struct splice_desc_ext *); | |
257 | extern void splice_from_pipe_end(struct pipe_inode_info *, | |
258 | - struct splice_desc *); | |
259 | + struct splice_desc_ext *); | |
260 | extern int pipe_to_file(struct pipe_inode_info *, struct pipe_buffer *, | |
261 | struct splice_desc *); | |
262 |