patch-2.4.4 linux/drivers/block/loop.c

Next file: linux/drivers/block/nbd.c
Previous file: linux/drivers/block/ll_rw_blk.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.3/linux/drivers/block/loop.c linux/drivers/block/loop.c
@@ -316,7 +316,6 @@
 static void loop_put_buffer(struct buffer_head *bh)
 {
 	if (bh) {
-		kunmap(bh->b_page);
 		__free_page(bh->b_page);
 		kmem_cache_free(bh_cachep, bh);
 	}
@@ -408,9 +407,16 @@
 	 * blocks... if highmem bounce buffering can get away with it,
 	 * so can we :-)
 	 */
-	bh->b_page = alloc_page(GFP_BUFFER);
-	bh->b_data = kmap(bh->b_page);
+	do {
+		bh->b_page = alloc_page(GFP_BUFFER);
+		if (bh->b_page)
+			break;
+
+		run_task_queue(&tq_disk);
+		schedule_timeout(HZ);
+	} while (1);
 
+	bh->b_data = page_address(bh->b_page);
 	bh->b_end_io = loop_end_io_transfer;
 	bh->b_rsector = rbh->b_rsector + (lo->lo_offset >> 9);
 	init_waitqueue_head(&bh->b_wait);
@@ -455,6 +461,10 @@
 	 * file backed, queue for loop_thread to handle
 	 */
 	if (lo->lo_flags & LO_FLAGS_DO_BMAP) {
+		/*
+		 * rbh locked at this point, noone else should clear
+		 * the dirty flag
+		 */
 		if (rw == WRITE)
 			set_bit(BH_Dirty, &rbh->b_state);
 		loop_add_bh(lo, rbh);
@@ -469,7 +479,8 @@
 	IV = loop_get_iv(lo, bh->b_rsector);
 	if (rw == WRITE) {
 		set_bit(BH_Dirty, &bh->b_state);
-		if (lo_do_transfer(lo, WRITE, bh->b_data, rbh->b_data, bh->b_size, IV))
+		if (lo_do_transfer(lo, WRITE, bh->b_data, rbh->b_data,
+				   bh->b_size, IV))
 			goto err;
 	}
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)