aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/pipe.c')
-rw-r--r--fs/pipe.c70
1 files changed, 16 insertions, 54 deletions
diff --git a/fs/pipe.c b/fs/pipe.c
index 78fd0d0788db..6679c95eb4c3 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -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 */
242void *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}
252EXPORT_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 */
263void 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}
272EXPORT_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
352static const struct pipe_buf_operations anon_pipe_buf_ops = { 306static 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
362static const struct pipe_buf_operations packet_pipe_buf_ops = { 314static 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);
412redo: 362redo:
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);
540redo1: 496redo1:
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) {