patch-2.0.31 linux/mm/filemap.c
Next file: linux/mm/kmalloc.c
Previous file: linux/kernel/time.c
Back to the patch index
Back to the overall index
- Lines: 153
- Date:
Sat Aug 23 10:54:08 1997
- Orig file:
v2.0.30/linux/mm/filemap.c
- Orig date:
Wed Sep 11 07:57:19 1996
diff -u --recursive --new-file v2.0.30/linux/mm/filemap.c linux/mm/filemap.c
@@ -41,18 +41,7 @@
* Simple routines for both non-shared and shared mappings.
*/
-/*
- * This is a special fast page-free routine that _only_ works
- * on page-cache pages that we are currently using. We can
- * just decrement the page count, because we know that the page
- * has a count > 1 (the page cache itself counts as one, and
- * we're currently using it counts as one). So we don't need
- * the full free_page() stuff..
- */
-static inline void release_page(struct page * page)
-{
- atomic_dec(&page->count);
-}
+#define release_page(page) __free_page((page))
/*
* Invalidate the pages of an inode, removing all pages that aren't
@@ -100,7 +89,7 @@
/* page wholly truncated - free it */
if (offset >= start) {
if (PageLocked(page)) {
- wait_on_page(page);
+ __wait_on_page(page);
goto repeat;
}
inode->i_nrpages--;
@@ -125,7 +114,7 @@
}
}
-int shrink_mmap(int priority, int dma)
+int shrink_mmap(int priority, int dma, int can_do_io)
{
static int clock = 0;
struct page * page;
@@ -169,8 +158,12 @@
switch (page->count) {
case 1:
/* If it has been referenced recently, don't free it */
- if (clear_bit(PG_referenced, &page->flags))
+ if (clear_bit(PG_referenced, &page->flags)) {
+ /* age this page potential used */
+ if (priority < 4)
+ age_page(page);
break;
+ }
/* is it a page cache page? */
if (page->inode) {
@@ -181,7 +174,7 @@
}
/* is it a buffer cache page? */
- if (bh && try_to_free_buffer(bh, &bh, 6))
+ if (can_do_io && bh && try_to_free_buffer(bh, &bh, 6))
return 1;
break;
@@ -448,7 +441,7 @@
#define PageAlignSize(size) (((size) + PAGE_SIZE -1) & PAGE_MASK)
-#if 0 /* small readahead */
+#ifdef CONFIG_READA_SMALL /* small readahead */
#define MAX_READAHEAD PageAlignSize(4096*7)
#define MIN_READAHEAD PageAlignSize(4096*2)
#else /* large readahead */
@@ -743,10 +736,7 @@
filp->f_reada = 1;
if (page_cache)
free_page(page_cache);
- if (!IS_RDONLY(inode)) {
- inode->i_atime = CURRENT_TIME;
- inode->i_dirt = 1;
- }
+ UPDATE_ATIME(inode)
if (!read)
read = error;
return read;
@@ -784,8 +774,15 @@
found_page:
/*
* Ok, found a page in the page cache, now we need to check
- * that it's up-to-date
+ * that it's up-to-date. First check whether we'll need an
+ * extra page -- better to overlap the allocation with the I/O.
*/
+ if (no_share && !new_page) {
+ new_page = __get_free_page(GFP_KERNEL);
+ if (!new_page)
+ goto failure;
+ }
+
if (PageLocked(page))
goto page_locked_wait;
if (!PageUptodate(page))
@@ -810,13 +807,8 @@
}
/*
- * Check that we have another page to copy it over to..
+ * No sharing ... copy to the new page.
*/
- if (!new_page) {
- new_page = __get_free_page(GFP_KERNEL);
- if (!new_page)
- goto failure;
- }
memcpy((void *) new_page, (void *) old_page, PAGE_SIZE);
flush_page_to_ram(new_page);
release_page(page);
@@ -880,6 +872,8 @@
*/
failure:
release_page(page);
+ if (new_page)
+ free_page(new_page);
no_page:
return 0;
}
@@ -1003,6 +997,8 @@
unsigned long page;
int error;
+ if (pte_none(pte))
+ return 0;
if (!(flags & MS_INVALIDATE)) {
if (!pte_present(pte))
return 0;
@@ -1015,8 +1011,6 @@
page = pte_page(pte);
mem_map[MAP_NR(page)].count++;
} else {
- if (pte_none(pte))
- return 0;
flush_cache_page(vma, address);
pte_clear(ptep);
flush_tlb_page(vma, address);
@@ -1178,10 +1172,7 @@
return -EACCES;
if (!inode->i_op || !inode->i_op->readpage)
return -ENOEXEC;
- if (!IS_RDONLY(inode)) {
- inode->i_atime = CURRENT_TIME;
- inode->i_dirt = 1;
- }
+ UPDATE_ATIME(inode)
vma->vm_inode = inode;
inode->i_count++;
vma->vm_ops = ops;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov