From 735a257344c83ebe06e2b4df1d4b3e5769704e19 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 2 Oct 2002 22:57:40 -0700 Subject: [PATCH] truncate/invalidate_inode_pages rewrite Rewrite these functions to use gang lookup. - This probably has similar performance to the old code in the common case. - It will be vastly quicker than current code for the worst case (single-page truncate). - invalidate_inode_pages() has been changed. It used to use page_count(page) as the "is it mapped into pagetables" heuristic. It now uses the (page->pte.direct != 0) heuristic. - Removes the worst cause of scheduling latency in the kernel. - It's a big code cleanup. - invalidate_inode_pages() has been changed to take an address_space *, not an inode *. - the maximum hold times for mapping->page_lock are enormously reduced, making it quite feasible to turn this into an irq-safe lock. Which, it seems, is a requirement for sane AIO<->direct-io integration, as well as possibly other AIO things. (Thanks Hugh for fixing a bug in this one as well). (Christoph added some stuff too) --- include/linux/fs.h | 2 +- include/linux/pagemap.h | 3 +++ include/linux/pagevec.h | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index 56f2bab87d7f..f0ba1e96325c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1140,7 +1140,7 @@ extern int full_check_disk_change(struct block_device *); extern int __check_disk_change(dev_t); extern int invalidate_inodes(struct super_block *); extern int invalidate_device(kdev_t, int); -extern void invalidate_inode_pages(struct inode *); +extern void invalidate_inode_pages(struct address_space *mapping); extern void invalidate_inode_pages2(struct address_space *mapping); extern void write_inode_now(struct inode *, int); extern int filemap_fdatawrite(struct address_space *); diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index bfc986131fe6..1fe640eaf601 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -41,6 +41,9 @@ extern struct page * find_trylock_page(struct address_space *mapping, unsigned long index); extern struct page * find_or_create_page(struct address_space *mapping, unsigned long index, unsigned int gfp_mask); +extern unsigned int find_get_pages(struct address_space *mapping, + pgoff_t start, unsigned int nr_pages, + struct page **pages); /* * Returns locked page at given index in given cache, creating it if needed. diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h index 278689b2fb2a..0207270b0fe7 100644 --- a/include/linux/pagevec.h +++ b/include/linux/pagevec.h @@ -8,6 +8,7 @@ #define PAGEVEC_SIZE 16 struct page; +struct address_space; struct pagevec { unsigned nr; @@ -21,6 +22,8 @@ void __pagevec_lru_add(struct pagevec *pvec); void lru_add_drain(void); void pagevec_deactivate_inactive(struct pagevec *pvec); void pagevec_strip(struct pagevec *pvec); +unsigned int pagevec_lookup(struct pagevec *pvec, struct address_space *mapping, + pgoff_t start, unsigned int nr_pages); static inline void pagevec_init(struct pagevec *pvec) { -- cgit v1.2.3