| 1 | #ifndef _LINUX_PAGEMAP_H | 
|---|
| 2 | #define _LINUX_PAGEMAP_H | 
|---|
| 3 |  | 
|---|
| 4 | /* | 
|---|
| 5 | * Page-mapping primitive inline functions | 
|---|
| 6 | * | 
|---|
| 7 | * Copyright 1995 Linus Torvalds | 
|---|
| 8 | */ | 
|---|
| 9 |  | 
|---|
| 10 | #include <linux/mm.h> | 
|---|
| 11 | #include <linux/fs.h> | 
|---|
| 12 | #include <linux/list.h> | 
|---|
| 13 |  | 
|---|
| 14 | #include <asm/system.h> | 
|---|
| 15 | #include <asm/pgtable.h> | 
|---|
| 16 |  | 
|---|
| 17 | /* | 
|---|
| 18 | * The page cache can done in larger chunks than | 
|---|
| 19 | * one page, because it allows for more efficient | 
|---|
| 20 | * throughput (it can then be mapped into user | 
|---|
| 21 | * space in smaller chunks for same flexibility). | 
|---|
| 22 | * | 
|---|
| 23 | * Or rather, it _will_ be done in larger chunks. | 
|---|
| 24 | */ | 
|---|
| 25 | #define PAGE_CACHE_SHIFT        PAGE_SHIFT | 
|---|
| 26 | #define PAGE_CACHE_SIZE         PAGE_SIZE | 
|---|
| 27 | #define PAGE_CACHE_MASK         PAGE_MASK | 
|---|
| 28 | #define PAGE_CACHE_ALIGN(addr)  (((addr)+PAGE_CACHE_SIZE-1)&PAGE_CACHE_MASK) | 
|---|
| 29 |  | 
|---|
| 30 | #define page_cache_alloc()      alloc_pages(GFP_HIGHUSER, 0) | 
|---|
| 31 | #define page_cache_free(x)      __free_page(x) | 
|---|
| 32 | #define page_cache_release(x)   __free_page(x) | 
|---|
| 33 |  | 
|---|
| 34 | /* | 
|---|
| 35 | * From a kernel address, get the "struct page *" | 
|---|
| 36 | */ | 
|---|
| 37 | #define page_cache_entry(x)     (mem_map + MAP_NR(x)) | 
|---|
| 38 |  | 
|---|
| 39 | extern unsigned int page_hash_bits; | 
|---|
| 40 | #define PAGE_HASH_BITS (page_hash_bits) | 
|---|
| 41 | #define PAGE_HASH_SIZE (1 << PAGE_HASH_BITS) | 
|---|
| 42 |  | 
|---|
| 43 | extern atomic_t page_cache_size; /* # of pages currently in the hash table */ | 
|---|
| 44 | extern struct page **page_hash_table; | 
|---|
| 45 |  | 
|---|
| 46 | extern void page_cache_init(unsigned long); | 
|---|
| 47 |  | 
|---|
| 48 | /* | 
|---|
| 49 | * We use a power-of-two hash table to avoid a modulus, | 
|---|
| 50 | * and get a reasonable hash by knowing roughly how the | 
|---|
| 51 | * inode pointer and indexes are distributed (ie, we | 
|---|
| 52 | * roughly know which bits are "significant") | 
|---|
| 53 | * | 
|---|
| 54 | * For the time being it will work for struct address_space too (most of | 
|---|
| 55 | * them sitting inside the inodes). We might want to change it later. | 
|---|
| 56 | */ | 
|---|
| 57 | //extern inline unsigned long _page_hashfn(struct address_space * mapping, unsigned long index) | 
|---|
| 58 | //{ | 
|---|
| 59 | //#define i (((unsigned long) mapping)/(sizeof(struct inode) & ~ (sizeof(struct inode) - 1))) | 
|---|
| 60 | //#define s(x) ((x)+((x)>>PAGE_HASH_BITS)) | 
|---|
| 61 | //      return s(i+index) & (PAGE_HASH_SIZE-1); | 
|---|
| 62 | //#undef i | 
|---|
| 63 | //#undef o | 
|---|
| 64 | //#undef s | 
|---|
| 65 | //} | 
|---|
| 66 |  | 
|---|
| 67 | #define page_hash(mapping,index) (page_hash_table+_page_hashfn(mapping,index)) | 
|---|
| 68 |  | 
|---|
| 69 | extern struct page * __find_get_page (struct address_space *mapping, | 
|---|
| 70 | unsigned long index, struct page **hash); | 
|---|
| 71 | #define find_get_page(mapping, index) \ | 
|---|
| 72 | __find_get_page(mapping, index, page_hash(mapping, index)) | 
|---|
| 73 | extern struct page * __find_lock_page (struct address_space * mapping, | 
|---|
| 74 | unsigned long index, struct page **hash); | 
|---|
| 75 | extern void lock_page(struct page *page); | 
|---|
| 76 | #define find_lock_page(mapping, index) \ | 
|---|
| 77 | __find_lock_page(mapping, index, page_hash(mapping, index)) | 
|---|
| 78 |  | 
|---|
| 79 | extern void __add_page_to_hash_queue(struct page * page, struct page **p); | 
|---|
| 80 |  | 
|---|
| 81 | extern void add_to_page_cache(struct page * page, struct address_space *mapping, unsigned long index); | 
|---|
| 82 | extern int add_to_page_cache_unique(struct page * page, struct address_space *mapping, unsigned long index, struct page **hash); | 
|---|
| 83 |  | 
|---|
| 84 | #if 0 | 
|---|
| 85 | extern inline void add_page_to_hash_queue(struct page * page, struct inode * inode, unsigned long index) | 
|---|
| 86 | { | 
|---|
| 87 | __add_page_to_hash_queue(page, page_hash(&inode->i_data,index)); | 
|---|
| 88 | } | 
|---|
| 89 |  | 
|---|
| 90 | extern inline void add_page_to_inode_queue(struct address_space *mapping, struct page * page) | 
|---|
| 91 | { | 
|---|
| 92 | struct list_head *head = &mapping->pages; | 
|---|
| 93 |  | 
|---|
| 94 | if (!mapping->nrpages++) { | 
|---|
| 95 | if (!list_empty(head)) | 
|---|
| 96 | BUG(); | 
|---|
| 97 | } else { | 
|---|
| 98 | if (list_empty(head)) | 
|---|
| 99 | BUG(); | 
|---|
| 100 | } | 
|---|
| 101 | list_add(&page->list, head); | 
|---|
| 102 | page->mapping = mapping; | 
|---|
| 103 | } | 
|---|
| 104 |  | 
|---|
| 105 | extern inline void remove_page_from_inode_queue(struct page * page) | 
|---|
| 106 | { | 
|---|
| 107 | struct address_space * mapping = page->mapping; | 
|---|
| 108 |  | 
|---|
| 109 | mapping->nrpages--; | 
|---|
| 110 | list_del(&page->list); | 
|---|
| 111 | } | 
|---|
| 112 |  | 
|---|
| 113 | extern void ___wait_on_page(struct page *); | 
|---|
| 114 |  | 
|---|
| 115 | extern inline void wait_on_page(struct page * page) | 
|---|
| 116 | { | 
|---|
| 117 | if (PageLocked(page)) | 
|---|
| 118 | ___wait_on_page(page); | 
|---|
| 119 | } | 
|---|
| 120 | #endif | 
|---|
| 121 |  | 
|---|
| 122 | #endif | 
|---|