Messages in this thread Patch in this message |  | | Subject | Re: floppy access causes crash in 2.1.3 | Date | Thu, 17 Oct 1996 23:35:30 +0200 | From | Alain Knaff <> |
| |
>I got a couple of crashes running make zdisk the other day under 2.1.3 and >again it's crashing when I'm trying to make redhat 4.0 boot floppies. I >don't have the problem under 2.0.21. (same floppies and everything)
ok, I think I found the problem:
Starting from 2.1.3 on, the sync_buffers routine no longer scans all buffer lists, but only the "dirty" (modified) buffer list. The result of this is that fsync is no longer synchronous, i.e. it is no longer guaranteed that all buffers have been written to disk when fsync returns. This affects the floppy driver very badly. Indeed, in order to allow sharing with ftape, the floppy driver releases its IRQ and DMA when nobody has the device open. However, it can't handle any I/O requests in this state. In order to make sure that it doesn't get any "deferred write" requests in this state, it fsyncs its buffers whenever a file descriptor to a floppy device is closed. Usually this ensures that all outstanding writes to the floppy are done at close time. Unfortunatelym this no longer works, and the write requests which happen after close crash the floppy driver.
The following patch should fix the problem:
Regards,
Alain
diff -ur 2.1.4/linux/fs/buffer.c linux/fs/buffer.c --- 2.1.4/linux/fs/buffer.c Thu Oct 17 21:47:38 1996 +++ linux/fs/buffer.c Thu Oct 17 21:22:55 1996 @@ -210,7 +210,31 @@ next->b_count--; retry = 1; } - + + repeat2: + bh = lru_list[BUF_LOCKED]; + if (!bh) + break; + for (i = nr_buffers_type[BUF_LOCKED]*2 ; i-- > 0 ; bh = next) { + if (bh->b_list != BUF_LOCKED) + goto repeat2; + next = bh->b_next_free; + if (!lru_list[BUF_LOCKED]) + break; + if (dev && bh->b_dev != dev) + continue; + if (buffer_locked(bh)) { + /* Buffer is locked; skip it unless wait is + requested AND pass > 0. */ + if (!wait || !pass) { + retry = 1; + continue; + } + wait_on_buffer (bh); + goto repeat2; + } + } + /* If we are waiting for the sync to succeed, and if any dirty blocks were written, then repeat; on the second pass, only wait for buffers being written (do not pass to write any
|  |