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.