Re: Race in buffer code (Was Re: move block #A to block #B on a given device.)

Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz)
Mon, 8 Nov 1999 16:20:05 +0100 (CET)


On Mon, 8 Nov 1999, Tigran Aivazian wrote:
> On Fri, 5 Nov 1999, Mikulas Patocka wrote:
> > There is another - more severe - destruction case: breada. On filesystems
> > that use breada it can smash buffers randomly!
>
> The whole point of having buffer cache (apart from some performance
> benefit of caching) is to serialize io, i.e. getblk() returns a locked
> buffer

getblk doesn't lock buffer. It only increments reference count. The caller
of getblk is suposed to do any locking.

> and until the caller is done with it nothing can do io on that
> block.

There can be pending read request if
- user reads device directly, or
- filesystem uses asynchonous i/o (breada or ll_rw_block)

> So there are (hopefully) no races of the kind you described in
> current or future implementation of buffer cache (as long as it does not
> deviate from old good SVR3 thing described in Bach's book).

Look at the code:

struct buffer_head * getblk(kdev_t dev, int block, int size)
{
struct buffer_head * bh;
int isize;
repeat:
bh = get_hash_table(dev, block, size);
if (bh) {
if (!buffer_dirty(bh)) {
bh->b_flushtime = 0;
}
return bh;
}
...

There is not (and should not be) any serialization in getblk. The
filesystem should call wait_on_buffer(bh), after getblk()ing, but it
doesn't.

Mikulas Patocka

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/