diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext2/inode.c | 2 | ||||
-rw-r--r-- | fs/ext2/xip.c | 37 | ||||
-rw-r--r-- | fs/ext2/xip.h | 9 | ||||
-rw-r--r-- | fs/open.c | 2 |
4 files changed, 22 insertions, 28 deletions
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index b8a2990bab83..687023bdfd1e 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -796,7 +796,7 @@ const struct address_space_operations ext2_aops = { | |||
796 | 796 | ||
797 | const struct address_space_operations ext2_aops_xip = { | 797 | const struct address_space_operations ext2_aops_xip = { |
798 | .bmap = ext2_bmap, | 798 | .bmap = ext2_bmap, |
799 | .get_xip_page = ext2_get_xip_page, | 799 | .get_xip_mem = ext2_get_xip_mem, |
800 | }; | 800 | }; |
801 | 801 | ||
802 | const struct address_space_operations ext2_nobh_aops = { | 802 | const struct address_space_operations ext2_nobh_aops = { |
diff --git a/fs/ext2/xip.c b/fs/ext2/xip.c index 430b4c8ee971..233f7fdbe31d 100644 --- a/fs/ext2/xip.c +++ b/fs/ext2/xip.c | |||
@@ -15,26 +15,28 @@ | |||
15 | #include "xip.h" | 15 | #include "xip.h" |
16 | 16 | ||
17 | static inline int | 17 | static inline int |
18 | __inode_direct_access(struct inode *inode, sector_t sector, | 18 | __inode_direct_access(struct inode *inode, sector_t block, |
19 | void **kaddr, unsigned long *pfn) | 19 | void **kaddr, unsigned long *pfn) |
20 | { | 20 | { |
21 | struct block_device *bdev = inode->i_sb->s_bdev; | 21 | struct block_device *bdev = inode->i_sb->s_bdev; |
22 | struct block_device_operations *ops = bdev->bd_disk->fops; | 22 | struct block_device_operations *ops = bdev->bd_disk->fops; |
23 | sector_t sector; | ||
24 | |||
25 | sector = block * (PAGE_SIZE / 512); /* ext2 block to bdev sector */ | ||
23 | 26 | ||
24 | BUG_ON(!ops->direct_access); | 27 | BUG_ON(!ops->direct_access); |
25 | return ops->direct_access(bdev, sector, kaddr, pfn); | 28 | return ops->direct_access(bdev, sector, kaddr, pfn); |
26 | } | 29 | } |
27 | 30 | ||
28 | static inline int | 31 | static inline int |
29 | __ext2_get_sector(struct inode *inode, sector_t offset, int create, | 32 | __ext2_get_block(struct inode *inode, pgoff_t pgoff, int create, |
30 | sector_t *result) | 33 | sector_t *result) |
31 | { | 34 | { |
32 | struct buffer_head tmp; | 35 | struct buffer_head tmp; |
33 | int rc; | 36 | int rc; |
34 | 37 | ||
35 | memset(&tmp, 0, sizeof(struct buffer_head)); | 38 | memset(&tmp, 0, sizeof(struct buffer_head)); |
36 | rc = ext2_get_block(inode, offset/ (PAGE_SIZE/512), &tmp, | 39 | rc = ext2_get_block(inode, pgoff, &tmp, create); |
37 | create); | ||
38 | *result = tmp.b_blocknr; | 40 | *result = tmp.b_blocknr; |
39 | 41 | ||
40 | /* did we get a sparse block (hole in the file)? */ | 42 | /* did we get a sparse block (hole in the file)? */ |
@@ -47,14 +49,13 @@ __ext2_get_sector(struct inode *inode, sector_t offset, int create, | |||
47 | } | 49 | } |
48 | 50 | ||
49 | int | 51 | int |
50 | ext2_clear_xip_target(struct inode *inode, int block) | 52 | ext2_clear_xip_target(struct inode *inode, sector_t block) |
51 | { | 53 | { |
52 | sector_t sector = block * (PAGE_SIZE/512); | ||
53 | void *kaddr; | 54 | void *kaddr; |
54 | unsigned long pfn; | 55 | unsigned long pfn; |
55 | int rc; | 56 | int rc; |
56 | 57 | ||
57 | rc = __inode_direct_access(inode, sector, &kaddr, &pfn); | 58 | rc = __inode_direct_access(inode, block, &kaddr, &pfn); |
58 | if (!rc) | 59 | if (!rc) |
59 | clear_page(kaddr); | 60 | clear_page(kaddr); |
60 | return rc; | 61 | return rc; |
@@ -72,26 +73,18 @@ void ext2_xip_verify_sb(struct super_block *sb) | |||
72 | } | 73 | } |
73 | } | 74 | } |
74 | 75 | ||
75 | struct page * | 76 | int ext2_get_xip_mem(struct address_space *mapping, pgoff_t pgoff, int create, |
76 | ext2_get_xip_page(struct address_space *mapping, sector_t offset, | 77 | void **kmem, unsigned long *pfn) |
77 | int create) | ||
78 | { | 78 | { |
79 | int rc; | 79 | int rc; |
80 | void *kaddr; | 80 | sector_t block; |
81 | unsigned long pfn; | ||
82 | sector_t sector; | ||
83 | 81 | ||
84 | /* first, retrieve the sector number */ | 82 | /* first, retrieve the sector number */ |
85 | rc = __ext2_get_sector(mapping->host, offset, create, §or); | 83 | rc = __ext2_get_block(mapping->host, pgoff, create, &block); |
86 | if (rc) | 84 | if (rc) |
87 | goto error; | 85 | return rc; |
88 | 86 | ||
89 | /* retrieve address of the target data */ | 87 | /* retrieve address of the target data */ |
90 | rc = __inode_direct_access | 88 | rc = __inode_direct_access(mapping->host, block, kmem, pfn); |
91 | (mapping->host, sector * (PAGE_SIZE/512), &kaddr, &pfn); | 89 | return rc; |
92 | if (!rc) | ||
93 | return pfn_to_page(pfn); | ||
94 | |||
95 | error: | ||
96 | return ERR_PTR(rc); | ||
97 | } | 90 | } |
diff --git a/fs/ext2/xip.h b/fs/ext2/xip.h index aa85331d6c56..18b34d2f31b3 100644 --- a/fs/ext2/xip.h +++ b/fs/ext2/xip.h | |||
@@ -7,19 +7,20 @@ | |||
7 | 7 | ||
8 | #ifdef CONFIG_EXT2_FS_XIP | 8 | #ifdef CONFIG_EXT2_FS_XIP |
9 | extern void ext2_xip_verify_sb (struct super_block *); | 9 | extern void ext2_xip_verify_sb (struct super_block *); |
10 | extern int ext2_clear_xip_target (struct inode *, int); | 10 | extern int ext2_clear_xip_target (struct inode *, sector_t); |
11 | 11 | ||
12 | static inline int ext2_use_xip (struct super_block *sb) | 12 | static inline int ext2_use_xip (struct super_block *sb) |
13 | { | 13 | { |
14 | struct ext2_sb_info *sbi = EXT2_SB(sb); | 14 | struct ext2_sb_info *sbi = EXT2_SB(sb); |
15 | return (sbi->s_mount_opt & EXT2_MOUNT_XIP); | 15 | return (sbi->s_mount_opt & EXT2_MOUNT_XIP); |
16 | } | 16 | } |
17 | struct page* ext2_get_xip_page (struct address_space *, sector_t, int); | 17 | int ext2_get_xip_mem(struct address_space *, pgoff_t, int, |
18 | #define mapping_is_xip(map) unlikely(map->a_ops->get_xip_page) | 18 | void **, unsigned long *); |
19 | #define mapping_is_xip(map) unlikely(map->a_ops->get_xip_mem) | ||
19 | #else | 20 | #else |
20 | #define mapping_is_xip(map) 0 | 21 | #define mapping_is_xip(map) 0 |
21 | #define ext2_xip_verify_sb(sb) do { } while (0) | 22 | #define ext2_xip_verify_sb(sb) do { } while (0) |
22 | #define ext2_use_xip(sb) 0 | 23 | #define ext2_use_xip(sb) 0 |
23 | #define ext2_clear_xip_target(inode, chain) 0 | 24 | #define ext2_clear_xip_target(inode, chain) 0 |
24 | #define ext2_get_xip_page NULL | 25 | #define ext2_get_xip_mem NULL |
25 | #endif | 26 | #endif |
@@ -837,7 +837,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, | |||
837 | if (f->f_flags & O_DIRECT) { | 837 | if (f->f_flags & O_DIRECT) { |
838 | if (!f->f_mapping->a_ops || | 838 | if (!f->f_mapping->a_ops || |
839 | ((!f->f_mapping->a_ops->direct_IO) && | 839 | ((!f->f_mapping->a_ops->direct_IO) && |
840 | (!f->f_mapping->a_ops->get_xip_page))) { | 840 | (!f->f_mapping->a_ops->get_xip_mem))) { |
841 | fput(f); | 841 | fput(f); |
842 | f = ERR_PTR(-EINVAL); | 842 | f = ERR_PTR(-EINVAL); |
843 | } | 843 | } |