|
@@ -943,11 +943,25 @@ bool reuse_swap_page(struct page *page, int *total_mapcount)
|
|
count = page_trans_huge_mapcount(page, total_mapcount);
|
|
count = page_trans_huge_mapcount(page, total_mapcount);
|
|
if (count <= 1 && PageSwapCache(page)) {
|
|
if (count <= 1 && PageSwapCache(page)) {
|
|
count += page_swapcount(page);
|
|
count += page_swapcount(page);
|
|
- if (count == 1 && !PageWriteback(page)) {
|
|
|
|
|
|
+ if (count != 1)
|
|
|
|
+ goto out;
|
|
|
|
+ if (!PageWriteback(page)) {
|
|
delete_from_swap_cache(page);
|
|
delete_from_swap_cache(page);
|
|
SetPageDirty(page);
|
|
SetPageDirty(page);
|
|
|
|
+ } else {
|
|
|
|
+ swp_entry_t entry;
|
|
|
|
+ struct swap_info_struct *p;
|
|
|
|
+
|
|
|
|
+ entry.val = page_private(page);
|
|
|
|
+ p = swap_info_get(entry);
|
|
|
|
+ if (p->flags & SWP_STABLE_WRITES) {
|
|
|
|
+ spin_unlock(&p->lock);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ spin_unlock(&p->lock);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+out:
|
|
return count <= 1;
|
|
return count <= 1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2448,6 +2462,10 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
|
|
error = -ENOMEM;
|
|
error = -ENOMEM;
|
|
goto bad_swap;
|
|
goto bad_swap;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (bdi_cap_stable_pages_required(inode_to_bdi(inode)))
|
|
|
|
+ p->flags |= SWP_STABLE_WRITES;
|
|
|
|
+
|
|
if (p->bdev && blk_queue_nonrot(bdev_get_queue(p->bdev))) {
|
|
if (p->bdev && blk_queue_nonrot(bdev_get_queue(p->bdev))) {
|
|
int cpu;
|
|
int cpu;
|
|
|
|
|