diff options
Diffstat (limited to 'fs/ext4/page-io.c')
-rw-r--r-- | fs/ext4/page-io.c | 39 |
1 files changed, 11 insertions, 28 deletions
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index b6dbd056fcb1..7bb8f76d470a 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c | |||
@@ -203,46 +203,29 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
203 | for (i = 0; i < io_end->num_io_pages; i++) { | 203 | for (i = 0; i < io_end->num_io_pages; i++) { |
204 | struct page *page = io_end->pages[i]->p_page; | 204 | struct page *page = io_end->pages[i]->p_page; |
205 | struct buffer_head *bh, *head; | 205 | struct buffer_head *bh, *head; |
206 | int partial_write = 0; | 206 | loff_t offset; |
207 | loff_t io_end_offset; | ||
207 | 208 | ||
208 | head = page_buffers(page); | 209 | if (error) { |
209 | if (error) | ||
210 | SetPageError(page); | 210 | SetPageError(page); |
211 | BUG_ON(!head); | 211 | set_bit(AS_EIO, &page->mapping->flags); |
212 | if (head->b_size != PAGE_CACHE_SIZE) { | 212 | head = page_buffers(page); |
213 | loff_t offset; | 213 | BUG_ON(!head); |
214 | loff_t io_end_offset = io_end->offset + io_end->size; | 214 | |
215 | io_end_offset = io_end->offset + io_end->size; | ||
215 | 216 | ||
216 | offset = (sector_t) page->index << PAGE_CACHE_SHIFT; | 217 | offset = (sector_t) page->index << PAGE_CACHE_SHIFT; |
217 | bh = head; | 218 | bh = head; |
218 | do { | 219 | do { |
219 | if ((offset >= io_end->offset) && | 220 | if ((offset >= io_end->offset) && |
220 | (offset+bh->b_size <= io_end_offset)) { | 221 | (offset+bh->b_size <= io_end_offset)) |
221 | if (error) | 222 | buffer_io_error(bh); |
222 | buffer_io_error(bh); | 223 | |
223 | |||
224 | } | ||
225 | if (buffer_delay(bh)) | ||
226 | partial_write = 1; | ||
227 | else if (!buffer_mapped(bh)) | ||
228 | clear_buffer_dirty(bh); | ||
229 | else if (buffer_dirty(bh)) | ||
230 | partial_write = 1; | ||
231 | offset += bh->b_size; | 224 | offset += bh->b_size; |
232 | bh = bh->b_this_page; | 225 | bh = bh->b_this_page; |
233 | } while (bh != head); | 226 | } while (bh != head); |
234 | } | 227 | } |
235 | 228 | ||
236 | /* | ||
237 | * If this is a partial write which happened to make | ||
238 | * all buffers uptodate then we can optimize away a | ||
239 | * bogus readpage() for the next read(). Here we | ||
240 | * 'discover' whether the page went uptodate as a | ||
241 | * result of this (potentially partial) write. | ||
242 | */ | ||
243 | if (!partial_write) | ||
244 | SetPageUptodate(page); | ||
245 | |||
246 | put_io_page(io_end->pages[i]); | 229 | put_io_page(io_end->pages[i]); |
247 | } | 230 | } |
248 | io_end->num_io_pages = 0; | 231 | io_end->num_io_pages = 0; |