So the start:
When we write buffers from the buffer cache we clear buffer_dirty
but not PageDirty
So try_to_free_buffers() will mark any page with clean buffer_heads
that is not clean itself clean.
The ramdisk set pages dirty to keep them from being removed from the
page cache, just like ramfs.
Unfortunately when those dirty ramdisk pages get buffers on them and
those buffers all go clean and we are trying to reclaim buffer_heads
we drop those pages from the page cache. Ouch!
We can fix the ramdisk by setting making certain that buffer_heads
on ramdisk pages stay dirty as well. The problem is this breaks
filesystems like reiserfs and ext3 that expect to be able to make
buffer_heads clean sometimes.
There are other ways to solve this for ramdisks, such as changing
where ramdisks are stored. However fixing the ramdisks this way
still leaves the general problem that there are other paths to the
filesystem metadata buffers, and those other paths cause the code
to be complicated and buggy.
So I'm trying to see if we can untangle this Gordian knot, so the
code because more easily maintainable.
To make the buffer cache a helper library instead of require
infrastructure, it looks like two things need to happen.
- Move metadata buffer heads off block devices page cache entries,
- Communicate the mappings of data pages to block device sectors
in a generic way without buffer heads.
How we ultimately fix the ramdisk tends to depend on how we untangle
the buffer head problem. Right now the only simple solution is to
suppress try_to_free_buffers, which is a bit ugly. We can also come
up with a completely separate store for the pages in the buffer cache
but if we wind up moving the metadata buffer heads anyway then that
should not be necessary.
Eric
-