On Mon, 1 May 2000, Roman V. Shaposhnick wrote:

>   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. 

If we remove the struct file *'s from the interface, it becomes quite
trivial to do this.

> > 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 ?

Holding the file_id in file->private_data is just plain wrong in the
presence of delayed writes (especially on NFS).  Consider the case where a
temporary file is opened and deleted but then used for either read/write
or backing an mmap.  Does it not make sense that when the file is finally
close()'d/munmap()'d by the last user that the contents should be merely
discarded?  If you're tieing the ability to complete write()'s to the
struct file * that was opened, you'll never be able to detect this case
(which is trivial if the file_id token is placed in the inode or address
space).  An address_space should be able to do everything without
requiring a struct file.  Granted, this raises the problem that Al pointed
out about signing RPC requests, but if a copy of the authentication token
is made at open() time into the lower layer for the filesystem, this
problem goes away.

This is important because you can't have a struct file when getting calls
from the page reclaim action in shrink_mmap.

> > 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. 

No, they are not.  address_spaces are a generic way of caching pages of a
vm object.  Files happen to fit nicely into vm objects.

                -ben

Reply via email to