aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorLuden <luden@ghostmail.com>2016-02-14 00:00:13 +0100
committerZiyan <jaraidaniel@gmail.com>2016-05-01 23:35:57 +0200
commite0f3b2e128dd26d96e43317565f4a7ee90138e92 (patch)
tree444ab4acd14e343b097be064e1a1e21cad00f9bd /mm
parent7fd80cc6a3049e630d84d2baaae87fa1eece486c (diff)
downloadkernel_samsung_tuna-e0f3b2e128dd26d96e43317565f4a7ee90138e92.tar.gz
kernel_samsung_tuna-e0f3b2e128dd26d96e43317565f4a7ee90138e92.tar.bz2
kernel_samsung_tuna-e0f3b2e128dd26d96e43317565f4a7ee90138e92.zip
Added buffers flushing for dirty pages.
Diffstat (limited to 'mm')
-rw-r--r--mm/migrate.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/mm/migrate.c b/mm/migrate.c
index e598fae088c..982656e2707 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -758,6 +758,19 @@ static int move_to_new_page(struct page *newpage, struct page *page,
return rc;
}
+static void write_dirty_buffers(struct page *page)
+{
+ struct buffer_head *head = page_buffers(page);
+ struct buffer_head *bh;
+
+ bh = head;
+ do {
+ write_dirty_buffer(bh, WRITE_SYNC);
+ wait_on_buffer(bh);
+ bh = bh->b_this_page;
+ } while (bh != head);
+}
+
static int __unmap_and_move(struct page *page, struct page *newpage,
int force, bool offlining, enum migrate_mode mode)
{
@@ -905,6 +918,14 @@ static int __unmap_and_move(struct page *page, struct page *newpage,
if (!page->mapping) {
VM_BUG_ON(PageAnon(page));
if (page_has_private(page)) {
+ /* try_to_free_buffers() call below won't try to write
+ * buffers if they're dirty, so it will fail. */
+ if (PageDirty(page)) {
+#ifdef CONFIG_CMA_DEBUG_VERBOSE
+ pr_info("__unmap_and_move: flushing dirty page buffers ...\n");
+#endif
+ write_dirty_buffers(page);
+ }
if (!try_to_free_buffers(page)) {
#ifdef CONFIG_CMA_DEBUG_VERBOSE
pr_err("__unmap_and_move: in !page_mapping/page_has_private case, mode = %d, force = %d\n", mode, force);