Messages in this thread Patch in this message | | | Date | Fri, 9 Apr 1999 17:23:00 +0200 (MET DST) | From | MOLNAR Ingo <> | Subject | Re: [RFC] set_blocksize() oddity. |
| |
On Fri, 9 Apr 1999, Alexander Viro wrote:
> set_blocksize() seems to do really odd thing: > suppose you have clean buffer (b_count==0, all nice and dandy) with > b_size==foo. > set_blocksize(dev, bar) will leave it on a clean list and will call > remove_from_hash_queue() on it. > set_blocksize(dev,foo) now. Nothing happens with our buffer. > set_blocksize(dev,bar) again and there we go - > remove_from_hash_queue() is called again. > > Repeat until the complete satisfaction (nr_hashed_buffers going negative ;-/) > > Wouldn't remove_from_queues() be the right thing here?
yep, the RAID patch has been doing this for some time:
--- linux/fs/buffer.c.orig Tue Apr 6 16:35:10 1999 +++ linux/fs/buffer.c Wed Apr 7 16:08:12 1999 @@ -663,9 +663,16 @@ continue; if (bh->b_size == size) continue; - bhnext->b_count++; + /* + * We try to completely drop alien-size + * buffers. subtle: we have to protect + * bhnext across the wait and across the + * try_to_free... call because we have + * to keep the 'way forward' on the list. + */ + if (bhnext) + bhnext->b_count++; wait_on_buffer(bh); - bhnext->b_count--; if (bh->b_dev == dev && bh->b_size != size) { clear_bit(BH_Dirty, &bh->b_state); clear_bit(BH_Uptodate, &bh->b_state); @@ -673,11 +680,57 @@ bh->b_flushtime = 0; } remove_from_hash_queue(bh); + + /* + * lets be mega-conservative about what to free: + */ + if ( (bh->b_dev != dev) || + (bh->b_size == size) || + bh->b_count || + buffer_protected(bh) || + buffer_dirty(bh) || + buffer_locked(bh) || + waitqueue_active(&bh->b_wait)) { + if (bhnext) + bhnext->b_count--; + continue; + } + try_to_free_buffers(buffer_page(bh)); + if (bhnext) + bhnext->b_count--; } } }
-- mingo
- 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/
| |