RISC-V: Introduce sv48 support without relocatable kernel
[linux-2.6-microblaze.git] / fs / fs-writeback.c
index 67f0e88..f8d7fe6 100644 (file)
@@ -372,7 +372,7 @@ static bool inode_do_switch_wbs(struct inode *inode,
 {
        struct address_space *mapping = inode->i_mapping;
        XA_STATE(xas, &mapping->i_pages, 0);
-       struct page *page;
+       struct folio *folio;
        bool switched = false;
 
        spin_lock(&inode->i_lock);
@@ -389,21 +389,23 @@ static bool inode_do_switch_wbs(struct inode *inode,
 
        /*
         * Count and transfer stats.  Note that PAGECACHE_TAG_DIRTY points
-        * to possibly dirty pages while PAGECACHE_TAG_WRITEBACK points to
-        * pages actually under writeback.
+        * to possibly dirty folios while PAGECACHE_TAG_WRITEBACK points to
+        * folios actually under writeback.
         */
-       xas_for_each_marked(&xas, page, ULONG_MAX, PAGECACHE_TAG_DIRTY) {
-               if (PageDirty(page)) {
-                       dec_wb_stat(old_wb, WB_RECLAIMABLE);
-                       inc_wb_stat(new_wb, WB_RECLAIMABLE);
+       xas_for_each_marked(&xas, folio, ULONG_MAX, PAGECACHE_TAG_DIRTY) {
+               if (folio_test_dirty(folio)) {
+                       long nr = folio_nr_pages(folio);
+                       wb_stat_mod(old_wb, WB_RECLAIMABLE, -nr);
+                       wb_stat_mod(new_wb, WB_RECLAIMABLE, nr);
                }
        }
 
        xas_set(&xas, 0);
-       xas_for_each_marked(&xas, page, ULONG_MAX, PAGECACHE_TAG_WRITEBACK) {
-               WARN_ON_ONCE(!PageWriteback(page));
-               dec_wb_stat(old_wb, WB_WRITEBACK);
-               inc_wb_stat(new_wb, WB_WRITEBACK);
+       xas_for_each_marked(&xas, folio, ULONG_MAX, PAGECACHE_TAG_WRITEBACK) {
+               long nr = folio_nr_pages(folio);
+               WARN_ON_ONCE(!folio_test_writeback(folio));
+               wb_stat_mod(old_wb, WB_WRITEBACK, -nr);
+               wb_stat_mod(new_wb, WB_WRITEBACK, nr);
        }
 
        if (mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK)) {
@@ -1666,6 +1668,13 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 
        if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
                inode->i_state |= I_DIRTY_PAGES;
+       else if (unlikely(inode->i_state & I_PINNING_FSCACHE_WB)) {
+               if (!(inode->i_state & I_DIRTY_PAGES)) {
+                       inode->i_state &= ~I_PINNING_FSCACHE_WB;
+                       wbc->unpinned_fscache_wb = true;
+                       dirty |= I_PINNING_FSCACHE_WB; /* Cause write_inode */
+               }
+       }
 
        spin_unlock(&inode->i_lock);
 
@@ -1675,6 +1684,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
                if (ret == 0)
                        ret = err;
        }
+       wbc->unpinned_fscache_wb = false;
        trace_writeback_single_inode(inode, wbc, nr_to_write);
        return ret;
 }