diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-04-04 23:12:29 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-05-06 17:39:45 -0400 |
commit | 62a8067a7f35dba2de501c9cb00e4cf36da90bc0 (patch) | |
tree | bb008456891c13b9d8a25825a10074efb861cd88 /mm/page_io.c | |
parent | 81055e584f9d743cb13dc7944923d817c20f089d (diff) |
bio_vec-backed iov_iter
New variant of iov_iter - ITER_BVEC in iter->type, backed with
bio_vec array instead of iovec one. Primitives taught to deal
with such beasts, __swap_write() switched to using that kind
of iov_iter.
Note that bio_vec is just a <page, offset, length> triple - there's
nothing block-specific about it. I've left the definition where it
was, but took it from under ifdef CONFIG_BLOCK.
Next target: ->splice_write()...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'mm/page_io.c')
-rw-r--r-- | mm/page_io.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/mm/page_io.c b/mm/page_io.c index 313bfedb75d1..33bb38c4aad7 100644 --- a/mm/page_io.c +++ b/mm/page_io.c | |||
@@ -259,23 +259,28 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc, | |||
259 | struct kiocb kiocb; | 259 | struct kiocb kiocb; |
260 | struct file *swap_file = sis->swap_file; | 260 | struct file *swap_file = sis->swap_file; |
261 | struct address_space *mapping = swap_file->f_mapping; | 261 | struct address_space *mapping = swap_file->f_mapping; |
262 | struct iovec iov = { | 262 | struct bio_vec bv = { |
263 | .iov_base = kmap(page), | 263 | .bv_page = page, |
264 | .iov_len = PAGE_SIZE, | 264 | .bv_len = PAGE_SIZE, |
265 | .bv_offset = 0 | ||
266 | }; | ||
267 | struct iov_iter from = { | ||
268 | .type = ITER_BVEC | WRITE, | ||
269 | .count = PAGE_SIZE, | ||
270 | .iov_offset = 0, | ||
271 | .nr_segs = 1, | ||
272 | .bvec = &bv | ||
265 | }; | 273 | }; |
266 | struct iov_iter from; | ||
267 | 274 | ||
268 | init_sync_kiocb(&kiocb, swap_file); | 275 | init_sync_kiocb(&kiocb, swap_file); |
269 | kiocb.ki_pos = page_file_offset(page); | 276 | kiocb.ki_pos = page_file_offset(page); |
270 | kiocb.ki_nbytes = PAGE_SIZE; | 277 | kiocb.ki_nbytes = PAGE_SIZE; |
271 | iov_iter_init(&from, KERNEL_WRITE, &iov, 1, PAGE_SIZE); | ||
272 | 278 | ||
273 | set_page_writeback(page); | 279 | set_page_writeback(page); |
274 | unlock_page(page); | 280 | unlock_page(page); |
275 | ret = mapping->a_ops->direct_IO(KERNEL_WRITE, | 281 | ret = mapping->a_ops->direct_IO(ITER_BVEC | WRITE, |
276 | &kiocb, &from, | 282 | &kiocb, &from, |
277 | kiocb.ki_pos); | 283 | kiocb.ki_pos); |
278 | kunmap(page); | ||
279 | if (ret == PAGE_SIZE) { | 284 | if (ret == PAGE_SIZE) { |
280 | count_vm_event(PSWPOUT); | 285 | count_vm_event(PSWPOUT); |
281 | ret = 0; | 286 | ret = 0; |