Alexander Viro wrote:
> 
> On Wed, 13 Sep 2000, Daniel Phillips wrote:
> 
> > Alexander Viro wrote:
> > >
> > > On Tue, 12 Sep 2000, Daniel Phillips wrote:
> > > >
> > > > There is a very heavy investment in generic_read/write/mmap - I don't
> > > > want to throw that away.  This is a mod to Ext2, and Ext2 uses these
> > >
> > >         Oh, but these functions don't need to be modified. Change
> > > address_space_operations and they will be happy.
> >
> > I've been doing that all along and it works fine... but only for
> > generic_file_write, not for generic_file_mmap.
> 
> ?
> If your ->readpage() and ->writepage() are working for the last page...
> What's the problem? You don't have to implement your writepage() as a call
> of block_write_full_page().  It just happens to work for UNIX-like and
> no-holes sorts of layout, but there is no reason to do the same thing
> in your case. You probably will find __block_write_full_page() useful
> for handling the case of non-tail pages, but that's about it.

I tried it and you are right.  The functionality I had to reproduce
was just:

  if (err = <my prepare write>) goto err_out;
  memset(page_address(page) + offset, 0, PAGE_CACHE_SIZE - offset);
  flush_dcache_page(page);
  <my commit write>
  kunmap(page);

And the only mysterious are flush_dcache_page and kunmap, both of
which are macros defined for i386 as:

  do { } while (0)

(this shouldn't generate any code, so why is it even there?)  I guess
these are placeholders for code that has to be there on non-i386
architectures.  The point is, it's functionality I have to replicate
in my own block_write_full_page, even though I don't know what it's
for.  Fine, it's only a niggle.  I'm doing it the way you suggest. 
Having perfect block I/O libraries is not essential, just now, today.
:-)

> BTW, before you start exporting the stuff left, right and center - let's
> see how will fs/buffer.c + your helper functions + stuff needed for
> fragments look like. I suspect that we will be able to come up with better
> factorization that way.

I just needed to export one function: create_empty_buffers. 
Grab_cache_page will create/find a file page in the correct form for
the page I/O to handle, but if I want to write onto the page I have to
create the buffers.  Then I can put the one that holds the tail
fragment into the correct state.

A comment on create_empty_buffers: it takes inode as a parameter and
only uses that to set the b_dev.  Shouldn't it just take dev as a
parameter instead of inode?

> > Prepare_write does a lot of stuff associated with actual I/O.  I don't
> > need to start a write here, or a read - just get the data onto the
> > page with the buffers in a consistent state and let ext2_get_block
> 
> Yes, you do. Think of the case when your data partially covers some block.
> ->prepare_write() is just that:
> 
>    Do everything that must be done before copying the data into page.
> 
> If your page is the tail one - well, you need different things done, but
> write() still fits the "prepare + copy_from_user() + let it roll" pattern.
> So make the first part your ->prepare_write() and the last one -
> ->commit_write() and be done with that.

My ->commit_write operates on merged tails, and what we are talking
about now is the unmerge operation, so it doesn't fit.  But you just
helped me find a common factor - read_tail_to_page - consisting of
about 4 lines of code.

I like how it feels using grab_chace_page/create_empty_buffers.  It
makes the page cache do a lot of work for me, using nice simple,
efficient operations to set it up.  I like the way it lets me put the
state-change operations into the part of the code where they make the
most sense instead of stuffing everything into ext2_get_block and then
getting it to work with a bunch of new flags, variables, etc, that can
all get out of synch.

--
Daniel
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]

Reply via email to