aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/ops_address.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2007-09-28 08:49:05 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2008-01-25 03:07:25 -0500
commit9ff8ec32e58875022447af619bec6e5aee7c77e4 (patch)
tree0c626762f334d1cc066113b3e47a2fa02a72af0c /fs/gfs2/ops_address.c
parent5561093e2cac9f7d2a77e39cc689b8d2b7f9b2bc (diff)
[GFS2] Split gfs2_writepage into three cases
This patch splits gfs2_writepage into separate functions for each of the three cases: writeback, ordered and journalled. As a result it becomes a lot easier to see what each one is doing. The common code is moved into gfs2_writepage_common. This fixes a performance bug where we were doing more work than strictly required in the ordered write case. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/ops_address.c')
-rw-r--r--fs/gfs2/ops_address.c112
1 files changed, 91 insertions, 21 deletions
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 207014f363d8..4bf73ed945ae 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -103,16 +103,15 @@ static int gfs2_get_block_direct(struct inode *inode, sector_t lblock,
103} 103}
104 104
105/** 105/**
106 * gfs2_writepage - Write complete page 106 * gfs2_writepage_common - Common bits of writepage
107 * @page: Page to write 107 * @page: The page to be written
108 * 108 * @wbc: The writeback control
109 * Returns: errno
110 * 109 *
111 * Some of this is copied from block_write_full_page() although we still 110 * Returns: 1 if writepage is ok, otherwise an error code or zero if no error.
112 * call it to do most of the work.
113 */ 111 */
114 112
115static int gfs2_writepage(struct page *page, struct writeback_control *wbc) 113static int gfs2_writepage_common(struct page *page,
114 struct writeback_control *wbc)
116{ 115{
117 struct inode *inode = page->mapping->host; 116 struct inode *inode = page->mapping->host;
118 struct gfs2_inode *ip = GFS2_I(inode); 117 struct gfs2_inode *ip = GFS2_I(inode);
@@ -120,23 +119,94 @@ static int gfs2_writepage(struct page *page, struct writeback_control *wbc)
120 loff_t i_size = i_size_read(inode); 119 loff_t i_size = i_size_read(inode);
121 pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT; 120 pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
122 unsigned offset; 121 unsigned offset;
123 int error; 122 int ret = -EIO;
124 int done_trans = 0;
125 123
126 if (gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(ip->i_gl))) { 124 if (gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(ip->i_gl)))
127 unlock_page(page); 125 goto out;
128 return -EIO; 126 ret = 0;
129 }
130 if (current->journal_info) 127 if (current->journal_info)
131 goto out_ignore; 128 goto redirty;
132
133 /* Is the page fully outside i_size? (truncate in progress) */ 129 /* Is the page fully outside i_size? (truncate in progress) */
134 offset = i_size & (PAGE_CACHE_SIZE-1); 130 offset = i_size & (PAGE_CACHE_SIZE-1);
135 if (page->index > end_index || (page->index == end_index && !offset)) { 131 if (page->index > end_index || (page->index == end_index && !offset)) {
136 page->mapping->a_ops->invalidatepage(page, 0); 132 page->mapping->a_ops->invalidatepage(page, 0);
137 unlock_page(page); 133 goto out;
138 return 0; /* don't care */
139 } 134 }
135 return 1;
136redirty:
137 redirty_page_for_writepage(wbc, page);
138out:
139 unlock_page(page);
140 return 0;
141}
142
143/**
144 * gfs2_writeback_writepage - Write page for writeback mappings
145 * @page: The page
146 * @wbc: The writeback control
147 *
148 */
149
150static int gfs2_writeback_writepage(struct page *page,
151 struct writeback_control *wbc)
152{
153 int ret;
154
155 ret = gfs2_writepage_common(page, wbc);
156 if (ret <= 0)
157 return ret;
158
159 ret = mpage_writepage(page, gfs2_get_block_noalloc, wbc);
160 if (ret == -EAGAIN)
161 ret = block_write_full_page(page, gfs2_get_block_noalloc, wbc);
162 return ret;
163}
164
165/**
166 * gfs2_ordered_writepage - Write page for ordered data files
167 * @page: The page to write
168 * @wbc: The writeback control
169 *
170 */
171
172static int gfs2_ordered_writepage(struct page *page,
173 struct writeback_control *wbc)
174{
175 struct inode *inode = page->mapping->host;
176 struct gfs2_inode *ip = GFS2_I(inode);
177 int ret;
178
179 ret = gfs2_writepage_common(page, wbc);
180 if (ret <= 0)
181 return ret;
182
183 if (!page_has_buffers(page)) {
184 create_empty_buffers(page, inode->i_sb->s_blocksize,
185 (1 << BH_Dirty)|(1 << BH_Uptodate));
186 }
187 gfs2_page_add_databufs(ip, page, 0, inode->i_sb->s_blocksize-1);
188 return block_write_full_page(page, gfs2_get_block_noalloc, wbc);
189}
190
191/**
192 * gfs2_jdata_writepage - Write complete page
193 * @page: Page to write
194 *
195 * Returns: errno
196 *
197 */
198
199static int gfs2_jdata_writepage(struct page *page, struct writeback_control *wbc)
200{
201 struct inode *inode = page->mapping->host;
202 struct gfs2_inode *ip = GFS2_I(inode);
203 struct gfs2_sbd *sdp = GFS2_SB(inode);
204 int error;
205 int done_trans = 0;
206
207 error = gfs2_writepage_common(page, wbc);
208 if (error <= 0)
209 return error;
140 210
141 if (PageChecked(page)) { 211 if (PageChecked(page)) {
142 error = gfs2_trans_begin(sdp, RES_DINODE + 1, 0); 212 error = gfs2_trans_begin(sdp, RES_DINODE + 1, 0);
@@ -838,7 +908,7 @@ cannot_release:
838} 908}
839 909
840static const struct address_space_operations gfs2_writeback_aops = { 910static const struct address_space_operations gfs2_writeback_aops = {
841 .writepage = gfs2_writepage, 911 .writepage = gfs2_writeback_writepage,
842 .writepages = gfs2_writeback_writepages, 912 .writepages = gfs2_writeback_writepages,
843 .readpage = gfs2_readpage, 913 .readpage = gfs2_readpage,
844 .readpages = gfs2_readpages, 914 .readpages = gfs2_readpages,
@@ -852,7 +922,7 @@ static const struct address_space_operations gfs2_writeback_aops = {
852}; 922};
853 923
854static const struct address_space_operations gfs2_ordered_aops = { 924static const struct address_space_operations gfs2_ordered_aops = {
855 .writepage = gfs2_writepage, 925 .writepage = gfs2_ordered_writepage,
856 .readpage = gfs2_readpage, 926 .readpage = gfs2_readpage,
857 .readpages = gfs2_readpages, 927 .readpages = gfs2_readpages,
858 .sync_page = block_sync_page, 928 .sync_page = block_sync_page,
@@ -866,7 +936,7 @@ static const struct address_space_operations gfs2_ordered_aops = {
866}; 936};
867 937
868static const struct address_space_operations gfs2_jdata_aops = { 938static const struct address_space_operations gfs2_jdata_aops = {
869 .writepage = gfs2_writepage, 939 .writepage = gfs2_jdata_writepage,
870 .readpage = gfs2_readpage, 940 .readpage = gfs2_readpage,
871 .readpages = gfs2_readpages, 941 .readpages = gfs2_readpages,
872 .sync_page = block_sync_page, 942 .sync_page = block_sync_page,