The sync_request_done function is called after each sync I/O request completes regardless of the error outcome.
See end_sync_write and the "!sum_bhs" case a few lines above the patch location for references. If sync_request_done is not called the accounting is not updated and sooner or later things will hang. The R1BH_Uptodate not set case (read I/O error) does not do this and the problem occurs.
mark
--- raid1.c.orig 2004-03-23 17:18:29.000000000 -0700 +++ raid1.c 2004-03-23 17:18:48.000000000 -0700 @@ -1251,6 +1251,7 @@ */ printk (IO_ERROR, partition_name(bh->b_dev), bh->b_blocknr); + sync_request_done(bh->b_blocknr, conf); md_done_sync(mddev, bh->b_size>>9, 0); raid1_free_buf(r1_bh); }