diff options
Diffstat (limited to 'drivers/block/xen-blkfront.c')
| -rw-r--r-- | drivers/block/xen-blkfront.c | 10 | 
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 96e9b00db08..11043c18ac5 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -792,6 +792,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)  {  	struct llist_node *all_gnts;  	struct grant *persistent_gnt; +	struct llist_node *n;  	/* Prevent new requests being issued until we fix things up. */  	spin_lock_irq(&info->io_lock); @@ -804,7 +805,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)  	/* Remove all persistent grants */  	if (info->persistent_gnts_c) {  		all_gnts = llist_del_all(&info->persistent_gnts); -		llist_for_each_entry(persistent_gnt, all_gnts, node) { +		llist_for_each_entry_safe(persistent_gnt, n, all_gnts, node) {  			gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);  			__free_page(pfn_to_page(persistent_gnt->pfn));  			kfree(persistent_gnt); @@ -835,7 +836,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)  static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,  			     struct blkif_response *bret)  { -	int i; +	int i = 0;  	struct bio_vec *bvec;  	struct req_iterator iter;  	unsigned long flags; @@ -852,7 +853,8 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,  		 */  		rq_for_each_segment(bvec, s->request, iter) {  			BUG_ON((bvec->bv_offset + bvec->bv_len) > PAGE_SIZE); -			i = offset >> PAGE_SHIFT; +			if (bvec->bv_offset < offset) +				i++;  			BUG_ON(i >= s->req.u.rw.nr_segments);  			shared_data = kmap_atomic(  				pfn_to_page(s->grants_used[i]->pfn)); @@ -861,7 +863,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,  				bvec->bv_len);  			bvec_kunmap_irq(bvec_data, &flags);  			kunmap_atomic(shared_data); -			offset += bvec->bv_len; +			offset = bvec->bv_offset + bvec->bv_len;  		}  	}  	/* Add the persistent grant into the list of free grants */  |