On Tue, 12 Sep 2000, Daniel Phillips wrote:
> After thinking about it last night I saw the correct approach. I need
> a new page cache primitive:
>
> struct page *getpage (struct address_space *mapping, unsigned long
> index)
>
> This is getblk, except for pages. It finds or sets up a page in a
> mapping. It puts buffers on the page if necessary but doesn't cause
> any I/O action.
... and it is absolutely meaningless for many filesystems. Try to define
what it means for NFS, etc.
> I also need another function, and I'll write it right now:
>
> struct buffer_head *page_buffer (struct page *page, int i)
> {
> struct buffer_head *bh = page->buffers;
> while (i--)
> bh = bh->b_this_page;
> return bh;
> }
>
> Getpage isn't as easy as this, but it's not that hard either. A
> gutted version of do_generic_read_page serves the purpose; the result
> is fairly pleasing to the eye (but is for my eyes only until I've
> tested it).
>
> Now I can unmerge this way:
>
> - Fix up various inode fields
> - getpage the tail page from the mapping
> - bread the shared tail block
> - get the appropriate page buffer using page_buffer
> - copy the tail fragment to that buffer and dirty it
>
> I can do this at a high level - the place where the unmerge conditions
> are most easily and accurately detected - as opposed to deep in the
> guts of the page I/O. The page is left in a state that already makes
> sense to read_page, write_page and friends.
Wait a minute. block_*_page is pure library stuff. VFS doesn't use it - it
just happens to be common for many filesystems, thus it had been placed
into fs/buffer.c.
There is absolutely no need to make it work in your case. Think of it that
way: we have VFS/VM, we have filesystems and we have (imaginary)
libblockfs.a that is often used by filesystems. They are not obliged to
use it - it's just a collection of helper functions.
Make your expanding truncate() call ->prepare_write() and you are done -
just put all unmerging into your instance of ->prepare_write(). That's it.
Nothing forces you to use block_prepare_write() there.
IOW, you are fighting imaginary problem. I'm not saying that these
functions could not use a cleanup. They certainly could and your
tailmerging stuff may be good for that - it will show what other helper
functions are needed and it may help to factor this stuff better. Ditto
for fragments handling, BTW. But these functions are _not_ primitives.
They certainly do not belong to address_space or inode interface.
Maybe separating helpers into fs/libfs would be a good idea. Or not - that
would pollute the kernel namespace...
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]