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]

Reply via email to