diff options
-rw-r--r-- | include/linux/swap.h | 3 | ||||
-rw-r--r-- | mm/page_io.c | 19 | ||||
-rw-r--r-- | mm/swapfile.c | 29 |
3 files changed, 25 insertions, 26 deletions
diff --git a/include/linux/swap.h b/include/linux/swap.h index abce8a0b2507..82aa7e121c05 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h | |||
@@ -318,9 +318,8 @@ extern void swapcache_free(swp_entry_t, struct page *page); | |||
318 | extern int free_swap_and_cache(swp_entry_t); | 318 | extern int free_swap_and_cache(swp_entry_t); |
319 | extern int swap_type_of(dev_t, sector_t, struct block_device **); | 319 | extern int swap_type_of(dev_t, sector_t, struct block_device **); |
320 | extern unsigned int count_swap_pages(int, int); | 320 | extern unsigned int count_swap_pages(int, int); |
321 | extern sector_t map_swap_page(struct swap_info_struct *, pgoff_t); | 321 | extern sector_t map_swap_page(swp_entry_t, struct block_device **); |
322 | extern sector_t swapdev_block(int, pgoff_t); | 322 | extern sector_t swapdev_block(int, pgoff_t); |
323 | extern struct swap_info_struct *get_swap_info_struct(unsigned); | ||
324 | extern int reuse_swap_page(struct page *); | 323 | extern int reuse_swap_page(struct page *); |
325 | extern int try_to_free_swap(struct page *); | 324 | extern int try_to_free_swap(struct page *); |
326 | struct backing_dev_info; | 325 | struct backing_dev_info; |
diff --git a/mm/page_io.c b/mm/page_io.c index c6f3e5071de3..afeed89a0a5d 100644 --- a/mm/page_io.c +++ b/mm/page_io.c | |||
@@ -19,20 +19,17 @@ | |||
19 | #include <linux/writeback.h> | 19 | #include <linux/writeback.h> |
20 | #include <asm/pgtable.h> | 20 | #include <asm/pgtable.h> |
21 | 21 | ||
22 | static struct bio *get_swap_bio(gfp_t gfp_flags, pgoff_t index, | 22 | static struct bio *get_swap_bio(gfp_t gfp_flags, |
23 | struct page *page, bio_end_io_t end_io) | 23 | struct page *page, bio_end_io_t end_io) |
24 | { | 24 | { |
25 | struct bio *bio; | 25 | struct bio *bio; |
26 | 26 | ||
27 | bio = bio_alloc(gfp_flags, 1); | 27 | bio = bio_alloc(gfp_flags, 1); |
28 | if (bio) { | 28 | if (bio) { |
29 | struct swap_info_struct *sis; | 29 | swp_entry_t entry; |
30 | swp_entry_t entry = { .val = index, }; | 30 | entry.val = page_private(page); |
31 | 31 | bio->bi_sector = map_swap_page(entry, &bio->bi_bdev); | |
32 | sis = get_swap_info_struct(swp_type(entry)); | 32 | bio->bi_sector <<= PAGE_SHIFT - 9; |
33 | bio->bi_sector = map_swap_page(sis, swp_offset(entry)) * | ||
34 | (PAGE_SIZE >> 9); | ||
35 | bio->bi_bdev = sis->bdev; | ||
36 | bio->bi_io_vec[0].bv_page = page; | 33 | bio->bi_io_vec[0].bv_page = page; |
37 | bio->bi_io_vec[0].bv_len = PAGE_SIZE; | 34 | bio->bi_io_vec[0].bv_len = PAGE_SIZE; |
38 | bio->bi_io_vec[0].bv_offset = 0; | 35 | bio->bi_io_vec[0].bv_offset = 0; |
@@ -102,8 +99,7 @@ int swap_writepage(struct page *page, struct writeback_control *wbc) | |||
102 | unlock_page(page); | 99 | unlock_page(page); |
103 | goto out; | 100 | goto out; |
104 | } | 101 | } |
105 | bio = get_swap_bio(GFP_NOIO, page_private(page), page, | 102 | bio = get_swap_bio(GFP_NOIO, page, end_swap_bio_write); |
106 | end_swap_bio_write); | ||
107 | if (bio == NULL) { | 103 | if (bio == NULL) { |
108 | set_page_dirty(page); | 104 | set_page_dirty(page); |
109 | unlock_page(page); | 105 | unlock_page(page); |
@@ -127,8 +123,7 @@ int swap_readpage(struct page *page) | |||
127 | 123 | ||
128 | VM_BUG_ON(!PageLocked(page)); | 124 | VM_BUG_ON(!PageLocked(page)); |
129 | VM_BUG_ON(PageUptodate(page)); | 125 | VM_BUG_ON(PageUptodate(page)); |
130 | bio = get_swap_bio(GFP_KERNEL, page_private(page), page, | 126 | bio = get_swap_bio(GFP_KERNEL, page, end_swap_bio_read); |
131 | end_swap_bio_read); | ||
132 | if (bio == NULL) { | 127 | if (bio == NULL) { |
133 | unlock_page(page); | 128 | unlock_page(page); |
134 | ret = -ENOMEM; | 129 | ret = -ENOMEM; |
diff --git a/mm/swapfile.c b/mm/swapfile.c index 9c590eef7912..f83f1c6f6196 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -1283,12 +1283,22 @@ static void drain_mmlist(void) | |||
1283 | 1283 | ||
1284 | /* | 1284 | /* |
1285 | * Use this swapdev's extent info to locate the (PAGE_SIZE) block which | 1285 | * Use this swapdev's extent info to locate the (PAGE_SIZE) block which |
1286 | * corresponds to page offset `offset'. | 1286 | * corresponds to page offset `offset'. Note that the type of this function |
1287 | * is sector_t, but it returns page offset into the bdev, not sector offset. | ||
1287 | */ | 1288 | */ |
1288 | sector_t map_swap_page(struct swap_info_struct *sis, pgoff_t offset) | 1289 | sector_t map_swap_page(swp_entry_t entry, struct block_device **bdev) |
1289 | { | 1290 | { |
1290 | struct swap_extent *se = sis->curr_swap_extent; | 1291 | struct swap_info_struct *sis; |
1291 | struct swap_extent *start_se = se; | 1292 | struct swap_extent *start_se; |
1293 | struct swap_extent *se; | ||
1294 | pgoff_t offset; | ||
1295 | |||
1296 | sis = swap_info + swp_type(entry); | ||
1297 | *bdev = sis->bdev; | ||
1298 | |||
1299 | offset = swp_offset(entry); | ||
1300 | start_se = sis->curr_swap_extent; | ||
1301 | se = start_se; | ||
1292 | 1302 | ||
1293 | for ( ; ; ) { | 1303 | for ( ; ; ) { |
1294 | struct list_head *lh; | 1304 | struct list_head *lh; |
@@ -1314,12 +1324,14 @@ sector_t map_swap_page(struct swap_info_struct *sis, pgoff_t offset) | |||
1314 | sector_t swapdev_block(int swap_type, pgoff_t offset) | 1324 | sector_t swapdev_block(int swap_type, pgoff_t offset) |
1315 | { | 1325 | { |
1316 | struct swap_info_struct *sis; | 1326 | struct swap_info_struct *sis; |
1327 | struct block_device *bdev; | ||
1317 | 1328 | ||
1318 | if (swap_type >= nr_swapfiles) | 1329 | if (swap_type >= nr_swapfiles) |
1319 | return 0; | 1330 | return 0; |
1320 | 1331 | ||
1321 | sis = swap_info + swap_type; | 1332 | sis = swap_info + swap_type; |
1322 | return (sis->flags & SWP_WRITEOK) ? map_swap_page(sis, offset) : 0; | 1333 | return (sis->flags & SWP_WRITEOK) ? |
1334 | map_swap_page(swp_entry(swap_type, offset), &bdev) : 0; | ||
1323 | } | 1335 | } |
1324 | #endif /* CONFIG_HIBERNATION */ | 1336 | #endif /* CONFIG_HIBERNATION */ |
1325 | 1337 | ||
@@ -2159,13 +2171,6 @@ int swapcache_prepare(swp_entry_t entry) | |||
2159 | return __swap_duplicate(entry, SWAP_CACHE); | 2171 | return __swap_duplicate(entry, SWAP_CACHE); |
2160 | } | 2172 | } |
2161 | 2173 | ||
2162 | |||
2163 | struct swap_info_struct * | ||
2164 | get_swap_info_struct(unsigned type) | ||
2165 | { | ||
2166 | return &swap_info[type]; | ||
2167 | } | ||
2168 | |||
2169 | /* | 2174 | /* |
2170 | * swap_lock prevents swap_map being freed. Don't grab an extra | 2175 | * swap_lock prevents swap_map being freed. Don't grab an extra |
2171 | * reference on the swaphandle, it doesn't matter if it becomes unused. | 2176 | * reference on the swaphandle, it doesn't matter if it becomes unused. |