Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 2657

kernel-2.6.18-194.11.1.el5.src.rpm

From: Steve Dickson <SteveD@redhat.com>
Date: Wed, 26 Mar 2008 16:15:14 -0400
Subject: [nfs] stop sillyrenames and unmounts from racing
Message-id: 47EAAED2.4070801@RedHat.com
O-Subject: [RHEL5.2][bz437302] nfs: sillyrenames crashes system
Bugzilla: 437302

This patch is basically part of the patch set in:

NFS: silly rename races with umounts
http://post-office.corp.redhat.com/archives/rhkernel-list/2007-November/msg00516.html

It was found when then following upstream patch when in:
commit ef818a28fac9bd214e676986d8301db0582b92a9
Author: Steve Dickson <SteveD@redhat.com>
Date:   Thu Nov 8 04:05:04 2007 -0500

    NFS: Stop sillyname renames and unmounts from racing

    Added an active/deactive mechanism to the nfs_server structure
    allowing async operations to hold off umount until the
    operations are done.

    Signed-off-by: Steve Dickson <steved@redhat.com>
    Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.c>

but I could never reproduce the exact problem the attached
patch fixes... Unfortunately UBS could.. :-\ and through
the hard work of Ulrich Obergfell a reproducer was developed.

So that attached patch fixes an oops when a client holds
open a file, another process removes that file and the
.nfsXXX file is remove on the server... Thats basically
what the reproducer does.

I would push to get this in 5.2 since it does fix a crash..

Thanks to Ulrich Obergfell who did do the majority of the work!

steved.

Acked-by: Jeff Layton <jlayton@redhat.com>

diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 29e2a40..0967cd7 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -33,7 +33,6 @@ struct nfs_unlinkdata {
 static void
 nfs_free_unlinkdata(struct nfs_unlinkdata *data)
 {
-	nfs_sb_deactive(NFS_SERVER(data->dir));
 	iput(data->dir);
 	put_rpccred(data->cred);
 	kfree(data->args.name.name);
@@ -118,6 +117,7 @@ static void nfs_async_unlink_release(void *calldata)
 	struct nfs_unlinkdata	*data = calldata;
 
 	nfs_dec_sillycount(data->dir);
+	nfs_sb_deactive(NFS_SERVER(data->dir));
 	nfs_free_unlinkdata(data);
 }