Merge tag 'trace-3.16-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[pandora-kernel.git] / mm / page_io.c
index 7c59ef6..243a9b7 100644 (file)
@@ -248,20 +248,33 @@ out:
        return ret;
 }
 
+static sector_t swap_page_sector(struct page *page)
+{
+       return (sector_t)__page_file_index(page) << (PAGE_CACHE_SHIFT - 9);
+}
+
 int __swap_writepage(struct page *page, struct writeback_control *wbc,
        void (*end_write_func)(struct bio *, int))
 {
        struct bio *bio;
-       int ret = 0, rw = WRITE;
+       int ret, rw = WRITE;
        struct swap_info_struct *sis = page_swap_info(page);
 
        if (sis->flags & SWP_FILE) {
                struct kiocb kiocb;
                struct file *swap_file = sis->swap_file;
                struct address_space *mapping = swap_file->f_mapping;
-               struct iovec iov = {
-                       .iov_base = kmap(page),
-                       .iov_len  = PAGE_SIZE,
+               struct bio_vec bv = {
+                       .bv_page = page,
+                       .bv_len  = PAGE_SIZE,
+                       .bv_offset = 0
+               };
+               struct iov_iter from = {
+                       .type = ITER_BVEC | WRITE,
+                       .count = PAGE_SIZE,
+                       .iov_offset = 0,
+                       .nr_segs = 1,
+                       .bvec = &bv
                };
 
                init_sync_kiocb(&kiocb, swap_file);
@@ -270,10 +283,9 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,
 
                set_page_writeback(page);
                unlock_page(page);
-               ret = mapping->a_ops->direct_IO(KERNEL_WRITE,
-                                               &kiocb, &iov,
-                                               kiocb.ki_pos, 1);
-               kunmap(page);
+               ret = mapping->a_ops->direct_IO(ITER_BVEC | WRITE,
+                                               &kiocb, &from,
+                                               kiocb.ki_pos);
                if (ret == PAGE_SIZE) {
                        count_vm_event(PSWPOUT);
                        ret = 0;
@@ -297,6 +309,13 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,
                return ret;
        }
 
+       ret = bdev_write_page(sis->bdev, swap_page_sector(page), page, wbc);
+       if (!ret) {
+               count_vm_event(PSWPOUT);
+               return 0;
+       }
+
+       ret = 0;
        bio = get_swap_bio(GFP_NOIO, page, end_write_func);
        if (bio == NULL) {
                set_page_dirty(page);
@@ -338,6 +357,13 @@ int swap_readpage(struct page *page)
                return ret;
        }
 
+       ret = bdev_read_page(sis->bdev, swap_page_sector(page), page);
+       if (!ret) {
+               count_vm_event(PSWPIN);
+               return 0;
+       }
+
+       ret = 0;
        bio = get_swap_bio(GFP_KERNEL, page, end_swap_bio_read);
        if (bio == NULL) {
                unlock_page(page);