aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinchan Kim <[email protected]>2011-03-22 16:30:53 -0700
committerLinus Torvalds <[email protected]>2011-03-22 17:44:02 -0700
commit97cecb5a254fec22d28ef32235d888bfbfd7c783 (patch)
tree186c6bb9c1f999f807e2ec68dc6a0cf16c9d0d73
parentef6a3c63112e865d632ff7c478ba7c7160cad0d1 (diff)
mm: introduce delete_from_page_cache()
Presently we increase the page refcount in add_to_page_cache() but don't decrease it in remove_from_page_cache(). Such asymmetry adds confusion, requiring that callers notice it and a comment explaining why they release a page reference. It's not a good API. A long time ago, Hugh tried it (http://lkml.org/lkml/2004/10/24/140) but gave up because reiser4's drop_page() had to unlock the page between removing it from page cache and doing the page_cache_release(). But now the situation is changed. I think at least things in current mainline don't have any obstacles. The problem is for out-of-mainline filesystems - if they have done such things as reiser4, this patch could be a problem but they will discover this at compile time since we remove remove_from_page_cache(). This patch: This function works as just wrapper remove_from_page_cache(). The difference is that it decreases page references in itself. So caller have to make sure it has a page reference before calling. This patch is ready for removing remove_from_page_cache(). Signed-off-by: Minchan Kim <[email protected]> Cc: Christoph Hellwig <[email protected]> Acked-by: Hugh Dickins <[email protected]> Acked-by: Mel Gorman <[email protected]> Reviewed-by: KAMEZAWA Hiroyuki <[email protected]> Reviewed-by: Johannes Weiner <[email protected]> Reviewed-by: KOSAKI Motohiro <[email protected]> Cc: Edward Shishkin <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
-rw-r--r--include/linux/pagemap.h1
-rw-r--r--mm/filemap.c16
2 files changed, 17 insertions, 0 deletions
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 26946ad483bf..0aa258f4678d 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -455,6 +455,7 @@ int add_to_page_cache_locked(struct page *page, struct address_space *mapping,
pgoff_t index, gfp_t gfp_mask);
int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
pgoff_t index, gfp_t gfp_mask);
+extern void delete_from_page_cache(struct page *page);
extern void remove_from_page_cache(struct page *page);
extern void __remove_from_page_cache(struct page *page);
int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask);
diff --git a/mm/filemap.c b/mm/filemap.c
index c1459f2cdb5e..e7b59785ceb9 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -155,6 +155,22 @@ void remove_from_page_cache(struct page *page)
}
EXPORT_SYMBOL(remove_from_page_cache);
+/**
+ * delete_from_page_cache - delete page from page cache
+ * @page: the page which the kernel is trying to remove from page cache
+ *
+ * This must be called only on pages that have
+ * been verified to be in the page cache and locked.
+ * It will never put the page into the free list,
+ * the caller has a reference on the page.
+ */
+void delete_from_page_cache(struct page *page)
+{
+ remove_from_page_cache(page);
+ page_cache_release(page);
+}
+EXPORT_SYMBOL(delete_from_page_cache);
+
static int sync_page(void *word)
{
struct address_space *mapping;