Add journal checksum patches. Also move
[ext4-patch-queue.git] / ext4-delalloc-inverse-jbd-and-page-lock-ordering.patch
blobffaaca60cd3ce3b10811851bd7c9fea488f542f4
1 ext4: inverse locking ordering of page_lock and transaction start in delalloc
3 From: Mingming Cao <cmm@us.ibm.com>
5 Inverse locking ordering of page_lock and transaction start in delalloc
7 Signed-off-by: Mingming Cao <cmm@us.ibm.com>
8 Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
9 ---
11 fs/ext4/inode.c | 96 +++++++++++++++++++++++++++++++++++++++----------------
12 1 files changed, 68 insertions(+), 28 deletions(-)
15 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
16 index 62b38b6..65e02a3 100644
17 --- a/fs/ext4/inode.c
18 +++ b/fs/ext4/inode.c
19 @@ -1448,18 +1448,14 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
20 static int ext4_da_get_block_write(struct inode *inode, sector_t iblock,
21 struct buffer_head *bh_result, int create)
23 - int ret, needed_blocks = ext4_writepage_trans_blocks(inode);
24 + int ret;
25 unsigned max_blocks = bh_result->b_size >> inode->i_blkbits;
26 loff_t disksize = EXT4_I(inode)->i_disksize;
27 handle_t *handle = NULL;
29 - if (create) {
30 - handle = ext4_journal_start(inode, needed_blocks);
31 - if (IS_ERR(handle)) {
32 - ret = PTR_ERR(handle);
33 - goto out;
34 - }
35 - }
36 + handle = ext4_journal_current_handle();
37 + BUG_ON(handle == 0);
38 + BUG_ON(create == 0);
40 ret = ext4_get_blocks_wrap(handle, inode, iblock, max_blocks,
41 bh_result, create, 0);
42 @@ -1494,29 +1490,17 @@ static int ext4_da_get_block_write(struct inode *inode, sector_t iblock,
43 ret = 0;
46 -out:
47 - if (handle && !IS_ERR(handle))
48 - ext4_journal_stop(handle);
50 return ret;
52 /* FIXME!! only support data=writeback mode */
53 -static int ext4_da_writepage(struct page *page,
54 +static int __ext4_da_writepage(struct page *page,
55 struct writeback_control *wbc)
57 struct inode *inode = page->mapping->host;
58 handle_t *handle = NULL;
59 int ret = 0;
60 - int err;
62 - if (ext4_journal_current_handle())
63 - goto out_fail;
65 - handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode));
66 - if (IS_ERR(handle)) {
67 - ret = PTR_ERR(handle);
68 - goto out_fail;
69 - }
70 + handle = ext4_journal_current_handle();
72 if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode))
73 ret = nobh_writepage(page, ext4_get_block, wbc);
74 @@ -1528,21 +1512,77 @@ static int ext4_da_writepage(struct page *page,
75 ext4_mark_inode_dirty(handle, inode);
78 - err = ext4_journal_stop(handle);
79 - if (!ret)
80 - ret = err;
81 return ret;
83 +static int ext4_da_writepage(struct page *page,
84 + struct writeback_control *wbc)
86 + if (!ext4_journal_current_handle())
87 + return __ext4_da_writepage(page, wbc);
89 -out_fail:
90 redirty_page_for_writepage(wbc, page);
91 unlock_page(page);
92 - return ret;
93 + return 0;
96 +/*
97 + * For now just follow the DIO way to estimate the max credits
98 + * needed to write out EXT4_MAX_WRITEBACK_PAGES.
99 + * todo: need to calculate the max credits need for
100 + * extent based files, currently the DIO credits is based on
101 + * indirect-blocks mapping way.
103 + * Probably should have a generic way to calculate credits
104 + * for DIO, writepages, and truncate
105 + */
106 +#define EXT4_MAX_WRITEBACK_PAGES DIO_MAX_BLOCKS
107 +#define EXT4_MAX_WRITEBACK_CREDITS DIO_CREDITS
109 static int ext4_da_writepages(struct address_space *mapping,
110 struct writeback_control *wbc)
112 - return mpage_da_writepages(mapping, wbc, ext4_da_get_block_write);
113 + struct inode *inode = mapping->host;
114 + handle_t *handle = NULL;
115 + int needed_blocks;
116 + int ret = 0;
117 + unsigned range_cyclic;
118 + long to_write;
120 + /*
121 + * Estimate the worse case needed credits to write out
122 + * EXT4_MAX_BUF_BLOCKS pages
123 + */
124 + needed_blocks = EXT4_MAX_WRITEBACK_CREDITS;
126 + to_write = wbc->nr_to_write;
127 + range_cyclic = wbc->range_cyclic;
128 + wbc->range_cyclic = 1;
130 + while (!ret && to_write) {
131 + /* start a new transaction*/
132 + handle = ext4_journal_start(inode, needed_blocks);
133 + if (IS_ERR(handle)) {
134 + ret = PTR_ERR(handle);
135 + goto out_writepages;
137 + /*
138 + * set the max dirty pages could be write at a time
139 + * to fit into the reserved transaction credits
140 + */
141 + if (wbc->nr_to_write > EXT4_MAX_WRITEBACK_PAGES)
142 + wbc->nr_to_write = EXT4_MAX_WRITEBACK_PAGES;
143 + to_write -= wbc->nr_to_write;
145 + ret = mpage_da_writepages(mapping, wbc,
146 + ext4_da_get_block_write);
147 + ext4_journal_stop(handle);
148 + to_write += wbc->nr_to_write;
151 +out_writepages:
152 + wbc->nr_to_write = to_write;
153 + wbc->range_cyclic = range_cyclic;
154 + return ret;
157 static int ext4_da_write_begin(struct file *file, struct address_space *mapping,