Merge tag 'xfs-for-linus-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[platform/kernel/linux-starfive.git] / fs / xfs / xfs_aops.c
index dc52698..3859f5e 100644 (file)
@@ -356,7 +356,6 @@ xfs_end_bio(
 {
        xfs_ioend_t             *ioend = bio->bi_private;
 
-       ASSERT(atomic_read(&bio->bi_cnt) >= 1);
        ioend->io_error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : error;
 
        /* Toss bio and pass work off to an xfsdatad thread */
@@ -1942,6 +1941,7 @@ xfs_vm_set_page_dirty(
        loff_t                  end_offset;
        loff_t                  offset;
        int                     newly_dirty;
+       struct mem_cgroup       *memcg;
 
        if (unlikely(!mapping))
                return !TestSetPageDirty(page);
@@ -1961,6 +1961,11 @@ xfs_vm_set_page_dirty(
                        offset += 1 << inode->i_blkbits;
                } while (bh != head);
        }
+       /*
+        * Use mem_group_begin_page_stat() to keep PageDirty synchronized with
+        * per-memcg dirty page counters.
+        */
+       memcg = mem_cgroup_begin_page_stat(page);
        newly_dirty = !TestSetPageDirty(page);
        spin_unlock(&mapping->private_lock);
 
@@ -1971,13 +1976,15 @@ xfs_vm_set_page_dirty(
                spin_lock_irqsave(&mapping->tree_lock, flags);
                if (page->mapping) {    /* Race with truncate? */
                        WARN_ON_ONCE(!PageUptodate(page));
-                       account_page_dirtied(page, mapping);
+                       account_page_dirtied(page, mapping, memcg);
                        radix_tree_tag_set(&mapping->page_tree,
                                        page_index(page), PAGECACHE_TAG_DIRTY);
                }
                spin_unlock_irqrestore(&mapping->tree_lock, flags);
-               __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
        }
+       mem_cgroup_end_page_stat(memcg);
+       if (newly_dirty)
+               __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
        return newly_dirty;
 }