xip.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. * linux/fs/ext2/xip.c
  3. *
  4. * Copyright (C) 2005 IBM Corporation
  5. * Author: Carsten Otte (cotte@de.ibm.com)
  6. */
  7. #include <linux/mm.h>
  8. #include <linux/fs.h>
  9. #include <linux/genhd.h>
  10. #include <linux/buffer_head.h>
  11. #include <linux/ext2_fs_sb.h>
  12. #include <linux/ext2_fs.h>
  13. #include "ext2.h"
  14. #include "xip.h"
  15. static inline int
  16. __inode_direct_access(struct inode *inode, sector_t sector, unsigned long *data) {
  17. BUG_ON(!inode->i_sb->s_bdev->bd_disk->fops->direct_access);
  18. return inode->i_sb->s_bdev->bd_disk->fops
  19. ->direct_access(inode->i_sb->s_bdev,sector,data);
  20. }
  21. int
  22. ext2_clear_xip_target(struct inode *inode, int block) {
  23. sector_t sector = block*(PAGE_SIZE/512);
  24. unsigned long data;
  25. int rc;
  26. rc = __inode_direct_access(inode, sector, &data);
  27. if (rc)
  28. return rc;
  29. clear_page((void*)data);
  30. return 0;
  31. }
  32. void ext2_xip_verify_sb(struct super_block *sb)
  33. {
  34. struct ext2_sb_info *sbi = EXT2_SB(sb);
  35. if ((sbi->s_mount_opt & EXT2_MOUNT_XIP)) {
  36. if ((sb->s_bdev == NULL) ||
  37. sb->s_bdev->bd_disk == NULL ||
  38. sb->s_bdev->bd_disk->fops == NULL ||
  39. sb->s_bdev->bd_disk->fops->direct_access == NULL) {
  40. sbi->s_mount_opt &= (~EXT2_MOUNT_XIP);
  41. ext2_warning(sb, __FUNCTION__,
  42. "ignoring xip option - not supported by bdev");
  43. }
  44. }
  45. }
  46. struct page*
  47. ext2_get_xip_page(struct address_space *mapping, sector_t blockno,
  48. int create)
  49. {
  50. int rc;
  51. unsigned long data;
  52. struct buffer_head tmp;
  53. tmp.b_state = 0;
  54. tmp.b_blocknr = 0;
  55. rc = ext2_get_block(mapping->host, blockno/(PAGE_SIZE/512) , &tmp,
  56. create);
  57. if (rc)
  58. return ERR_PTR(rc);
  59. if (tmp.b_blocknr == 0) {
  60. /* SPARSE block */
  61. BUG_ON(create);
  62. return ERR_PTR(-ENODATA);
  63. }
  64. rc = __inode_direct_access
  65. (mapping->host,tmp.b_blocknr*(PAGE_SIZE/512) ,&data);
  66. if (rc)
  67. return ERR_PTR(rc);
  68. SetPageUptodate(virt_to_page(data));
  69. return virt_to_page(data);
  70. }