Merge tag 'soc-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[firefly-linux-kernel-4.4.55.git] / fs / nilfs2 / page.c
index 07f76db04ec7ef65b0103a6755e2f5746364d3e6..0ba679866e504ec126720f3eb7b78e210703f538 100644 (file)
@@ -370,7 +370,12 @@ repeat:
        goto repeat;
 }
 
-void nilfs_clear_dirty_pages(struct address_space *mapping)
+/**
+ * nilfs_clear_dirty_pages - discard dirty pages in address space
+ * @mapping: address space with dirty pages for discarding
+ * @silent: suppress [true] or print [false] warning messages
+ */
+void nilfs_clear_dirty_pages(struct address_space *mapping, bool silent)
 {
        struct pagevec pvec;
        unsigned int i;
@@ -382,25 +387,9 @@ void nilfs_clear_dirty_pages(struct address_space *mapping)
                                  PAGEVEC_SIZE)) {
                for (i = 0; i < pagevec_count(&pvec); i++) {
                        struct page *page = pvec.pages[i];
-                       struct buffer_head *bh, *head;
 
                        lock_page(page);
-                       ClearPageUptodate(page);
-                       ClearPageMappedToDisk(page);
-                       bh = head = page_buffers(page);
-                       do {
-                               lock_buffer(bh);
-                               clear_buffer_dirty(bh);
-                               clear_buffer_nilfs_volatile(bh);
-                               clear_buffer_nilfs_checked(bh);
-                               clear_buffer_nilfs_redirected(bh);
-                               clear_buffer_uptodate(bh);
-                               clear_buffer_mapped(bh);
-                               unlock_buffer(bh);
-                               bh = bh->b_this_page;
-                       } while (bh != head);
-
-                       __nilfs_clear_page_dirty(page);
+                       nilfs_clear_dirty_page(page, silent);
                        unlock_page(page);
                }
                pagevec_release(&pvec);
@@ -408,6 +397,51 @@ void nilfs_clear_dirty_pages(struct address_space *mapping)
        }
 }
 
+/**
+ * nilfs_clear_dirty_page - discard dirty page
+ * @page: dirty page that will be discarded
+ * @silent: suppress [true] or print [false] warning messages
+ */
+void nilfs_clear_dirty_page(struct page *page, bool silent)
+{
+       struct inode *inode = page->mapping->host;
+       struct super_block *sb = inode->i_sb;
+
+       BUG_ON(!PageLocked(page));
+
+       if (!silent) {
+               nilfs_warning(sb, __func__,
+                               "discard page: offset %lld, ino %lu",
+                               page_offset(page), inode->i_ino);
+       }
+
+       ClearPageUptodate(page);
+       ClearPageMappedToDisk(page);
+
+       if (page_has_buffers(page)) {
+               struct buffer_head *bh, *head;
+
+               bh = head = page_buffers(page);
+               do {
+                       lock_buffer(bh);
+                       if (!silent) {
+                               nilfs_warning(sb, __func__,
+                                       "discard block %llu, size %zu",
+                                       (u64)bh->b_blocknr, bh->b_size);
+                       }
+                       clear_buffer_dirty(bh);
+                       clear_buffer_nilfs_volatile(bh);
+                       clear_buffer_nilfs_checked(bh);
+                       clear_buffer_nilfs_redirected(bh);
+                       clear_buffer_uptodate(bh);
+                       clear_buffer_mapped(bh);
+                       unlock_buffer(bh);
+               } while (bh = bh->b_this_page, bh != head);
+       }
+
+       __nilfs_clear_page_dirty(page);
+}
+
 unsigned nilfs_page_count_clean_buffers(struct page *page,
                                        unsigned from, unsigned to)
 {