aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext2/xip.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext2/xip.c')
-rw-r--r--fs/ext2/xip.c53
1 files changed, 25 insertions, 28 deletions
diff --git a/fs/ext2/xip.c b/fs/ext2/xip.c
index ca7f00312388..4fb94c20041b 100644
--- a/fs/ext2/xip.c
+++ b/fs/ext2/xip.c
@@ -15,24 +15,28 @@
15#include "xip.h" 15#include "xip.h"
16 16
17static inline int 17static inline int
18__inode_direct_access(struct inode *inode, sector_t sector, 18__inode_direct_access(struct inode *inode, sector_t block,
19 unsigned long *data) 19 void **kaddr, unsigned long *pfn)
20{ 20{
21 BUG_ON(!inode->i_sb->s_bdev->bd_disk->fops->direct_access); 21 struct block_device *bdev = inode->i_sb->s_bdev;
22 return inode->i_sb->s_bdev->bd_disk->fops 22 struct block_device_operations *ops = bdev->bd_disk->fops;
23 ->direct_access(inode->i_sb->s_bdev,sector,data); 23 sector_t sector;
24
25 sector = block * (PAGE_SIZE / 512); /* ext2 block to bdev sector */
26
27 BUG_ON(!ops->direct_access);
28 return ops->direct_access(bdev, sector, kaddr, pfn);
24} 29}
25 30
26static inline int 31static inline int
27__ext2_get_sector(struct inode *inode, sector_t offset, int create, 32__ext2_get_block(struct inode *inode, pgoff_t pgoff, int create,
28 sector_t *result) 33 sector_t *result)
29{ 34{
30 struct buffer_head tmp; 35 struct buffer_head tmp;
31 int rc; 36 int rc;
32 37
33 memset(&tmp, 0, sizeof(struct buffer_head)); 38 memset(&tmp, 0, sizeof(struct buffer_head));
34 rc = ext2_get_block(inode, offset/ (PAGE_SIZE/512), &tmp, 39 rc = ext2_get_block(inode, pgoff, &tmp, create);
35 create);
36 *result = tmp.b_blocknr; 40 *result = tmp.b_blocknr;
37 41
38 /* did we get a sparse block (hole in the file)? */ 42 /* did we get a sparse block (hole in the file)? */
@@ -45,15 +49,15 @@ __ext2_get_sector(struct inode *inode, sector_t offset, int create,
45} 49}
46 50
47int 51int
48ext2_clear_xip_target(struct inode *inode, int block) 52ext2_clear_xip_target(struct inode *inode, sector_t block)
49{ 53{
50 sector_t sector = block * (PAGE_SIZE/512); 54 void *kaddr;
51 unsigned long data; 55 unsigned long pfn;
52 int rc; 56 int rc;
53 57
54 rc = __inode_direct_access(inode, sector, &data); 58 rc = __inode_direct_access(inode, block, &kaddr, &pfn);
55 if (!rc) 59 if (!rc)
56 clear_page((void*)data); 60 clear_page(kaddr);
57 return rc; 61 return rc;
58} 62}
59 63
@@ -64,30 +68,23 @@ void ext2_xip_verify_sb(struct super_block *sb)
64 if ((sbi->s_mount_opt & EXT2_MOUNT_XIP) && 68 if ((sbi->s_mount_opt & EXT2_MOUNT_XIP) &&
65 !sb->s_bdev->bd_disk->fops->direct_access) { 69 !sb->s_bdev->bd_disk->fops->direct_access) {
66 sbi->s_mount_opt &= (~EXT2_MOUNT_XIP); 70 sbi->s_mount_opt &= (~EXT2_MOUNT_XIP);
67 ext2_warning(sb, __FUNCTION__, 71 ext2_warning(sb, __func__,
68 "ignoring xip option - not supported by bdev"); 72 "ignoring xip option - not supported by bdev");
69 } 73 }
70} 74}
71 75
72struct page * 76int ext2_get_xip_mem(struct address_space *mapping, pgoff_t pgoff, int create,
73ext2_get_xip_page(struct address_space *mapping, sector_t offset, 77 void **kmem, unsigned long *pfn)
74 int create)
75{ 78{
76 int rc; 79 int rc;
77 unsigned long data; 80 sector_t block;
78 sector_t sector;
79 81
80 /* first, retrieve the sector number */ 82 /* first, retrieve the sector number */
81 rc = __ext2_get_sector(mapping->host, offset, create, &sector); 83 rc = __ext2_get_block(mapping->host, pgoff, create, &block);
82 if (rc) 84 if (rc)
83 goto error; 85 return rc;
84 86
85 /* retrieve address of the target data */ 87 /* retrieve address of the target data */
86 rc = __inode_direct_access 88 rc = __inode_direct_access(mapping->host, block, kmem, pfn);
87 (mapping->host, sector * (PAGE_SIZE/512), &data); 89 return rc;
88 if (!rc)
89 return virt_to_page(data);
90
91 error:
92 return ERR_PTR(rc);
93} 90}