X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=mm%2Fhighmem.c;h=e4cb0aadadaa151c697c3d073349398794dd8216;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=432da5b68baf5ae4c730610c7f69019e387a7ca0;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/mm/highmem.c b/mm/highmem.c index 432da5b68..e4cb0aada 100644 --- a/mm/highmem.c +++ b/mm/highmem.c @@ -53,7 +53,7 @@ static void page_pool_free(void *page, void *data) #ifdef CONFIG_HIGHMEM static int pkmap_count[LAST_PKMAP]; static unsigned int last_pkmap_nr; -static spinlock_t kmap_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; +static __cacheline_aligned_in_smp DEFINE_SPINLOCK(kmap_lock); pte_t * pkmap_page_table; @@ -284,7 +284,7 @@ static void copy_to_high_bio_irq(struct bio *to, struct bio *from) struct bio_vec *tovec, *fromvec; int i; - bio_for_each_segment(tovec, to, i) { + __bio_for_each_segment(tovec, to, i, 0) { fromvec = from->bi_io_vec + i; /* @@ -300,23 +300,24 @@ static void copy_to_high_bio_irq(struct bio *to, struct bio *from) */ vfrom = page_address(fromvec->bv_page) + tovec->bv_offset; + flush_dcache_page(tovec->bv_page); bounce_copy_vec(tovec, vfrom); } } -static void bounce_end_io(struct bio *bio, mempool_t *pool) +static void bounce_end_io(struct bio *bio, mempool_t *pool, int err) { struct bio *bio_orig = bio->bi_private; struct bio_vec *bvec, *org_vec; - int i, err = 0; + int i; - if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) - err = -EIO; + if (test_bit(BIO_EOPNOTSUPP, &bio->bi_flags)) + set_bit(BIO_EOPNOTSUPP, &bio_orig->bi_flags); /* * free up bounce indirect pages used */ - bio_for_each_segment(bvec, bio, i) { + __bio_for_each_segment(bvec, bio, i, 0) { org_vec = bio_orig->bi_io_vec + i; if (bvec->bv_page == org_vec->bv_page) continue; @@ -333,7 +334,7 @@ static int bounce_end_io_write(struct bio *bio, unsigned int bytes_done,int err) if (bio->bi_size) return 1; - bounce_end_io(bio, page_pool); + bounce_end_io(bio, page_pool, err); return 0; } @@ -342,18 +343,18 @@ static int bounce_end_io_write_isa(struct bio *bio, unsigned int bytes_done, int if (bio->bi_size) return 1; - bounce_end_io(bio, isa_page_pool); + bounce_end_io(bio, isa_page_pool, err); return 0; } -static void __bounce_end_io_read(struct bio *bio, mempool_t *pool) +static void __bounce_end_io_read(struct bio *bio, mempool_t *pool, int err) { struct bio *bio_orig = bio->bi_private; if (test_bit(BIO_UPTODATE, &bio->bi_flags)) copy_to_high_bio_irq(bio_orig, bio); - bounce_end_io(bio, pool); + bounce_end_io(bio, pool, err); } static int bounce_end_io_read(struct bio *bio, unsigned int bytes_done, int err) @@ -361,7 +362,7 @@ static int bounce_end_io_read(struct bio *bio, unsigned int bytes_done, int err) if (bio->bi_size) return 1; - __bounce_end_io_read(bio, page_pool); + __bounce_end_io_read(bio, page_pool, err); return 0; } @@ -370,7 +371,7 @@ static int bounce_end_io_read_isa(struct bio *bio, unsigned int bytes_done, int if (bio->bi_size) return 1; - __bounce_end_io_read(bio, isa_page_pool); + __bounce_end_io_read(bio, isa_page_pool, err); return 0; } @@ -406,6 +407,7 @@ static void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig, if (rw == WRITE) { char *vto, *vfrom; + flush_dcache_page(from->bv_page); vto = page_address(to->bv_page) + to->bv_offset; vfrom = kmap(from->bv_page) + from->bv_offset; memcpy(vto, vfrom, to->bv_len); @@ -423,7 +425,7 @@ static void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig, * at least one page was bounced, fill in possible non-highmem * pages */ - bio_for_each_segment(from, *bio_orig, i) { + __bio_for_each_segment(from, *bio_orig, i, 0) { to = bio_iovec_idx(bio, i); if (!to->bv_page) { to->bv_page = from->bv_page;