Merge tag 'gfs2-4.8.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2...
[cascardo/linux.git] / fs / gfs2 / aops.c
index 82df368..5a6f52e 100644 (file)
@@ -187,7 +187,7 @@ static int __gfs2_jdata_writepage(struct page *page, struct writeback_control *w
                ClearPageChecked(page);
                if (!page_has_buffers(page)) {
                        create_empty_buffers(page, inode->i_sb->s_blocksize,
-                                            (1 << BH_Dirty)|(1 << BH_Uptodate));
+                                            BIT(BH_Dirty)|BIT(BH_Uptodate));
                }
                gfs2_page_add_databufs(ip, page, 0, sdp->sd_vfs->s_blocksize-1);
        }
@@ -1147,6 +1147,16 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
        if (!page_has_buffers(page))
                return 0;
 
+       /*
+        * From xfs_vm_releasepage: mm accommodates an old ext3 case where
+        * clean pages might not have had the dirty bit cleared.  Thus, it can
+        * send actual dirty pages to ->releasepage() via shrink_active_list().
+        *
+        * As a workaround, we skip pages that contain dirty buffers below.
+        * Once ->releasepage isn't called on dirty pages anymore, we can warn
+        * on dirty buffers like we used to here again.
+        */
+
        gfs2_log_lock(sdp);
        spin_lock(&sdp->sd_ail_lock);
        head = bh = page_buffers(page);
@@ -1156,8 +1166,8 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
                bd = bh->b_private;
                if (bd && bd->bd_tr)
                        goto cannot_release;
-               if (buffer_pinned(bh) || buffer_dirty(bh))
-                       goto not_possible;
+               if (buffer_dirty(bh) || WARN_ON(buffer_pinned(bh)))
+                       goto cannot_release;
                bh = bh->b_this_page;
        } while(bh != head);
        spin_unlock(&sdp->sd_ail_lock);
@@ -1180,9 +1190,6 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
 
        return try_to_free_buffers(page);
 
-not_possible: /* Should never happen */
-       WARN_ON(buffer_dirty(bh));
-       WARN_ON(buffer_pinned(bh));
 cannot_release:
        spin_unlock(&sdp->sd_ail_lock);
        gfs2_log_unlock(sdp);