From: "Ken Chen" On 3/26/07, Andrew Morton wrote: > LTP's vmsplice01 triggers the below: > > Unable to handle kernel NULL pointer dereference at 0000000000000130 RIP: > [] pipe_to_file+0x1f3/0x2a6 Ouch, generic_pipe_buf_map() and unmap is used by both pipe and splice, I better constrain all changes within fs/pipe.c because from splice path, the page->private is not initialized. Double ouch for missing test that code path. Here is an updated patch, tested with LTP and FIO. I will write more test cases to make sure all code path are covered. Signed-off-by: Andrew Morton --- fs/pipe.c | 27 ++++++++++++++++++++++++--- 1 files changed, 24 insertions(+), 3 deletions(-) diff -puN fs/pipe.c~cache-pipe-buf-page-address-for-non-highmem-arch-fix fs/pipe.c --- a/fs/pipe.c~cache-pipe-buf-page-address-for-non-highmem-arch-fix +++ a/fs/pipe.c @@ -184,13 +184,34 @@ void *generic_pipe_buf_map(struct pipe_i { if (atomic) { buf->flags |= PIPE_BUF_FLAG_ATOMIC; + return kmap_atomic(buf->page, KM_USER0); + } + + return kmap(buf->page); +} + +void generic_pipe_buf_unmap(struct pipe_inode_info *pipe, + struct pipe_buffer *buf, void *map_data) +{ + if (buf->flags & PIPE_BUF_FLAG_ATOMIC) { + buf->flags &= ~PIPE_BUF_FLAG_ATOMIC; + kunmap_atomic(map_data, KM_USER0); + } else + kunmap(buf->page); +} + +static void *pipe_buf_map(struct pipe_inode_info *pipe, + struct pipe_buffer *buf, int atomic) +{ + if (atomic) { + buf->flags |= PIPE_BUF_FLAG_ATOMIC; return pipe_kmap_atomic(buf->page, KM_USER0); } return pipe_kmap(buf->page); } -void generic_pipe_buf_unmap(struct pipe_inode_info *pipe, +static void pipe_buf_unmap(struct pipe_inode_info *pipe, struct pipe_buffer *buf, void *map_data) { if (buf->flags & PIPE_BUF_FLAG_ATOMIC) { @@ -225,8 +246,8 @@ int generic_pipe_buf_pin(struct pipe_ino static const struct pipe_buf_operations anon_pipe_buf_ops = { .can_merge = 1, - .map = generic_pipe_buf_map, - .unmap = generic_pipe_buf_unmap, + .map = pipe_buf_map, + .unmap = pipe_buf_unmap, .pin = generic_pipe_buf_pin, .release = anon_pipe_buf_release, .steal = generic_pipe_buf_steal, _