Whamcloud - gitweb
b=24214 Discard preallocation blocks after failed allocated.
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext3-map_inode_page-2.6.18.patch
1 Index: linux-2.6.18.8/fs/ext3/inode.c
2 ===================================================================
3 --- linux-2.6.18.8.orig/fs/ext3/inode.c 2007-06-20 18:10:33.000000000 +0200
4 +++ linux-2.6.18.8/fs/ext3/inode.c      2007-06-20 18:53:48.000000000 +0200
5 @@ -3222,3 +3222,66 @@ int ext3_change_inode_journal_flag(struc
6  
7         return err;
8  }
9 +
10 +int ext3_map_inode_page(struct inode *inode, struct page *page,
11 +                       unsigned long *blocks, int *created, int create)
12 +{
13 +       unsigned int blocksize, blocks_per_page;
14 +       unsigned long iblock;
15 +       struct buffer_head dummy;
16 +       void *handle;
17 +       int i, rc = 0, failed = 0, needed_blocks;
18 +
19 +       blocksize = inode->i_sb->s_blocksize;
20 +       blocks_per_page = PAGE_SIZE >> inode->i_sb->s_blocksize_bits;
21 +       iblock = page->index * blocks_per_page;
22 +
23 +       for (i = 0; i < blocks_per_page; i++, iblock++) {
24 +               blocks[i] = ext3_bmap(inode->i_mapping, iblock);
25 +               if (blocks[i] == 0) {
26 +                       failed++;
27 +                       if (created)
28 +                               created[i] = -1;
29 +               } else if (created) {
30 +                       created[i] = 0;
31 +               }
32 +       }
33 +
34 +       if (failed == 0 || create == 0)
35 +               return 0;
36 +
37 +       needed_blocks = ext3_writepage_trans_blocks(inode);
38 +       handle = ext3_journal_start(inode, needed_blocks);
39 +       if (IS_ERR(handle))
40 +               return PTR_ERR(handle);
41 +
42 +       iblock = page->index * blocks_per_page;
43 +       for (i = 0; i < blocks_per_page; i++, iblock++) {
44 +               if (blocks[i] != 0)
45 +                       continue;
46 +
47 +               rc = ext3_get_blocks_handle(handle, inode, iblock, 1, &dummy, 1, 1);
48 +               if (rc < 0) {
49 +                       printk(KERN_INFO "ext3_map_inode_page: error reading "
50 +                                       "block %ld\n", iblock);
51 +                       goto out;
52 +               } else {
53 +                       if (rc > 1)
54 +                               WARN_ON(1);
55 +                       rc = 0;
56 +               }
57 +               /* Unmap any metadata buffers from the block mapping, to avoid
58 +                * data corruption due to direct-write from Lustre being
59 +                * clobbered by a later flush of the blockdev metadata buffer.*/
60 +               if (buffer_new(&dummy))
61 +                       unmap_underlying_metadata(dummy.b_bdev,
62 +                                       dummy.b_blocknr);
63 +               blocks[i] = dummy.b_blocknr;
64 +               if (created)
65 +                       created[i] = 1;
66 +       }
67 +
68 +out:
69 +       ext3_journal_stop(handle);
70 +       return rc;
71 +}
72 Index: linux-2.6.18.8/fs/ext3/super.c
73 ===================================================================
74 --- linux-2.6.18.8.orig/fs/ext3/super.c 2007-06-20 18:10:33.000000000 +0200
75 +++ linux-2.6.18.8/fs/ext3/super.c      2007-06-20 18:51:12.000000000 +0200
76 @@ -2765,6 +2765,10 @@ static void __exit exit_ext3_fs(void)
77         exit_ext3_xattr();
78  }
79  
80 +int ext3_map_inode_page(struct inode *inode, struct page *page,
81 +                       unsigned long *blocks, int *created, int create);
82 +EXPORT_SYMBOL(ext3_map_inode_page);
83 +
84  MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
85  MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
86  MODULE_LICENSE("GPL");