Whamcloud - gitweb
LU-3719 ldiskfs: adjust s_mb_prealloc_table_size correctly
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / sles11sp2 / ext4-map_inode_page-3.0.patch
1 ---
2  fs/ext4/ext4.h  |    3 ++
3  fs/ext4/inode.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4  2 files changed, 71 insertions(+)
5
6 --- a/fs/ext4/ext4.h
7 +++ b/fs/ext4/ext4.h
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);
14 +
15  /* ioctl.c */
16  extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
17  extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
18 --- a/fs/ext4/inode.c
19 +++ b/fs/ext4/inode.c
20 @@ -5968,3 +5968,65 @@ out_unlock:
21         up_read(&inode->i_alloc_sem);
22         return ret;
23  }
24 +
25 +int ext4_map_inode_page(struct inode *inode, struct page *page,
26 +                       unsigned long *blocks, int create)
27 +{
28 +       unsigned int blocksize, blocks_per_page;
29 +       unsigned long iblock;
30 +       struct ext4_map_blocks map;
31 +       void *handle;
32 +       int i, rc = 0, failed = 0, needed_blocks;
33 +
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;
37 +
38 +       for (i = 0; i < blocks_per_page; i++, iblock++) {
39 +               blocks[i] = ext4_bmap(inode->i_mapping, iblock);
40 +               if (blocks[i] == 0) {
41 +                       failed++;
42 +               }
43 +       }
44 +
45 +       if (failed == 0 || create == 0)
46 +               return 0;
47 +
48 +       needed_blocks = ext4_writepage_trans_blocks(inode);
49 +       handle = ext4_journal_start(inode, needed_blocks);
50 +       if (IS_ERR(handle))
51 +               return PTR_ERR(handle);
52 +
53 +       iblock = page->index * blocks_per_page;
54 +       for (i = 0; i < blocks_per_page; i++, iblock++) {
55 +               if (blocks[i] != 0)
56 +                       continue;
57 +
58 +               map.m_lblk = iblock;
59 +               map.m_len = 1;
60 +               map.m_flags = 0;
61 +               rc = ext4_ind_map_blocks(handle, inode, &map,
62 +                                        EXT4_GET_BLOCKS_CREATE);
63 +               if (rc < 0) {
64 +                       printk(KERN_INFO "ext4_map_inode_page: error reading "
65 +                                       "block %ld\n", iblock);
66 +                       goto out;
67 +               } else {
68 +                       if (rc > 1)
69 +                               WARN_ON(1);
70 +                       rc = 0;
71 +               }
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,
77 +                                       map.m_pblk);
78 +               blocks[i] = map.m_pblk;
79 +       }
80 +
81 +out:
82 +       ext4_journal_stop(handle);
83 +       return rc;
84 +}
85 +EXPORT_SYMBOL(ext4_map_inode_page);