]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.suse/SoN-fix-sync
Merge branch 'master' of git://git.ipfire.org/ipfire-2.x
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.suse / SoN-fix-sync
1 References: 441793
2 Subject: Cope with racy nature of sync_page in swap_sync_page
3
4 From: NeilBrown <neilb@suse.de>
5
6 sync_page is called without that PageLock held. This means that,
7 for example, PageSwapCache can be cleared at any time.
8 We need to be careful not to put much trust any any part of the page.
9
10 So allow page_swap_info to return NULL of the page is no longer
11 in a SwapCache, and handle the NULL gracefully in swap_sync_page.
12
13 No other calls need to handle the NULL as that all hold PageLock,
14 so PageSwapCache cannot be cleared by surprise. Add a WARN_ON to
15 document this fact and help find out if I am wrong.
16
17 Acked-By: Miklos Szeredi <mszeredi@novell.com>
18 Signed-off-by: NeilBrown <neilb@suse.de>
19
20 ---
21 mm/page_io.c | 2 ++
22 mm/swapfile.c | 9 ++++++++-
23 2 files changed, 10 insertions(+), 1 deletion(-)
24
25 --- linux-2.6.27.orig/mm/page_io.c
26 +++ linux-2.6.27/mm/page_io.c
27 @@ -139,6 +139,8 @@ void swap_sync_page(struct page *page)
28 {
29 struct swap_info_struct *sis = page_swap_info(page);
30
31 + if (!sis)
32 + return;
33 if (sis->flags & SWP_FILE) {
34 struct address_space *mapping = sis->swap_file->f_mapping;
35
36 --- linux-2.6.27.orig/mm/swapfile.c
37 +++ linux-2.6.27/mm/swapfile.c
38 @@ -1845,7 +1845,13 @@ get_swap_info_struct(unsigned type)
39 struct swap_info_struct *page_swap_info(struct page *page)
40 {
41 swp_entry_t swap = { .val = page_private(page) };
42 - BUG_ON(!PageSwapCache(page));
43 + if (!PageSwapCache(page) || !swap.val) {
44 + /* This should only happen from sync_page.
45 + * In other cases the page should be locked and
46 + * should be in a SwapCache
47 + */
48 + return NULL;
49 + }
50 return &swap_info[swp_type(swap)];
51 }
52