readahead: on-demand readahead logic
[linux-2.6.git] / include / linux / mm.h
index a5c4518..619c0e8 100644 (file)
@@ -168,6 +168,8 @@ extern unsigned int kobjsize(const void *objp);
 #define VM_INSERTPAGE  0x02000000      /* The vma has had "vm_insert_page()" done on it */
 #define VM_ALWAYSDUMP  0x04000000      /* Always include in core dumps */
 
+#define VM_CAN_NONLINEAR 0x08000000    /* Has ->fault & does nonlinear pages */
+
 #ifndef VM_STACK_DEFAULT_FLAGS         /* arch can override this */
 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
 #endif
@@ -190,6 +192,30 @@ extern unsigned int kobjsize(const void *objp);
  */
 extern pgprot_t protection_map[16];
 
+#define FAULT_FLAG_WRITE       0x01    /* Fault was a write access */
+#define FAULT_FLAG_NONLINEAR   0x02    /* Fault was via a nonlinear mapping */
+
+
+/*
+ * vm_fault is filled by the the pagefault handler and passed to the vma's
+ * ->fault function. The vma's ->fault is responsible for returning a bitmask
+ * of VM_FAULT_xxx flags that give details about how the fault was handled.
+ *
+ * pgoff should be used in favour of virtual_address, if possible. If pgoff
+ * is used, one may set VM_CAN_NONLINEAR in the vma->vm_flags to get nonlinear
+ * mapping support.
+ */
+struct vm_fault {
+       unsigned int flags;             /* FAULT_FLAG_xxx flags */
+       pgoff_t pgoff;                  /* Logical page offset based on vma */
+       void __user *virtual_address;   /* Faulting virtual address */
+
+       struct page *page;              /* ->fault handlers should return a
+                                        * page here, unless VM_FAULT_NOPAGE
+                                        * is set (which is also implied by
+                                        * VM_FAULT_ERROR).
+                                        */
+};
 
 /*
  * These are the virtual MM functions - opening of an area, closing and
@@ -199,9 +225,11 @@ extern pgprot_t protection_map[16];
 struct vm_operations_struct {
        void (*open)(struct vm_area_struct * area);
        void (*close)(struct vm_area_struct * area);
-       struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int *type);
-       unsigned long (*nopfn)(struct vm_area_struct * area, unsigned long address);
-       int (*populate)(struct vm_area_struct * area, unsigned long address, unsigned long len, pgprot_t prot, unsigned long pgoff, int nonblock);
+       int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf);
+       struct page *(*nopage)(struct vm_area_struct *area,
+                       unsigned long address, int *type);
+       unsigned long (*nopfn)(struct vm_area_struct *area,
+                       unsigned long address);
 
        /* notification that a previously read-only page is about to become
         * writable, if an error is returned it will cause a SIGBUS */
@@ -655,7 +683,6 @@ static inline int page_mapped(struct page *page)
  */
 #define NOPAGE_SIGBUS  (NULL)
 #define NOPAGE_OOM     ((struct page *) (-1))
-#define NOPAGE_REFAULT ((struct page *) (-2))  /* Return to userspace, rerun */
 
 /*
  * Error return values for the *_nopfn functions
@@ -669,16 +696,18 @@ static inline int page_mapped(struct page *page)
  * Used to decide whether a process gets delivered SIGBUS or
  * just gets major/minor fault counters bumped up.
  */
-#define VM_FAULT_OOM   0x00
-#define VM_FAULT_SIGBUS        0x01
-#define VM_FAULT_MINOR 0x02
-#define VM_FAULT_MAJOR 0x03
-
-/* 
- * Special case for get_user_pages.
- * Must be in a distinct bit from the above VM_FAULT_ flags.
- */
-#define VM_FAULT_WRITE 0x10
+
+#define VM_FAULT_MINOR 0 /* For backwards compat. Remove me quickly. */
+
+#define VM_FAULT_OOM   0x0001
+#define VM_FAULT_SIGBUS        0x0002
+#define VM_FAULT_MAJOR 0x0004
+#define VM_FAULT_WRITE 0x0008  /* Special case for get_user_pages */
+
+#define VM_FAULT_NOPAGE        0x0100  /* ->fault installed the pte, not return page */
+#define VM_FAULT_LOCKED        0x0200  /* ->fault locked the returned page */
+
+#define VM_FAULT_ERROR (VM_FAULT_OOM | VM_FAULT_SIGBUS)
 
 #define offset_in_page(p)      ((unsigned long)(p) & ~PAGE_MASK)
 
@@ -762,20 +791,10 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping,
 
 extern int vmtruncate(struct inode * inode, loff_t offset);
 extern int vmtruncate_range(struct inode * inode, loff_t offset, loff_t end);
-extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot);
-extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long pgoff, pgprot_t prot);
 
 #ifdef CONFIG_MMU
-extern int __handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma,
+extern int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
                        unsigned long address, int write_access);
-
-static inline int handle_mm_fault(struct mm_struct *mm,
-                       struct vm_area_struct *vma, unsigned long address,
-                       int write_access)
-{
-       return __handle_mm_fault(mm, vma, address, write_access) &
-                               (~VM_FAULT_WRITE);
-}
 #else
 static inline int handle_mm_fault(struct mm_struct *mm,
                        struct vm_area_struct *vma, unsigned long address,
@@ -1104,9 +1123,7 @@ extern void truncate_inode_pages_range(struct address_space *,
                                       loff_t lstart, loff_t lend);
 
 /* generic vm_area_ops exported for stackable file systems */
-extern struct page *filemap_nopage(struct vm_area_struct *, unsigned long, int *);
-extern int filemap_populate(struct vm_area_struct *, unsigned long,
-               unsigned long, pgprot_t, unsigned long, int);
+extern int filemap_fault(struct vm_area_struct *, struct vm_fault *);
 
 /* mm/page-writeback.c */
 int write_one_page(struct page *page, int wait);
@@ -1121,6 +1138,12 @@ int do_page_cache_readahead(struct address_space *mapping, struct file *filp,
                        pgoff_t offset, unsigned long nr_to_read);
 int force_page_cache_readahead(struct address_space *mapping, struct file *filp,
                        pgoff_t offset, unsigned long nr_to_read);
+unsigned long page_cache_readahead_ondemand(struct address_space *mapping,
+                         struct file_ra_state *ra,
+                         struct file *filp,
+                         struct page *page,
+                         pgoff_t offset,
+                         unsigned long size);
 unsigned long page_cache_readahead(struct address_space *mapping,
                          struct file_ra_state *ra,
                          struct file *filp,