On Sun, Apr 30, 2000 at 05:58:22PM -0400, Erez Zadok wrote:
> In message <[EMAIL PROTECTED]>, "Roman V. Shaposhnick" writes:
> > On Sun, Apr 30, 2000 at 03:28:18PM +0100, Steve Dodd wrote:
> [...]
> > > But an address_space is (or could be) a completely generic cache. It
> > > might never be associated with an inode, let alone a dentry or file
> > > structure.
> 
> [...]
> >   Thus my opinion is that address_space_operations should remain 
> > file-oriented ( and if there are no good contras take the first argument 
> > of "struct file *" type ). At the same time it is possible to have completely
> > different set of methods around  the same address_space stuff, but from my 
> > point of view this story has nothing in common with how an *existing* 
> > file-oriented interface should work.
> >   
> > Thanks, 
> > Roman.
> 
> If you look at how various address_space ops are called, you'll see enough
> evidence of an attempt to make this interface both a file-based interface
> and a generic cache one (well, at least as far as I understood the code):

  What do you mean by "generic cache" ? From what I see in kernel code I have 
a feeling that this kind of evidence is caused by an abuse of the interface. 
  Why? IMHO, because:
  
     1. In UNIX everything is a file. Thus we need just one type of a 
        cache -- cache for files that can be cached.
     2. File is not an atomic beast and there are four kind of objects 
        that userspace file brings into existence:
         file->dentry->inode->[some phisical entity].
     3. Different kernel subsystems work on different layers of this 
        picture and every relation in it is many-to-one.
     
Thus, considering 1, 2 and 3 we can clearly see that methods of
address_space_operations should be polymorphic in C++ sense. Depending on 
what subsystem calls them they should accept right type of parameters or
speaking it other way they should know on what level of the picture from 
para 2 the are supposed to work. Do you agree with that ? If yes, that 
the question of how to implement that kind  of polymorphism is a simple 
matter of coding style. Yes ?


> (1) generic_file_write (mm/filemap.c) can call ->commit_write with a normal
>     non-NULL file.
> (2) block_symlink (fs/buffer.c) calls ->commit_write with NULL for the file
>     arg.

   But it's the only one example. And moreover it proves that 'block_symlink', 
the only function that uses adress_space_operations directly,
suffers from the problem I've mentioned above. Let's see a typical usecase:

     fs/ext2/namei.c:

           ext2_symlink( struct inode *, struct dentry *, const char *) {
               .....
               err = block_symlink(inode, symname, l);
               .....
           }

What we have here is the subsystem that works on inode->... level -- that's it.
It is not an example of generic caching but just an example of that we can not
do without polymorphic interface.

> So perhaps to satisfy the various needs, all address_space ops should be
  
  Steve, Erez, please, show me an example of where do you need generic caching 
that fits into address_space infrastructure ? I can agree that we do need
some caches but they are not generic at all. For example in every network
based filesystem ( nfs, smbfs, ncpfs, mine ) there is a directory cache.
But all of them use address_space infrastructure with their own methods.
See nfs/dir.c and smbfs/cache.c for amusement. 

> passed a struct file which may be NULL; the individual f/s will have to
> check for it being NULL and deal with it.  (My stacking code already treats
> commit_write this way.)

   Don't get me wrong, but my strong persuasion here is that passing NULLS
when we can not pass meaningful value is yet another example of a huge 
abuse of the interface. 

Thanks,
Roman.

Reply via email to