All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@osdl.org>
To: David Howells <dhowells@redhat.com>
Cc: dhowells@redhat.com, torvalds@osdl.org, steved@redhat.com,
	trond.myklebust@fys.uio.no, aviro@redhat.com,
	linux-fsdevel@vger.kernel.org, linux-cachefs@redhat.com,
	nfsv4@linux-nfs.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 13/14] FS-Cache: Release page->private in failed readahead [try #8]
Date: Fri, 12 May 2006 07:11:00 -0700	[thread overview]
Message-ID: <20060512071100.5c5d52e9.akpm@osdl.org> (raw)
In-Reply-To: <11334.1147437245@warthog.cambridge.redhat.com>

David Howells <dhowells@redhat.com> wrote:
>
> Andrew Morton <akpm@osdl.org> wrote:
> 
> > The above code is identical to the below code, so a new helper function
> > would be appropriate.
> > ...
> > I think the above will be called against an unlocked page, in which case
> > the ->releasepage() implementation might choose to go BUG, or something.
> > I suppose locking the page here will suffice.
> 
> I'll move that bit of code into a helper function, along with the
> page_cache_release() and call it from both places.  I'll also call
> try_to_release_page() as you suggest rather than going directly.  I'll lock
> the page too:
> 
> static inline void read_cache_pages_release_page(struct address_space *mapping,
> 						 struct page *page)
> {
> 	if (PagePrivate(page)) {
> 		page->mapping = mapping;
> 		SetPageLocked(page);

	if (TestSetPagLocked(page))
		BUG();

would make me more comfortable..

> 		try_to_release_page(page, GFP_KERNEL);
> 		page->mapping = NULL;
> 	}
> 
> 	page_cache_release(page);
> }
> 
> > But it all seems a bit abusive of what ->releasepage() is supposed to do.
> 
> Where else should I do it?  I'm using releasepage() to break the association
> that the cache has made with a page.  If I don't do this, the cache may wind
> up retaining metadata unnecessarily.
> 
> I suppose I could add another address space op to do this, and have
> page_cache_release() check page->mapping->a_ops->destroypage(), and then force
> the mapping to be passed through to page_cache_release() where necessary.
> 
> > add_to_page_cache() won't set PagePrivate() anyway, so what point is there
> > in the first hunk?
> 
> The PagePrivate() bit is already set before read_cache_pages() is called.
> What happens is that the cache is invoked first: it sets to read any pages it
> can satisfy from the data it holds, and marks those pages for which it has
> allocated buffer space; the unsatisfied pages are then returned to NFS, which
> then calls read_cache_pages() to invoke readpage() serially - but if any pages
> get discarded, the cache metadata _also_ needs to be discarded.
> 
> > For the second hunk, is it not possible to do this cleanup in the callback
> > function?
> 
> Which callback function?

I was referring to the filler_t thingy.  Is it not possible to get control
of that?

>  The cleanup must be done before the page is returned
> to the page allocator, and since that is performed by read_cache_pages(), in
> read_cache_pages() the cleanup must be done.  The other option is to not use
> read_cache_pages(), I suppose.

hm.  There's a whole pile of stuff in this email which you're the only
person in the world who knows.  But a lot of people need to be able to
read, understand and work upon mm/readahead.c without having to intimately
understand the internals of cachefs behaviour.

So please, can we have some comments in there which describe the new
behaviour in a manner sufficient for a maintainer to follow so people don't
break your stuff?

> > If read_cache_pages() needs this treatment, shouldn't we also do it in
> > read_pages()?
> 
> Because read_pages() doesn't give the filesystem a chance to know about pages
> between it allocating them and it releasing them when add_to_page_cache()
> fails.  Although it calls readpage(), if that fails it should clean up for
> itself.
> 
> read_cache_pages() does not allocate the pages for itself.  It's called from a
> filesystem's readpages() op, which gives the filesystem ample opportunity to
> know about the pages that read_pages() doesn't afford it.
> 
> > And in mpage_readpages()?
> 
> mpage_readpages() uses PG_private for its own purposes, and so keying on that
> for any purpose but holding buffers is impossible, and if mpage_readpages()
> needs to clean those up, it must do so already.

OK.

> However, you've raised a good point, and it's one that'll need to be solved if
> I want to do caching on ISOFS and suchlike.
> 
> > Again, as this appears to be some special treatment for cachefs wouldn't it
> > be better to keep this special handling within cachefs?
> 
> How?  CacheFS can't practically monitor the pages it has been told about just
> in case they've been given back.  The netfs has to drive that end of things.
> 
> I could copy read_cache_pages() and place that in fscache and change it
> thusly, but there's no requirement that a netfs should use PG_private for
> marking cached pages - that just happens to be the way I've done it in NFS and
> AFS, but it can't be the way I do it in ISOFS.
> 
> Out of interest, why do we need PG_private to say there's something in
> page->private?  Can't it just be assumed either that if page->private is
> non-zero or that if a_ops->releasepage() is non-NULL, then we need to
> "release" the page?

page->private is an unsigned long, not a pointer.  The core kernel hence
cannot determine from its value whether or not it is live.  For example, the fs
might choose to treat it as a bitmap of which-blocks-are-uptodate and
which-blocks-are-dirty.

  reply	other threads:[~2006-05-12 14:14 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-05-10 16:01 [PATCH 00/14] Permit filesystem local caching and NFS superblock sharing [try #8] David Howells
2006-05-10 16:01 ` David Howells
2006-05-10 16:01 ` [PATCH 01/14] NFS: Permit filesystem to override root dentry on mount " David Howells
2006-05-10 16:01 ` [PATCH 02/14] NFS: Permit filesystem to perform statfs with a known root dentry " David Howells
2006-05-12 10:51   ` [PATCH 02/14] NFS: Permit filesystem to perform statfs with a known root dentry [try #9] David Howells
2006-05-15  5:46     ` Nathan Scott
2006-05-15  5:46       ` Nathan Scott
2006-05-10 16:01 ` [PATCH 03/14] NFS: Abstract out namespace initialisation [try #8] David Howells
2006-05-10 16:01 ` [PATCH 04/14] NFS: Add dentry materialisation op " David Howells
2006-05-10 16:01 ` [PATCH 05/14] NFS: Split fs/nfs/inode.c into inode, superblock and namespace bits " David Howells
2006-05-10 16:01 ` [PATCH 06/14] NFS: Share NFS superblocks per-protocol per-server per-FSID " David Howells
2006-05-10 16:23   ` Christoph Hellwig
2006-05-10 16:44     ` David Howells
2006-05-10 16:41   ` [PATCH 06/14] NFS: Share NFS superblocks per-protocol per-server per-FSID [try #9] David Howells
2006-05-10 16:01 ` [PATCH 07/14] FS-Cache: Provide a filesystem-specific sync'able page bit [try #8] David Howells
2006-05-10 16:01 ` [PATCH 08/14] FS-Cache: Add notification of page becoming writable to VMA ops " David Howells
2006-05-10 16:01 ` [PATCH 09/14] FS-Cache: Avoid ENFILE checking for kernel-specific open files " David Howells
2006-05-10 16:01 ` [PATCH 10/14] FS-Cache: Generic filesystem caching facility " David Howells
2006-05-10 16:01 ` [PATCH 11/14] FS-Cache: Make kAFS use FS-Cache " David Howells
2006-05-10 16:01 ` [PATCH 12/14] FS-Cache: CacheFiles: A cache that backs onto a mounted filesystem " David Howells
2006-05-10 16:01 ` [PATCH 13/14] FS-Cache: Release page->private in failed readahead " David Howells
2006-05-11 17:40   ` Andrew Morton
2006-05-11 17:40     ` Andrew Morton
2006-05-12 12:34     ` David Howells
2006-05-12 12:34       ` David Howells
2006-05-12 14:11       ` Andrew Morton [this message]
2006-05-12 16:23         ` David Howells
2006-05-12 16:23           ` David Howells
2006-05-12 12:49   ` [PATCH 13/14] FS-Cache: Release page->private in failed readahead [try #9] David Howells
2006-05-10 16:01 ` [PATCH 14/14] NFS: Use local caching [try #8] David Howells

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20060512071100.5c5d52e9.akpm@osdl.org \
    --to=akpm@osdl.org \
    --cc=aviro@redhat.com \
    --cc=dhowells@redhat.com \
    --cc=linux-cachefs@redhat.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nfsv4@linux-nfs.org \
    --cc=steved@redhat.com \
    --cc=torvalds@osdl.org \
    --cc=trond.myklebust@fys.uio.no \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.