Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
[firefly-linux-kernel-4.4.55.git] / fs / xfs / xfs_aops.c
index b984647c24db02e98b4e030fd03c7bac75740923..f5b2453a43b2b554cfe9c32f82bbf91d22d22882 100644 (file)
@@ -434,10 +434,22 @@ xfs_start_page_writeback(
 {
        ASSERT(PageLocked(page));
        ASSERT(!PageWriteback(page));
-       if (clear_dirty)
+
+       /*
+        * if the page was not fully cleaned, we need to ensure that the higher
+        * layers come back to it correctly. That means we need to keep the page
+        * dirty, and for WB_SYNC_ALL writeback we need to ensure the
+        * PAGECACHE_TAG_TOWRITE index mark is not removed so another attempt to
+        * write this page in this writeback sweep will be made.
+        */
+       if (clear_dirty) {
                clear_page_dirty_for_io(page);
-       set_page_writeback(page);
+               set_page_writeback(page);
+       } else
+               set_page_writeback_keepwrite(page);
+
        unlock_page(page);
+
        /* If no buffers on the page are to be written, finish it here */
        if (!buffers)
                end_page_writeback(page);
@@ -548,6 +560,13 @@ xfs_cancel_ioend(
                do {
                        next_bh = bh->b_private;
                        clear_buffer_async_write(bh);
+                       /*
+                        * The unwritten flag is cleared when added to the
+                        * ioend. We're not submitting for I/O so mark the
+                        * buffer unwritten again for next time around.
+                        */
+                       if (ioend->io_type == XFS_IO_UNWRITTEN)
+                               set_buffer_unwritten(bh);
                        unlock_buffer(bh);
                } while ((bh = next_bh) != NULL);