[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: JFFS2 Request For Testing.



On Thu, Feb 22, 2001 at 07:08:14PM +0000, David Woodhouse wrote:
> There's free beer for the first person who tells me why I need the 
> invalidate_inode_pages() in jffs2_file_release() when no other filesystem 
> seems to need it, or why it sometimes gets stuck on unmount, in 
> __wait_on_page() called from invalidate_inodes(). I suspect they're 
> related, and it's a stupid bug on my part.

I just looked at linux/fs/jffs/inode-v23.c and it looks like it really
tries to avoid using the pagecache right now. As the file_write looks
totally synchronous, a lot of my rambling is possibly not appropriate.

In any case, I don't think you would ever need invalidate_inode_pages.
It is used only by some network filesystems to improve consistency.

i.e. the pagecache tries to cache pages, which is what it is there for,
and normally only releases them due to memory pressure. NFS would like
to be given a chance to revalidate these pages sooner than later,
to reduce the window during which updates on the server aren't seen by
applications. So it forces the page cache to throw out anything that
isn't locked or dirty, using invalidate_inode_pages.

Coda used to have something similar, in 2.0/2.2, Coda had a
`cache-aliasing' bug, so that dirty pages as a result of writes through
/coda were associated with the Coda inode, while the cachemanager was
reading from the pages associated with the container inodes. So we
needed to flush dirty pages to disk before we could ship them off to the
server. This was done whenever the inode got released by calling
something like
  generic_osync_inode or
  write_inode_now(i, 1), which writes all dirty pages to disk.
  invalidate_inode_pages, which unmaps all the (now hopefully) clean pages.

Initially I simply removed the invalidate_inode_pages, hmm forgot
whether we actually might have used the more agressive
truncate_inode_pages here. But with the introduction of address-space
sharing in 2.4 (i_mapping) all of this is no longer necessary and we
simply let the VM do it's thing.

In any case here is my understanding of `how the pagecache thingy works',

Normally inodes and pages are kept around for as long as possible, the
kflushd thread slowly write dirty pages back to disk, while the kswapd
thread truncates clean mappings.

Once there are no _dirty_ pages left, and the time comes that we need to
re-use or reclaim the inode, the left over clean pages are simply thrown
out by truncate_inode_pages.

So if you need to flush all the dirty stuff to flash when the last
reference to a file is released, sync the inode, but leave the clean
pages around for the next application that wants to open the file.

If you tend to lose data, check inode->i_nlink, if that is 0 when the
inode is put for the last time, truncate_inode_pages is called which
kills any dirty pages, i.e. pending writes from the pagecache. It should
only ever be 0 for unlinked inodes.

I guess you get dirty pages, but there is nothing that can/will write
them out. When dirty pages are about to be written they are locked (see
mm/filemap.c:filemap_datasync) and queued, once they hit the disk, the
underlying writer unlocks the pages, so for a synchronous write the
queuing party simply waits for the locks to be released (filemap_datawait).
So maybe truncate_inode_pages is appropriate in your case, especially
when the file_write is still as synchronous as in jffs.

Sorry for all the rambling, I hope it turns out to be useful,

    Jan


To unsubscribe from this list: send the line "unsubscribe jffs-dev" in
the body of a message to majordomo@xxxxxxx.com