filemap_xip.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. /*
  2. * linux/mm/filemap_xip.c
  3. *
  4. * Copyright (C) 2005 IBM Corporation
  5. * Author: Carsten Otte <cotte@de.ibm.com>
  6. *
  7. * derived from linux/mm/filemap.c - Copyright (C) Linus Torvalds
  8. *
  9. */
  10. #include <linux/fs.h>
  11. #include <linux/backing-dev.h>
  12. #include <linux/pagemap.h>
  13. #include <linux/export.h>
  14. #include <linux/uio.h>
  15. #include <linux/rmap.h>
  16. #include <linux/mmu_notifier.h>
  17. #include <linux/sched.h>
  18. #include <linux/seqlock.h>
  19. #include <linux/mutex.h>
  20. #include <linux/gfp.h>
  21. #include <asm/tlbflush.h>
  22. #include <asm/io.h>
  23. /*
  24. * truncate a page used for execute in place
  25. * functionality is analog to block_truncate_page but does use get_xip_mem
  26. * to get the page instead of page cache
  27. */
  28. int
  29. xip_truncate_page(struct address_space *mapping, loff_t from)
  30. {
  31. pgoff_t index = from >> PAGE_CACHE_SHIFT;
  32. unsigned offset = from & (PAGE_CACHE_SIZE-1);
  33. unsigned blocksize;
  34. unsigned length;
  35. void *xip_mem;
  36. unsigned long xip_pfn;
  37. int err;
  38. BUG_ON(!mapping->a_ops->get_xip_mem);
  39. blocksize = 1 << mapping->host->i_blkbits;
  40. length = offset & (blocksize - 1);
  41. /* Block boundary? Nothing to do */
  42. if (!length)
  43. return 0;
  44. length = blocksize - length;
  45. err = mapping->a_ops->get_xip_mem(mapping, index, 0,
  46. &xip_mem, &xip_pfn);
  47. if (unlikely(err)) {
  48. if (err == -ENODATA)
  49. /* Hole? No need to truncate */
  50. return 0;
  51. else
  52. return err;
  53. }
  54. memset(xip_mem + offset, 0, length);
  55. return 0;
  56. }
  57. EXPORT_SYMBOL_GPL(xip_truncate_page);