This procedure takes the buffer passed as a parameter and links it back into the “av”-list.
Any process which is either waiting for the particular buffer or any available buffer is woken up.
Note however that since both “sleeps” (4943, 4955) are at the same priority, if two processes are waiting – one for the particular buffer and one for any buffer – it will be a toss-up which will get it.
By giving the first priority over the second (e.g. by biasing by one) the race should be resolved more satisfactorily. The disadvantage of such a change might be that it could lead to a deadlock situation in certain rather peculiar circumstances.
If an error has occurred e.g. upon reading information into the buffer the information in the buffer may be incorrect. The assignment on line 4883 ensures that the information in the buffer will not be mistakenly retrieved subsequently. The “B_ERROR” flag is set e.g. by “rkstrategy” (5403) and “rkintr” (5467).
To see how this could occur, consider what happens to a buffer when a disk i/o operation is completed:
“rkintr” calls “iodone”;
“iodone” sets the “B_DONE” flag;
“iodone” calls “brelse”;
“brelse” resets the “B_WANTED”, “B_BUSY” and “B_ASYNC” flags but not the “B_DONE” flag;
. . . . . . . . . . . .
“getblk” finds the buffer and calls “notavail”;
“notavail” sets the “B_BUSY” flag;
“bread” (which called “getblk”) finds the “B_DONE” flag set and exits.
Note that buffer headers are removed from the “av”-list by “notavail” and are returned by “brelse”. Buffer headers are moved from one “b”-list to another by “getblk”.