Blame view
kernel/power/block_io.c
2.37 KB
8a0d613fa PM / Hibernate: S... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
/* * This file provides functions for block I/O operations on swap/file. * * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@ucw.cz> * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl> * * This file is released under the GPLv2. */ #include <linux/bio.h> #include <linux/kernel.h> #include <linux/pagemap.h> #include <linux/swap.h> #include "power.h" /** * submit - submit BIO request. * @rw: READ or WRITE. * @off physical offset of page. * @page: page we're reading or writing. * @bio_chain: list of pending biod (for async reading) * * Straight from the textbook - allocate and initialize the bio. * If we're reading, make sure the page is marked as dirty. * Then submit it and, if @bio_chain == NULL, wait. */ static int submit(int rw, struct block_device *bdev, sector_t sector, struct page *page, struct bio **bio_chain) { |
721a9602e block: kill off R... |
31 |
const int bio_rw = rw | REQ_SYNC; |
8a0d613fa PM / Hibernate: S... |
32 33 34 35 36 37 38 39 |
struct bio *bio; bio = bio_alloc(__GFP_WAIT | __GFP_HIGH, 1); bio->bi_sector = sector; bio->bi_bdev = bdev; bio->bi_end_io = end_swap_bio_read; if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) { |
0fef8b1e8 PM / Hibernate: F... |
40 41 42 |
printk(KERN_ERR "PM: Adding page to bio failed at %llu ", (unsigned long long)sector); |
8a0d613fa PM / Hibernate: S... |
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
bio_put(bio); return -EFAULT; } lock_page(page); bio_get(bio); if (bio_chain == NULL) { submit_bio(bio_rw, bio); wait_on_page_locked(page); if (rw == READ) bio_set_pages_dirty(bio); bio_put(bio); } else { if (rw == READ) get_page(page); /* These pages are freed later */ bio->bi_private = *bio_chain; *bio_chain = bio; submit_bio(bio_rw, bio); } return 0; } int hib_bio_read_page(pgoff_t page_off, void *addr, struct bio **bio_chain) { return submit(READ, hib_resume_bdev, page_off * (PAGE_SIZE >> 9), virt_to_page(addr), bio_chain); } int hib_bio_write_page(pgoff_t page_off, void *addr, struct bio **bio_chain) { return submit(WRITE, hib_resume_bdev, page_off * (PAGE_SIZE >> 9), virt_to_page(addr), bio_chain); } int hib_wait_on_bio_chain(struct bio **bio_chain) { struct bio *bio; struct bio *next_bio; int ret = 0; if (bio_chain == NULL) return 0; bio = *bio_chain; if (bio == NULL) return 0; while (bio) { struct page *page; next_bio = bio->bi_private; page = bio->bi_io_vec[0].bv_page; wait_on_page_locked(page); if (!PageUptodate(page) || PageError(page)) ret = -EIO; put_page(page); bio_put(bio); bio = next_bio; } *bio_chain = NULL; return ret; } |