Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.3.9 /mm/filemap.c

Filename:/mm/filemap.c
Lines Added:41
Lines Deleted:11
Also changed in: (Previous) 2.3.8  2.3.7  2.3.5  2.3.4  2.3.1  2.2.9-ac6 
(Following) 2.3.10  2.3.11  2.3.13  2.3.14  2.3.15  2.3.16 

Location
[  2.3.9
  [  mm
     o  filemap.c

Patch

diff -u --recursive --new-file v2.3.8/linux/mm/filemap.c linux/mm/filemap.c
--- v2.3.8/linux/mm/filemap.c   Tue Jun 22 14:25:22 1999
+++ linux/mm/filemap.c   Wed Jun 30 10:25:46 1999
@@ -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 *));
 }


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.