Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / kernel_patches / patches / ext3-map_inode_page-2.4.21-suse2.patch
1
2
3
4  fs/ext3/ext3-exports.c |    3 ++
5  fs/ext3/inode.c        |   55 +++++++++++++++++++++++++++++++++++++++++++++++++
6  2 files changed, 58 insertions(+)
7
8 Index: linux-2.4.21-suse2/fs/ext3/inode.c
9 ===================================================================
10 --- linux-2.4.21-suse2.orig/fs/ext3/inode.c     2004-01-10 15:38:24.000000000 +0300
11 +++ linux-2.4.21-suse2/fs/ext3/inode.c  2004-01-10 16:22:45.000000000 +0300
12 @@ -3084,7 +3084,7 @@
13         /* alloc blocks one by one */
14         for (i = 0; i < nblocks; i++) {
15                 ret = ext3_get_block_handle(handle, inode, blocks[i],
16 -                                               &bh_tmp, 1);
17 +                                               &bh_tmp, 1, 1);
18                 if (ret)
19                         break;
20  
21 @@ -3105,3 +3105,80 @@
22                 ret = ret2;
23         return ret;
24  }
25 +
26 +/* copied from fs/buffer.c */
27 +static void unmap_underlying_metadata(struct buffer_head * bh)
28 +{
29 +       struct buffer_head *old_bh;
30 +
31 +       old_bh = get_hash_table(bh->b_dev, bh->b_blocknr, bh->b_size);
32 +       if (old_bh) {
33 +               mark_buffer_clean(old_bh);
34 +               wait_on_buffer(old_bh);
35 +               clear_bit(BH_Req, &old_bh->b_state);
36 +               __brelse(old_bh);
37 +       }
38 +}
39 +
40 +int ext3_map_inode_page(struct inode *inode, struct page *page,
41 +                        unsigned long *blocks, int *created, int create)
42 +{
43 +        unsigned int blocksize, blocks_per_page;
44 +        unsigned long iblock;
45 +        void *handle;
46 +        int i, rc = 0, failed = 0, needed_blocks;
47 +
48 +        blocksize = inode->i_sb->s_blocksize;
49 +        blocks_per_page = PAGE_SIZE >> inode->i_sb->s_blocksize_bits;
50 +        iblock = page->index * blocks_per_page;
51 +
52 +        for (i = 0; i < blocks_per_page; i++, iblock++) {
53 +                blocks[i] = ext3_bmap(inode->i_mapping, iblock);
54 +                if (blocks[i] == 0) {
55 +                        failed++;
56 +                       if (created)
57 +                               created[i] = -1;
58 +               } else if (created) {
59 +                        created[i] = 0;
60 +                }
61 +        }
62 +
63 +        if (failed == 0 || create == 0)
64 +                return 0;
65 +
66 +        needed_blocks = ext3_writepage_trans_blocks(inode);
67 +        lock_kernel();
68 +        handle = ext3_journal_start(inode, needed_blocks);
69 +        unlock_kernel();
70 +        if (IS_ERR(handle))
71 +                return PTR_ERR(handle);
72 +
73 +        iblock = page->index * blocks_per_page;
74 +        for (i = 0; i < blocks_per_page; i++, iblock++) {
75 +                struct buffer_head bh;
76 +
77 +                if (blocks[i] != 0)
78 +                        continue;
79 +
80 +                rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1, 1);
81 +                if (rc) {
82 +                        printk(KERN_INFO "ext3_map_inode_page: error %d "
83 +                               "allocating block %ld\n", rc, iblock);
84 +                        goto out;
85 +                }
86 +               /* Unmap any metadata buffers from the block mapping, to avoid
87 +                * data corruption due to direct-write from Lustre being
88 +                * clobbered by a later flush of the blockdev metadata buffer.*/
89 +                if (buffer_new(&bh))
90 +                        unmap_underlying_metadata(&bh);
91 +                blocks[i] = bh.b_blocknr;
92 +               if (created)
93 +                       created[i] = 1;
94 +        }
95 +
96 + out:
97 +       lock_kernel();
98 +       ext3_journal_stop(handle, inode);
99 +       unlock_kernel();
100 +        return rc;
101 +}
102 Index: linux-2.4.21-suse2/fs/ext3/ext3-exports.c
103 ===================================================================
104 --- linux-2.4.21-suse2.orig/fs/ext3/ext3-exports.c      2004-01-10 15:38:24.000000000 +0300
105 +++ linux-2.4.21-suse2/fs/ext3/ext3-exports.c   2004-01-10 16:22:09.000000000 +0300
106 @@ -9,6 +9,8 @@
107  
108  int ext3_prep_san_write(struct inode *inode, long *blocks,
109                         int nblocks, loff_t newsize);
110 +int ext3_map_inode_page(struct inode *inode, struct page *page,
111 +                        unsigned long *block, int *created, int create);
112  
113  EXPORT_SYMBOL(ext3_force_commit);
114  EXPORT_SYMBOL(ext3_bread);
115 @@ -19,3 +21,4 @@
116  EXPORT_SYMBOL(ext3_xattr_list);
117  EXPORT_SYMBOL(ext3_xattr_set);
118  EXPORT_SYMBOL(ext3_prep_san_write);
119 +EXPORT_SYMBOL(ext3_map_inode_page);