diff options
author | Nick Piggin <npiggin@suse.de> | 2007-07-19 04:47:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-19 13:04:41 -0400 |
commit | d0217ac04ca6591841e5665f518e38064f4e65bd (patch) | |
tree | d3309094bb734d34773f97d642593e298a5cfcfc /mm/filemap_xip.c | |
parent | ed2f2f9b3ff8debdf512f7687b232c3c1d7d60d7 (diff) |
mm: fault feedback #1
Change ->fault prototype. We now return an int, which contains
VM_FAULT_xxx code in the low byte, and FAULT_RET_xxx code in the next byte.
FAULT_RET_ code tells the VM whether a page was found, whether it has been
locked, and potentially other things. This is not quite the way he wanted
it yet, but that's changed in the next patch (which requires changes to
arch code).
This means we no longer set VM_CAN_INVALIDATE in the vma in order to say
that a page is locked which requires filemap_nopage to go away (because we
can no longer remain backward compatible without that flag), but we were
going to do that anyway.
struct fault_data is renamed to struct vm_fault as Linus asked. address
is now a void __user * that we should firmly encourage drivers not to use
without really good reason.
The page is now returned via a page pointer in the vm_fault struct.
Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/filemap_xip.c')
-rw-r--r-- | mm/filemap_xip.c | 37 |
1 files changed, 14 insertions, 23 deletions
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c index 82f4b8e9834e..847d5d78163e 100644 --- a/mm/filemap_xip.c +++ b/mm/filemap_xip.c | |||
@@ -210,8 +210,7 @@ __xip_unmap (struct address_space * mapping, | |||
210 | * | 210 | * |
211 | * This function is derived from filemap_fault, but used for execute in place | 211 | * This function is derived from filemap_fault, but used for execute in place |
212 | */ | 212 | */ |
213 | static struct page *xip_file_fault(struct vm_area_struct *area, | 213 | static int xip_file_fault(struct vm_area_struct *area, struct vm_fault *vmf) |
214 | struct fault_data *fdata) | ||
215 | { | 214 | { |
216 | struct file *file = area->vm_file; | 215 | struct file *file = area->vm_file; |
217 | struct address_space *mapping = file->f_mapping; | 216 | struct address_space *mapping = file->f_mapping; |
@@ -222,19 +221,15 @@ static struct page *xip_file_fault(struct vm_area_struct *area, | |||
222 | /* XXX: are VM_FAULT_ codes OK? */ | 221 | /* XXX: are VM_FAULT_ codes OK? */ |
223 | 222 | ||
224 | size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 223 | size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
225 | if (fdata->pgoff >= size) { | 224 | if (vmf->pgoff >= size) |
226 | fdata->type = VM_FAULT_SIGBUS; | 225 | return VM_FAULT_SIGBUS; |
227 | return NULL; | ||
228 | } | ||
229 | 226 | ||
230 | page = mapping->a_ops->get_xip_page(mapping, | 227 | page = mapping->a_ops->get_xip_page(mapping, |
231 | fdata->pgoff*(PAGE_SIZE/512), 0); | 228 | vmf->pgoff*(PAGE_SIZE/512), 0); |
232 | if (!IS_ERR(page)) | 229 | if (!IS_ERR(page)) |
233 | goto out; | 230 | goto out; |
234 | if (PTR_ERR(page) != -ENODATA) { | 231 | if (PTR_ERR(page) != -ENODATA) |
235 | fdata->type = VM_FAULT_OOM; | 232 | return VM_FAULT_OOM; |
236 | return NULL; | ||
237 | } | ||
238 | 233 | ||
239 | /* sparse block */ | 234 | /* sparse block */ |
240 | if ((area->vm_flags & (VM_WRITE | VM_MAYWRITE)) && | 235 | if ((area->vm_flags & (VM_WRITE | VM_MAYWRITE)) && |
@@ -242,26 +237,22 @@ static struct page *xip_file_fault(struct vm_area_struct *area, | |||
242 | (!(mapping->host->i_sb->s_flags & MS_RDONLY))) { | 237 | (!(mapping->host->i_sb->s_flags & MS_RDONLY))) { |
243 | /* maybe shared writable, allocate new block */ | 238 | /* maybe shared writable, allocate new block */ |
244 | page = mapping->a_ops->get_xip_page(mapping, | 239 | page = mapping->a_ops->get_xip_page(mapping, |
245 | fdata->pgoff*(PAGE_SIZE/512), 1); | 240 | vmf->pgoff*(PAGE_SIZE/512), 1); |
246 | if (IS_ERR(page)) { | 241 | if (IS_ERR(page)) |
247 | fdata->type = VM_FAULT_SIGBUS; | 242 | return VM_FAULT_SIGBUS; |
248 | return NULL; | ||
249 | } | ||
250 | /* unmap page at pgoff from all other vmas */ | 243 | /* unmap page at pgoff from all other vmas */ |
251 | __xip_unmap(mapping, fdata->pgoff); | 244 | __xip_unmap(mapping, vmf->pgoff); |
252 | } else { | 245 | } else { |
253 | /* not shared and writable, use xip_sparse_page() */ | 246 | /* not shared and writable, use xip_sparse_page() */ |
254 | page = xip_sparse_page(); | 247 | page = xip_sparse_page(); |
255 | if (!page) { | 248 | if (!page) |
256 | fdata->type = VM_FAULT_OOM; | 249 | return VM_FAULT_OOM; |
257 | return NULL; | ||
258 | } | ||
259 | } | 250 | } |
260 | 251 | ||
261 | out: | 252 | out: |
262 | fdata->type = VM_FAULT_MINOR; | ||
263 | page_cache_get(page); | 253 | page_cache_get(page); |
264 | return page; | 254 | vmf->page = page; |
255 | return VM_FAULT_MINOR; | ||
265 | } | 256 | } |
266 | 257 | ||
267 | static struct vm_operations_struct xip_file_vm_ops = { | 258 | static struct vm_operations_struct xip_file_vm_ops = { |