linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* Re: NFS infinite loop in filemap_fault()
       [not found] <E1JtqLW-0005j5-KU@pomaz-ex.szeredi.hu>
@ 2008-05-08  6:47 ` Miklos Szeredi
  2008-05-08 13:07   ` Josef Bacik
  0 siblings, 1 reply; 4+ messages in thread
From: Miklos Szeredi @ 2008-05-08  6:47 UTC (permalink / raw)
  To: trond.myklebust, npiggin; +Cc: linux-kernel, linux-fsdevel, linux-mm

> Page fault on NFS apparently goes into an infinite loop if the read on
> the server fails.
> 
> I don't understand the NFS readpage code, but the filemap_fault() code
> looks somewhat suspicious:
> 
> 	/*
> 	 * Umm, take care of errors if the page isn't up-to-date.
> 	 * Try to re-read it _once_. We do this synchronously,
> 	 * because there really aren't any performance issues here
> 	 * and we need to check for errors.
> 	 */
> 	ClearPageError(page);
> 	error = mapping->a_ops->readpage(file, page);
> 	page_cache_release(page);
> 
> 	if (!error || error == AOP_TRUNCATED_PAGE)
> 		goto retry_find;
> 
> The comment doesn't seem to match what the it actually does: if
> ->readpage() is asynchronous, then this will just repeat everything,
> without any guarantee that it will re-read once.

This patch fixes it.  It's probably wrong in some subtle way though...

Miklos


---
 mm/filemap.c |    6 ++++++
 1 file changed, 6 insertions(+)

Index: linux.git/mm/filemap.c
===================================================================
--- linux.git.orig/mm/filemap.c	2008-05-08 08:17:22.000000000 +0200
+++ linux.git/mm/filemap.c	2008-05-08 08:19:59.000000000 +0200
@@ -1461,6 +1461,12 @@ page_not_uptodate:
 	 */
 	ClearPageError(page);
 	error = mapping->a_ops->readpage(file, page);
+	if (!error && !PageUptodate(page)) {
+		lock_page(page);
+		if (!PageUptodate(page))
+			error = -EIO;
+		unlock_page(page);
+	}
 	page_cache_release(page);
 
 	if (!error || error == AOP_TRUNCATED_PAGE)

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: NFS infinite loop in filemap_fault()
  2008-05-08  6:47 ` NFS infinite loop in filemap_fault() Miklos Szeredi
@ 2008-05-08 13:07   ` Josef Bacik
  2008-05-08 18:42     ` Miklos Szeredi
  0 siblings, 1 reply; 4+ messages in thread
From: Josef Bacik @ 2008-05-08 13:07 UTC (permalink / raw)
  To: Miklos Szeredi
  Cc: trond.myklebust, npiggin, linux-kernel, linux-fsdevel, linux-mm

On Thu, May 08, 2008 at 08:47:09AM +0200, Miklos Szeredi wrote:
> > Page fault on NFS apparently goes into an infinite loop if the read on
> > the server fails.
> > 
> > I don't understand the NFS readpage code, but the filemap_fault() code
> > looks somewhat suspicious:
> > 
> > 	/*
> > 	 * Umm, take care of errors if the page isn't up-to-date.
> > 	 * Try to re-read it _once_. We do this synchronously,
> > 	 * because there really aren't any performance issues here
> > 	 * and we need to check for errors.
> > 	 */
> > 	ClearPageError(page);
> > 	error = mapping->a_ops->readpage(file, page);
> > 	page_cache_release(page);
> > 
> > 	if (!error || error == AOP_TRUNCATED_PAGE)
> > 		goto retry_find;
> > 
> > The comment doesn't seem to match what the it actually does: if
> > ->readpage() is asynchronous, then this will just repeat everything,
> > without any guarantee that it will re-read once.
> 
> This patch fixes it.  It's probably wrong in some subtle way though...
> 
> Miklos
> 
> 
> ---
>  mm/filemap.c |    6 ++++++
>  1 file changed, 6 insertions(+)
> 
> Index: linux.git/mm/filemap.c
> ===================================================================
> --- linux.git.orig/mm/filemap.c	2008-05-08 08:17:22.000000000 +0200
> +++ linux.git/mm/filemap.c	2008-05-08 08:19:59.000000000 +0200
> @@ -1461,6 +1461,12 @@ page_not_uptodate:
>  	 */
>  	ClearPageError(page);
>  	error = mapping->a_ops->readpage(file, page);
> +	if (!error && !PageUptodate(page)) {

Shouldn't you have (!error || error != AOP_TRUNCATED_PAGE), since the fs can
return AOP_TRUNCATED_PAGE if it needs vfs to try the readpage again?  Things
like OCFS2/GFS2 do this, they send of a lock request and return
AOP_TRUNCATED_PAGE so that when we come back into readpage we are already
holding our lock without blocking while holding the page lock.  Thanks,

Josef

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: NFS infinite loop in filemap_fault()
  2008-05-08 18:42     ` Miklos Szeredi
@ 2008-05-08 18:29       ` Josef Bacik
  0 siblings, 0 replies; 4+ messages in thread
From: Josef Bacik @ 2008-05-08 18:29 UTC (permalink / raw)
  To: Miklos Szeredi
  Cc: jbacik, trond.myklebust, npiggin, linux-kernel, linux-fsdevel, linux-mm

On Thu, May 08, 2008 at 08:42:03PM +0200, Miklos Szeredi wrote:
> > > Index: linux.git/mm/filemap.c
> > > ===================================================================
> > > --- linux.git.orig/mm/filemap.c	2008-05-08 08:17:22.000000000 +0200
> > > +++ linux.git/mm/filemap.c	2008-05-08 08:19:59.000000000 +0200
> > > @@ -1461,6 +1461,12 @@ page_not_uptodate:
> > >  	 */
> > >  	ClearPageError(page);
> > >  	error = mapping->a_ops->readpage(file, page);
> > > +	if (!error && !PageUptodate(page)) {
> > 
> > Shouldn't you have (!error || error != AOP_TRUNCATED_PAGE),
> 
> That would be a rather useless condition (hint: '!error' means 'error == 0')
> 
> > since the fs can
> > return AOP_TRUNCATED_PAGE if it needs vfs to try the readpage again?
> 
> Yep, I din't touch the 'error != 0' codepath.
>

Doh sorry, I hadn't had my coffee yet.

Josef 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: NFS infinite loop in filemap_fault()
  2008-05-08 13:07   ` Josef Bacik
@ 2008-05-08 18:42     ` Miklos Szeredi
  2008-05-08 18:29       ` Josef Bacik
  0 siblings, 1 reply; 4+ messages in thread
From: Miklos Szeredi @ 2008-05-08 18:42 UTC (permalink / raw)
  To: jbacik
  Cc: miklos, trond.myklebust, npiggin, linux-kernel, linux-fsdevel, linux-mm

> > Index: linux.git/mm/filemap.c
> > ===================================================================
> > --- linux.git.orig/mm/filemap.c	2008-05-08 08:17:22.000000000 +0200
> > +++ linux.git/mm/filemap.c	2008-05-08 08:19:59.000000000 +0200
> > @@ -1461,6 +1461,12 @@ page_not_uptodate:
> >  	 */
> >  	ClearPageError(page);
> >  	error = mapping->a_ops->readpage(file, page);
> > +	if (!error && !PageUptodate(page)) {
> 
> Shouldn't you have (!error || error != AOP_TRUNCATED_PAGE),

That would be a rather useless condition (hint: '!error' means 'error == 0')

> since the fs can
> return AOP_TRUNCATED_PAGE if it needs vfs to try the readpage again?

Yep, I din't touch the 'error != 0' codepath.

Miklos

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-05-08 18:42 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <E1JtqLW-0005j5-KU@pomaz-ex.szeredi.hu>
2008-05-08  6:47 ` NFS infinite loop in filemap_fault() Miklos Szeredi
2008-05-08 13:07   ` Josef Bacik
2008-05-08 18:42     ` Miklos Szeredi
2008-05-08 18:29       ` Josef Bacik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox