]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
swap: fix swapfile read/write offset
authorJens Axboe <axboe@kernel.dk>
Tue, 2 Mar 2021 21:53:21 +0000 (14:53 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 7 Mar 2021 10:24:22 +0000 (11:24 +0100)
commit caf6912f3f4af7232340d500a4a2008f81b93f14 upstream.

We're not factoring in the start of the file for where to write and
read the swapfile, which leads to very unfortunate side effects of
writing where we should not be...

[This issue only affects swapfiles on filesystems on top of blockdevs
that implement rw_page ops (brd, zram, btt, pmem), and not on top of any
other block devices, in contrast to the upstream commit fix.]

Fixes: dd6bd0d9c7db ("swap: use bdev_read_page() / bdev_write_page()")
Cc: stable@vger.kernel.org # 4.4
Signed-off-by: Anthony Iliopoulos <ailiop@suse.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
mm/page_io.c
mm/swapfile.c

index b995a5ba5e8f13f49c049e99eface364148d5660..ab92cd559404061dcc8e7e6bf3507b8d75c34052 100644 (file)
@@ -32,7 +32,6 @@ static struct bio *get_swap_bio(gfp_t gfp_flags,
        bio = bio_alloc(gfp_flags, 1);
        if (bio) {
                bio->bi_iter.bi_sector = map_swap_page(page, &bio->bi_bdev);
-               bio->bi_iter.bi_sector <<= PAGE_SHIFT - 9;
                bio->bi_end_io = end_io;
 
                bio_add_page(bio, page, PAGE_SIZE, 0);
@@ -244,11 +243,6 @@ 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,
                bio_end_io_t end_write_func)
 {
@@ -297,7 +291,8 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,
                return ret;
        }
 
-       ret = bdev_write_page(sis->bdev, swap_page_sector(page), page, wbc);
+       ret = bdev_write_page(sis->bdev, map_swap_page(page, &sis->bdev),
+                             page, wbc);
        if (!ret) {
                count_vm_event(PSWPOUT);
                return 0;
@@ -345,7 +340,7 @@ int swap_readpage(struct page *page)
                return ret;
        }
 
-       ret = bdev_read_page(sis->bdev, swap_page_sector(page), page);
+       ret = bdev_read_page(sis->bdev, map_swap_page(page, &sis->bdev), page);
        if (!ret) {
                count_vm_event(PSWPIN);
                return 0;
index 8e25ff2b693a66c5a32c96c9dce6d3edadddbedf..b338d8829239c640c3c600989d2344f459d5336a 100644 (file)
@@ -1653,7 +1653,7 @@ sector_t map_swap_page(struct page *page, struct block_device **bdev)
 {
        swp_entry_t entry;
        entry.val = page_private(page);
-       return map_swap_entry(entry, bdev);
+       return map_swap_entry(entry, bdev) << (PAGE_SHIFT - 9);
 }
 
 /*