| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- /*
- * linux/mm/filemap_xip.c
- *
- * Copyright (C) 2005 IBM Corporation
- * Author: Carsten Otte <cotte@de.ibm.com>
- *
- * derived from linux/mm/filemap.c - Copyright (C) Linus Torvalds
- *
- */
- #include <linux/fs.h>
- #include <linux/backing-dev.h>
- #include <linux/pagemap.h>
- #include <linux/export.h>
- #include <linux/uio.h>
- #include <linux/rmap.h>
- #include <linux/mmu_notifier.h>
- #include <linux/sched.h>
- #include <linux/seqlock.h>
- #include <linux/mutex.h>
- #include <linux/gfp.h>
- #include <asm/tlbflush.h>
- #include <asm/io.h>
- /*
- * truncate a page used for execute in place
- * functionality is analog to block_truncate_page but does use get_xip_mem
- * to get the page instead of page cache
- */
- int
- xip_truncate_page(struct address_space *mapping, loff_t from)
- {
- pgoff_t index = from >> PAGE_CACHE_SHIFT;
- unsigned offset = from & (PAGE_CACHE_SIZE-1);
- unsigned blocksize;
- unsigned length;
- void *xip_mem;
- unsigned long xip_pfn;
- int err;
- BUG_ON(!mapping->a_ops->get_xip_mem);
- blocksize = 1 << mapping->host->i_blkbits;
- length = offset & (blocksize - 1);
- /* Block boundary? Nothing to do */
- if (!length)
- return 0;
- length = blocksize - length;
- err = mapping->a_ops->get_xip_mem(mapping, index, 0,
- &xip_mem, &xip_pfn);
- if (unlikely(err)) {
- if (err == -ENODATA)
- /* Hole? No need to truncate */
- return 0;
- else
- return err;
- }
- memset(xip_mem + offset, 0, length);
- return 0;
- }
- EXPORT_SYMBOL_GPL(xip_truncate_page);
|