Re: BUG when doing parallel NFS mounts (WAS: Re: Merge window closed: v2.6.19-rc1)

Trond Myklebust
2006-10-08T19:22:20Z

[-- Attachment #1: Type: text/plain, Size: 507 bytes --]

On Sun, 2006-10-08 at 20:54 +0200, Peter Osterlund wrote:
> Trond Myklebust <trond.myklebust@fys.uio.no> writes:
>
> > On Sun, 2006-10-08 at 17:19 +0200, Peter Osterlund wrote:
> > > > kernel BUG at fs/nfs/client.c:352!
> >
> > Does the following patch fix it?
>
> Yes it does. Thanks!

Hmm... There would appear to be another bug there. After breaking out of
the loop, the task state is left as TASK_INTERRUPTIBLE. Let's just
replace the whole thing with a wait_on_event_interruptible.

Cheers,
Trond

[-- Attachment #2: linux-2.6.19-002-fix_nfs_get_client.dif --]
[-- Type: message/rfc822, Size: 1614 bytes --]

From: Trond Myklebust <Trond.Myklebust@netapp.com>
Subject: NFS: Fix typo in nfs_get_client()
Date: Sun, 8 Oct 2006 14:33:24 -0400
Message-ID: <1160335297.11233.11.camel@lade.trondhjem.org>

NFS_CS_INITING > NFS_CS_READY, so instead of waiting for the structure to
get initialised, we currently immediately jump out of the loop without ever
sleeping.

It is also possible to break out of the loop while still in
TASK_INTERRUPTIBLE. Replace by wait_event_interruptible, which doesn't
suffer from these problems.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---

fs/nfs/client.c | 24 +++++-------------------
1 files changed, 5 insertions(+), 19 deletions(-)

diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 6e4e48c..013cdbc 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -322,25 +322,11 @@ found_client:
if (new)
nfs_free_client(new);

- if (clp->cl_cons_state == NFS_CS_INITING) {
- DECLARE_WAITQUEUE(myself, current);
-
- add_wait_queue(&nfs_client_active_wq, &myself);
-
- for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (signal_pending(current) ||
- clp->cl_cons_state > NFS_CS_READY)
- break;
- schedule();
- }
-
- remove_wait_queue(&nfs_client_active_wq, &myself);
-
- if (signal_pending(current)) {
- nfs_put_client(clp);
- return ERR_PTR(-ERESTARTSYS);
- }
+ error = wait_event_interruptible(&nfs_client_active_wq,
+ clp->cl_cons_state != NFS_CS_INITING);
+ if (error < 0) {
+ nfs_put_client(clp);
+ return ERR_PTR(-ERESTARTSYS);
}

if (clp->cl_cons_state < NFS_CS_READY) {