patch-2.4.15 linux/drivers/block/loop.c
Next file: linux/drivers/block/paride/pd.c
Previous file: linux/drivers/block/cpqarray.c
Back to the patch index
Back to the overall index
- Lines: 60
- Date:
Mon Nov 19 14:48:02 2001
- Orig file:
v2.4.14/linux/drivers/block/loop.c
- Orig date:
Mon Nov 5 15:55:29 2001
diff -u --recursive --new-file v2.4.14/linux/drivers/block/loop.c linux/drivers/block/loop.c
@@ -180,12 +180,15 @@
unsigned size, offset;
int len;
+ down(&mapping->host->i_sem);
index = pos >> PAGE_CACHE_SHIFT;
offset = pos & (PAGE_CACHE_SIZE - 1);
len = bh->b_size;
data = bh->b_data;
while (len > 0) {
int IV = index * (PAGE_CACHE_SIZE/bsize) + offset/bsize;
+ int transfer_result;
+
size = PAGE_CACHE_SIZE - offset;
if (size > len)
size = len;
@@ -197,30 +200,35 @@
goto unlock;
kaddr = page_address(page);
flush_dcache_page(page);
- if (lo_do_transfer(lo, WRITE, kaddr + offset, data, size, IV))
- goto write_fail;
+ transfer_result = lo_do_transfer(lo, WRITE, kaddr + offset, data, size, IV);
+ if (transfer_result) {
+ /*
+ * The transfer failed, but we still write the data to
+ * keep prepare/commit calls balanced.
+ */
+ printk(KERN_ERR "loop: transfer error block %ld\n", index);
+ memset(kaddr + offset, 0, size);
+ }
if (aops->commit_write(file, page, offset, offset+size))
goto unlock;
+ if (transfer_result)
+ goto unlock;
data += size;
len -= size;
offset = 0;
index++;
pos += size;
UnlockPage(page);
- deactivate_page(page);
page_cache_release(page);
}
+ up(&mapping->host->i_sem);
return 0;
-write_fail:
- printk(KERN_ERR "loop: transfer error block %ld\n", index);
- ClearPageUptodate(page);
- kunmap(page);
unlock:
UnlockPage(page);
- deactivate_page(page);
page_cache_release(page);
fail:
+ up(&mapping->host->i_sem);
return -1;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)