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

From: Trond Myklebust
Date: Sun Oct 08 2006 - 15:22:37 EST


On Sun, 2006-10-08 at 20:54 +0200, Peter Osterlund wrote:
> Trond Myklebust <trond.myklebust@xxxxxxxxxx> 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
--- Begin Message --- 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@xxxxxxxxxx>
---

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) {

--- End Message ---