aboutsummaryrefslogtreecommitdiffstats
path: root/mm/filemap_xip.c
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2007-07-19 04:47:03 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-19 13:04:41 -0400
commitd0217ac04ca6591841e5665f518e38064f4e65bd (patch)
treed3309094bb734d34773f97d642593e298a5cfcfc /mm/filemap_xip.c
parented2f2f9b3ff8debdf512f7687b232c3c1d7d60d7 (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.c37
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 */
213static struct page *xip_file_fault(struct vm_area_struct *area, 213static 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
261out: 252out:
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
267static struct vm_operations_struct xip_file_vm_ops = { 258static struct vm_operations_struct xip_file_vm_ops = {