@@ -1132,12 +1132,26 @@ xfs_buf_bio_end_io(
xfs_buf_t *bp = (xfs_buf_t *)bio->bi_private;
unsigned int blocksize = bp->b_target->bt_bsize;
struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
+ void *vaddr = NULL;
+ int i;
xfs_buf_ioerror(bp, -error);
+ if (is_vmalloc_addr(bp->b_addr))
+ for (i = 0; i < bp->b_page_count; i++)
+ if (bvec->bv_page == bp->b_pages[i]) {
+ vaddr = bp->b_addr + i*PAGE_SIZE;
+ break;
+ }
+
do {
struct page *page = bvec->bv_page;
+ if (is_vmalloc_addr(bp->b_addr)) {
+ invalidate_kernel_dcache_addr(vaddr);
+ vaddr -= PAGE_SIZE;
+ }
+
ASSERT(!PagePrivate(page));
if (unlikely(bp->b_error)) {
if (bp->b_flags & XBF_READ)
@@ -1202,6 +1216,9 @@ _xfs_buf_ioapply(
bio->bi_end_io = xfs_buf_bio_end_io;
bio->bi_private = bp;
+ if (is_vmalloc_addr(bp->b_addr))
+ flush_kernel_dcache_addr(bp->b_addr);
+
bio_add_page(bio, bp->b_pages[0], PAGE_CACHE_SIZE, 0);
size = 0;
@@ -1228,6 +1245,9 @@ next_chunk:
if (nbytes > size)
nbytes = size;
+ if (is_vmalloc_addr(bp->b_addr))
+ flush_kernel_dcache_addr(bp->b_addr + PAGE_SIZE*map_i);
+
rbytes = bio_add_page(bio, bp->b_pages[map_i], nbytes, offset);
if (rbytes < nbytes)
break;