patch-2.3.9 linux/mm/filemap.c
Next file: linux/mm/memory.c
Previous file: linux/lib/string.c
Back to the patch index
Back to the overall index
- Lines: 132
- Date:
Wed Jun 30 10:25:46 1999
- Orig file:
v2.3.8/linux/mm/filemap.c
- Orig date:
Tue Jun 22 14:25:22 1999
diff -u --recursive --new-file v2.3.8/linux/mm/filemap.c linux/mm/filemap.c
@@ -20,6 +20,7 @@
#include <linux/file.h>
#include <linux/swapctl.h>
#include <linux/slab.h>
+#include <linux/init.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
@@ -35,7 +36,8 @@
*/
atomic_t page_cache_size = ATOMIC_INIT(0);
-struct page * page_hash_table[PAGE_HASH_SIZE];
+unsigned int page_hash_bits;
+struct page **page_hash_table;
spinlock_t pagecache_lock = SPIN_LOCK_UNLOCKED;
@@ -273,8 +275,8 @@
continue;
}
if (!page_count(page)) {
-// BUG();
spin_unlock(&pagecache_lock);
+ BUG();
continue;
}
get_page(page);
@@ -292,13 +294,18 @@
/* Is it a buffer page? */
if (page->buffers) {
+ int mem = page->inode ? 0 : PAGE_CACHE_SIZE;
spin_unlock(&pagecache_lock);
- if (try_to_free_buffers(page))
- goto made_progress;
+ if (!try_to_free_buffers(page))
+ goto unlock_continue;
+ atomic_sub(mem, &buffermem);
spin_lock(&pagecache_lock);
}
- /* We can't free pages unless there's just one user */
+ /*
+ * We can't free pages unless there's just one user
+ * (count == 2 because we added one ourselves above).
+ */
if (page_count(page) != 2)
goto spin_unlock_continue;
@@ -354,6 +361,7 @@
if (page->offset == offset)
break;
}
+ set_bit(PG_referenced, &page->flags);
not_found:
return page;
}
@@ -1138,7 +1146,6 @@
{
ssize_t retval;
- unlock_kernel();
retval = -EFAULT;
if (access_ok(VERIFY_WRITE, buf, count)) {
retval = 0;
@@ -1156,7 +1163,6 @@
retval = desc.error;
}
}
- lock_kernel();
return retval;
}
@@ -1481,7 +1487,7 @@
* If a task terminates while we're swapping the page, the vma and
* and file could be released ... increment the count to be safe.
*/
- file->f_count++;
+ atomic_inc(&file->f_count);
result = do_write_page(inode, file, (const char *) page, offset);
fput(file);
return result;
@@ -1829,8 +1835,6 @@
count = limit - pos;
}
- unlock_kernel();
-
while (count) {
unsigned long bytes, pgpos, offset;
/*
@@ -1892,7 +1896,6 @@
page_cache_free(page_cache);
err = written ? written : status;
- lock_kernel();
out:
return err;
}
@@ -1913,4 +1916,31 @@
panic("put_cached_page: page count=%d\n",
page_count(page));
page_cache_release(page);
+}
+
+void __init page_cache_init(unsigned long memory_size)
+{
+ unsigned long htable_size, order;
+
+ htable_size = memory_size >> PAGE_SHIFT;
+ htable_size *= sizeof(struct page *);
+ for(order = 0; (PAGE_SIZE << order) < htable_size; order++)
+ ;
+
+ do {
+ unsigned long tmp = (PAGE_SIZE << order) / sizeof(struct page *);
+
+ page_hash_bits = 0;
+ while((tmp >>= 1UL) != 0UL)
+ page_hash_bits++;
+
+ page_hash_table = (struct page **)
+ __get_free_pages(GFP_ATOMIC, order);
+ } while(page_hash_table == NULL && --order > 0);
+
+ printk("Page-cache hash table entries: %d (order: %ld, %ld bytes)\n",
+ (1 << page_hash_bits), order, (PAGE_SIZE << order));
+ if (!page_hash_table)
+ panic("Failed to allocate page hash table\n");
+ memset(page_hash_table, 0, PAGE_HASH_SIZE * sizeof(struct page *));
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)