f2fs: fix stale ATOMIC_WRITTEN_PAGE private pointer
[linux-2.6-block.git] / fs / f2fs / segment.c
index 4d7bf84dc3935e62f0293c9f6245e2038d84dad7..cb6d9ed634a35c3f58649e33dd662b08cc930d1e 100644 (file)
@@ -250,6 +250,36 @@ void drop_inmem_pages(struct inode *inode)
        stat_dec_atomic_write(inode);
 }
 
+void drop_inmem_page(struct inode *inode, struct page *page)
+{
+       struct f2fs_inode_info *fi = F2FS_I(inode);
+       struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+       struct list_head *head = &fi->inmem_pages;
+       struct inmem_pages *cur = NULL;
+
+       f2fs_bug_on(sbi, !IS_ATOMIC_WRITTEN_PAGE(page));
+
+       mutex_lock(&fi->inmem_lock);
+       list_for_each_entry(cur, head, list) {
+               if (cur->page == page)
+                       break;
+       }
+
+       f2fs_bug_on(sbi, !cur || cur->page != page);
+       list_del(&cur->list);
+       mutex_unlock(&fi->inmem_lock);
+
+       dec_page_count(sbi, F2FS_INMEM_PAGES);
+       kmem_cache_free(inmem_entry_slab, cur);
+
+       ClearPageUptodate(page);
+       set_page_private(page, 0);
+       ClearPagePrivate(page);
+       f2fs_put_page(page, 0);
+
+       trace_f2fs_commit_inmem_page(page, INMEM_INVALIDATE);
+}
+
 static int __commit_inmem_pages(struct inode *inode,
                                        struct list_head *revoke_list)
 {