block_io.c 2.4 KB

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