diff options
Diffstat (limited to 'fs/pipe.c')
-rw-r--r-- | fs/pipe.c | 70 |
1 files changed, 16 insertions, 54 deletions
@@ -226,52 +226,6 @@ static void anon_pipe_buf_release(struct pipe_inode_info *pipe, | |||
226 | } | 226 | } |
227 | 227 | ||
228 | /** | 228 | /** |
229 | * generic_pipe_buf_map - virtually map a pipe buffer | ||
230 | * @pipe: the pipe that the buffer belongs to | ||
231 | * @buf: the buffer that should be mapped | ||
232 | * @atomic: whether to use an atomic map | ||
233 | * | ||
234 | * Description: | ||
235 | * This function returns a kernel virtual address mapping for the | ||
236 | * pipe_buffer passed in @buf. If @atomic is set, an atomic map is provided | ||
237 | * and the caller has to be careful not to fault before calling | ||
238 | * the unmap function. | ||
239 | * | ||
240 | * Note that this function calls kmap_atomic() if @atomic != 0. | ||
241 | */ | ||
242 | void *generic_pipe_buf_map(struct pipe_inode_info *pipe, | ||
243 | struct pipe_buffer *buf, int atomic) | ||
244 | { | ||
245 | if (atomic) { | ||
246 | buf->flags |= PIPE_BUF_FLAG_ATOMIC; | ||
247 | return kmap_atomic(buf->page); | ||
248 | } | ||
249 | |||
250 | return kmap(buf->page); | ||
251 | } | ||
252 | EXPORT_SYMBOL(generic_pipe_buf_map); | ||
253 | |||
254 | /** | ||
255 | * generic_pipe_buf_unmap - unmap a previously mapped pipe buffer | ||
256 | * @pipe: the pipe that the buffer belongs to | ||
257 | * @buf: the buffer that should be unmapped | ||
258 | * @map_data: the data that the mapping function returned | ||
259 | * | ||
260 | * Description: | ||
261 | * This function undoes the mapping that ->map() provided. | ||
262 | */ | ||
263 | void generic_pipe_buf_unmap(struct pipe_inode_info *pipe, | ||
264 | struct pipe_buffer *buf, void *map_data) | ||
265 | { | ||
266 | if (buf->flags & PIPE_BUF_FLAG_ATOMIC) { | ||
267 | buf->flags &= ~PIPE_BUF_FLAG_ATOMIC; | ||
268 | kunmap_atomic(map_data); | ||
269 | } else | ||
270 | kunmap(buf->page); | ||
271 | } | ||
272 | EXPORT_SYMBOL(generic_pipe_buf_unmap); | ||
273 | |||
274 | /** | ||
275 | * generic_pipe_buf_steal - attempt to take ownership of a &pipe_buffer | 229 | * generic_pipe_buf_steal - attempt to take ownership of a &pipe_buffer |
276 | * @pipe: the pipe that the buffer belongs to | 230 | * @pipe: the pipe that the buffer belongs to |
277 | * @buf: the buffer to attempt to steal | 231 | * @buf: the buffer to attempt to steal |
@@ -351,8 +305,6 @@ EXPORT_SYMBOL(generic_pipe_buf_release); | |||
351 | 305 | ||
352 | static const struct pipe_buf_operations anon_pipe_buf_ops = { | 306 | static const struct pipe_buf_operations anon_pipe_buf_ops = { |
353 | .can_merge = 1, | 307 | .can_merge = 1, |
354 | .map = generic_pipe_buf_map, | ||
355 | .unmap = generic_pipe_buf_unmap, | ||
356 | .confirm = generic_pipe_buf_confirm, | 308 | .confirm = generic_pipe_buf_confirm, |
357 | .release = anon_pipe_buf_release, | 309 | .release = anon_pipe_buf_release, |
358 | .steal = generic_pipe_buf_steal, | 310 | .steal = generic_pipe_buf_steal, |
@@ -361,8 +313,6 @@ static const struct pipe_buf_operations anon_pipe_buf_ops = { | |||
361 | 313 | ||
362 | static const struct pipe_buf_operations packet_pipe_buf_ops = { | 314 | static const struct pipe_buf_operations packet_pipe_buf_ops = { |
363 | .can_merge = 0, | 315 | .can_merge = 0, |
364 | .map = generic_pipe_buf_map, | ||
365 | .unmap = generic_pipe_buf_unmap, | ||
366 | .confirm = generic_pipe_buf_confirm, | 316 | .confirm = generic_pipe_buf_confirm, |
367 | .release = anon_pipe_buf_release, | 317 | .release = anon_pipe_buf_release, |
368 | .steal = generic_pipe_buf_steal, | 318 | .steal = generic_pipe_buf_steal, |
@@ -410,9 +360,15 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, | |||
410 | 360 | ||
411 | atomic = !iov_fault_in_pages_write(iov, chars); | 361 | atomic = !iov_fault_in_pages_write(iov, chars); |
412 | redo: | 362 | redo: |
413 | addr = ops->map(pipe, buf, atomic); | 363 | if (atomic) |
364 | addr = kmap_atomic(buf->page); | ||
365 | else | ||
366 | addr = kmap(buf->page); | ||
414 | error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars, atomic); | 367 | error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars, atomic); |
415 | ops->unmap(pipe, buf, addr); | 368 | if (atomic) |
369 | kunmap_atomic(addr); | ||
370 | else | ||
371 | kunmap(buf->page); | ||
416 | if (unlikely(error)) { | 372 | if (unlikely(error)) { |
417 | /* | 373 | /* |
418 | * Just retry with the slow path if we failed. | 374 | * Just retry with the slow path if we failed. |
@@ -538,10 +494,16 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, | |||
538 | 494 | ||
539 | iov_fault_in_pages_read(iov, chars); | 495 | iov_fault_in_pages_read(iov, chars); |
540 | redo1: | 496 | redo1: |
541 | addr = ops->map(pipe, buf, atomic); | 497 | if (atomic) |
498 | addr = kmap_atomic(buf->page); | ||
499 | else | ||
500 | addr = kmap(buf->page); | ||
542 | error = pipe_iov_copy_from_user(offset + addr, iov, | 501 | error = pipe_iov_copy_from_user(offset + addr, iov, |
543 | chars, atomic); | 502 | chars, atomic); |
544 | ops->unmap(pipe, buf, addr); | 503 | if (atomic) |
504 | kunmap_atomic(addr); | ||
505 | else | ||
506 | kunmap(buf->page); | ||
545 | ret = error; | 507 | ret = error; |
546 | do_wakeup = 1; | 508 | do_wakeup = 1; |
547 | if (error) { | 509 | if (error) { |