3 fs/ext4/inode.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 2 files changed, 71 insertions(+)
8 @@ -1838,6 +1838,9 @@ extern int ext4_page_mkwrite(struct vm_a
9 extern qsize_t *ext4_get_reserved_space(struct inode *inode);
10 extern void ext4_da_update_reserve_space(struct inode *inode,
11 int used, int quota_claim);
12 +extern int ext4_map_inode_page(struct inode *inode, struct page *page,
13 + unsigned long *blocks, int created);
16 extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
17 extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
20 @@ -5968,3 +5968,65 @@ out_unlock:
21 up_read(&inode->i_alloc_sem);
25 +int ext4_map_inode_page(struct inode *inode, struct page *page,
26 + unsigned long *blocks, int create)
28 + unsigned int blocksize, blocks_per_page;
29 + unsigned long iblock;
30 + struct ext4_map_blocks map;
32 + int i, rc = 0, failed = 0, needed_blocks;
34 + blocksize = inode->i_sb->s_blocksize;
35 + blocks_per_page = PAGE_SIZE >> inode->i_sb->s_blocksize_bits;
36 + iblock = page->index * blocks_per_page;
38 + for (i = 0; i < blocks_per_page; i++, iblock++) {
39 + blocks[i] = ext4_bmap(inode->i_mapping, iblock);
40 + if (blocks[i] == 0) {
45 + if (failed == 0 || create == 0)
48 + needed_blocks = ext4_writepage_trans_blocks(inode);
49 + handle = ext4_journal_start(inode, needed_blocks);
51 + return PTR_ERR(handle);
53 + iblock = page->index * blocks_per_page;
54 + for (i = 0; i < blocks_per_page; i++, iblock++) {
58 + map.m_lblk = iblock;
61 + rc = ext4_ind_map_blocks(handle, inode, &map,
62 + EXT4_GET_BLOCKS_CREATE);
64 + printk(KERN_INFO "ext4_map_inode_page: error reading "
65 + "block %ld\n", iblock);
72 + /* Unmap any metadata buffers from the block mapping, to avoid
73 + * data corruption due to direct-write from Lustre being
74 + * clobbered by a later flush of the blockdev metadata buffer.*/
75 + if (map.m_flags & EXT4_MAP_NEW)
76 + unmap_underlying_metadata(inode->i_sb->s_bdev,
78 + blocks[i] = map.m_pblk;
82 + ext4_journal_stop(handle);
85 +EXPORT_SYMBOL(ext4_map_inode_page);