summaryrefslogtreecommitdiff
path: root/fs/xfs/linux-2.6/xfs_aops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_aops.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c68
1 files changed, 39 insertions, 29 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 1edd3b694332..9278e9aba9ba 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -558,7 +558,8 @@ xfs_submit_page(
int i;
BUG_ON(PageWriteback(page));
- set_page_writeback(page);
+ if (bh_count)
+ set_page_writeback(page);
if (clear_dirty)
clear_page_dirty(page);
unlock_page(page);
@@ -578,9 +579,6 @@ xfs_submit_page(
if (probed_page && clear_dirty)
wbc->nr_to_write--; /* Wrote an "extra" page */
- } else {
- end_page_writeback(page);
- wbc->pages_skipped++; /* We didn't write this page */
}
}
@@ -602,21 +600,26 @@ xfs_convert_page(
{
struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head;
xfs_iomap_t *mp = iomapp, *tmp;
- unsigned long end, offset;
- pgoff_t end_index;
- int i = 0, index = 0;
+ unsigned long offset, end_offset;
+ int index = 0;
int bbits = inode->i_blkbits;
+ int len, page_dirty;
- end_index = i_size_read(inode) >> PAGE_CACHE_SHIFT;
- if (page->index < end_index) {
- end = PAGE_CACHE_SIZE;
- } else {
- end = i_size_read(inode) & (PAGE_CACHE_SIZE-1);
- }
+ end_offset = (i_size_read(inode) & (PAGE_CACHE_SIZE - 1));
+
+ /*
+ * page_dirty is initially a count of buffers on the page before
+ * EOF and is decrememted as we move each into a cleanable state.
+ */
+ len = 1 << inode->i_blkbits;
+ end_offset = max(end_offset, PAGE_CACHE_SIZE);
+ end_offset = roundup(end_offset, len);
+ page_dirty = end_offset / len;
+
+ offset = 0;
bh = head = page_buffers(page);
do {
- offset = i << bbits;
- if (offset >= end)
+ if (offset >= end_offset)
break;
if (!(PageUptodate(page) || buffer_uptodate(bh)))
continue;
@@ -625,6 +628,7 @@ xfs_convert_page(
if (startio) {
lock_buffer(bh);
bh_arr[index++] = bh;
+ page_dirty--;
}
continue;
}
@@ -657,10 +661,11 @@ xfs_convert_page(
unlock_buffer(bh);
mark_buffer_dirty(bh);
}
- } while (i++, (bh = bh->b_this_page) != head);
+ page_dirty--;
+ } while (offset += len, (bh = bh->b_this_page) != head);
- if (startio) {
- xfs_submit_page(page, wbc, bh_arr, index, 1, index == i);
+ if (startio && index) {
+ xfs_submit_page(page, wbc, bh_arr, index, 1, !page_dirty);
} else {
unlock_page(page);
}
@@ -743,19 +748,22 @@ xfs_page_state_convert(
}
}
- offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
end_offset = min_t(unsigned long long,
- offset + PAGE_CACHE_SIZE, i_size_read(inode));
-
- bh = head = page_buffers(page);
- iomp = NULL;
+ (loff_t)(page->index + 1) << PAGE_CACHE_SHIFT, offset);
+ offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
/*
- * page_dirty is initially a count of buffers on the page and
- * is decrememted as we move each into a cleanable state.
+ * page_dirty is initially a count of buffers on the page before
+ * EOF and is decrememted as we move each into a cleanable state.
*/
- len = bh->b_size;
- page_dirty = PAGE_CACHE_SIZE / len;
+ len = 1 << inode->i_blkbits;
+ p_offset = max(p_offset, PAGE_CACHE_SIZE);
+ p_offset = roundup(p_offset, len);
+ page_dirty = p_offset / len;
+
+ iomp = NULL;
+ p_offset = 0;
+ bh = head = page_buffers(page);
do {
if (offset >= end_offset)
@@ -877,8 +885,10 @@ xfs_page_state_convert(
if (uptodate && bh == head)
SetPageUptodate(page);
- if (startio)
- xfs_submit_page(page, wbc, bh_arr, cnt, 0, 1);
+ if (startio) {
+ WARN_ON(page_dirty);
+ xfs_submit_page(page, wbc, bh_arr, cnt, 0, !page_dirty);
+ }
if (iomp) {
offset = (iomp->iomap_offset + iomp->iomap_bsize - 1) >>