On Mon, May 01, 2000 at 01:35:52PM +0100, Steve Dodd wrote:
> On Mon, May 01, 2000 at 01:41:43AM +0400, Roman V. Shaposhnick wrote:
> > 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.
> >
> > Ok, ok, hold on, it is filemap.c where all this stuff is defined, I guess
> > the name gives a hint about that it definitely is associated with some kind
> > of file machinery. But I understand what you mean. See my comments below.
>
> OK, more precisely, an address_space could (and IMO *should*) be a generic
> /page/ cache. Anything that's caching multiple pages of data indexed by an
> offset could use it. Then the page cache can sync pages, steal pages, etc.,
> etc., without having to know what the pages are being used for. At the moment,
> it's only used for inode data pages, but with some small changes it can be
> much more useful - and I believe this was Al's original intention.
I see what you mean. And I completely agree with only one exception: we
should not use and we should not think of address_space as a generic cache
till we implement the interface for address_space_operations that:
1. can work with *any* type of host object
2. at the same time can work with stackable or derived ( in C++
terminology ) host objects like file->dentry->inode->phis.
3. and has a reasonable and kludge-free specification.
I agree that providing such interface to the address_space will simplify
things a lot, but for now I see no evidence of somebody doing this.
As for, Al, I guess that only he could ever tell us what he is doing. But he
keeps silence.
> >
> > > For example, I've got some experimental NTFS code which caches all metadata
> > > in the page cache using the address_space stuff.
> [..]
>
> > IMHO, you are going wrong direction here. My point is that sometimes
> > we would like to see address_space stuff as generic cache but it is not.
>
> I disagree; at the moment the interface is not generic, but my belief is
> that it can be made so with only small changes to existing code. However,
> I haven't looked at all existing code yet. NFS is doing something odd, and I
> also should look at your code if that's possible (is it available somewhere?)
No but I hope you will be able to see it in 2.5. btw, if you would like
to see some parts that you are interested at I can send you early pre-alpha.
> > Or being more precise it is a generic cache from the generic perspective,
> > but when you try to use generic functions from filemap.c you are bound to
> > treat this beast as a file cache.
>
> The page cache at the moment is mostly used for caching inode data, hence
> the name "filemap.c".
Steve, please read my previous e-mail about what I consider file-cache and
what generic cache.
> [..]
> > 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.
>
> Hmm. Take ->readpage() for example. It is used to fill a page which "belongs"
> to an object. That object is referenced in page->mapping->host. For inode
> data, the host is the inode structure. When should readpage() ever need to
> see anything other than the object to which the pages belong? It doesn't make
> sense (to me).
I disagree; and mainly because sometimes it is hard to tell where object
"begins" and where it "ends". Complex objects are often derived from
simple and it is a very common practice to use the highest level available
for the sake of optimization. E.g. in Linux userspace file is built around
dentry which in turn is built around inode etc. Can we say that file do not
include inode directly ? Yes. Can we say that file do not include inode at
all? No.
Let me show you an example. Consider, that:
1. you have a network-based filesystem with a state oriented protocol.
2. to do something with a file you need a special pointer to it called
file_id.
3. before reading/writing to/from a file you should open its file_id
for reading, writing or both. After you open file_id you can only
read/write from/to it but you can not do nothing more.
I guess you will agree with me that the best place for "opened" file_id
is a file->private_data ? Ok. Now the question is, how can I access opened
file_id if all methods ( readpage, writepage, prepare_write and commit_write )
get the first argument of type inode ?
Now imagine that we have interface with all properties described above, than
it would be up to the each method to decide how to handle the particular
situation. I mean that in general it is possible to call them with the first
argument being "struct file *" ( because that's the way generic_file_read and
generic_file_write work ) but if suddenly we realize that the only data
available is inode -- that's fine because we know that this is a rare case and
can waste some additional network capacity to handle it.
> If you think you need to access other data, it should either
> be accessible through the host object, or you have used the wrong host object.
Steve, unfortunately relations are not always one-to-one, but tends to be
many-to-one. That's the problem.
> Inode data pages are per-inode, not per-dentry or per-file-struct.
Frankly, inode data pages are file pages, because it is userspace files we
care of. Nothing more, nothing less.
Thanks,
Roman.