On Wed, 2011-01-12 at 11:10 -0500, Nick Bowler wrote: > With 2.6.37 (client), opens on NFS with O_CREAT | O_EXCL are > occasionally succeeding when the file already exists, apparently > depending on the state of the filesystem cache. The issue was observed > because mplayer would randomly overwrite its config file... > > Using the test program (./nfsbreak) included in this mail, I can > reproduce it as follows (/home/nbowler is the NFS mount point). No > interesting kernel messages appear on either the client or server > machines during the test: > > % mkdir /home/nbowler/nfsexcl > % ./nfsbreak > nfsbreak: File opened <<< This is OK > % ./nfsbreak > nfsbreak: File exists > % ./nfsbreak > nfsbreak: File exists > % su -c 'echo 2 > /proc/sys/vm/drop_caches' > % ./nfsbreak > nfsbreak: File opened <<< Uhoh! > % ./nfsbreak > nfsbreak: File exists > > Here's the nfsbreak C source: > > #include <stdio.h> > #include <stdlib.h> > #include <fcntl.h> > > int main(void) > { > int fd; > > /* /home/nbowler is the NFS mount point */ > fd = open("/home/nbowler/nfsexcl/nfsexcl", O_WRONLY|O_CREAT|O_EXCL); > if (fd == -1) { > perror("nfsbreak"); > return EXIT_FAILURE; > } > > puts("nfsbreak: File opened"); > return 0; > } > > This is a regression from 2.6.36; bisection implicates the following, > which unfortunately does not revert cleanly. Confirmed. The breakage does not affect NFSv4, but is limited to NFSv3. The following patch should therefore suffice to fix it. Cheers Trond 8<--------------------------------------------------------------------- >From 1ec00b0d759586211447fec763f6c633759e4b3e Mon Sep 17 00:00:00 2001 From: Trond Myklebust <Trond.Myklebust@xxxxxxxxxx> Date: Wed, 12 Jan 2011 13:19:59 -0500 Subject: [PATCH] NFS: Fix NFSv3 exclusive open semantics Commit c0204fd2b8fe047b18b67e07e1bf2a03691240cd (NFS: Clean up nfs4_proc_create()) broke NFSv3 exclusive open by removing the code that passes the O_EXCL flag down to nfs3_proc_create(). This patch reverts that offending hunk from the original commit. Reported-by: Nick Bowler <nbowler@xxxxxxxxxxxxxxxx> Signed-off-by: Trond Myklebust <Trond.Myklebust@xxxxxxxxxx> Cc: stable@xxxxxxxxxx [2.6.37] --- fs/nfs/dir.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index abe4f0c..f9d6a37 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1583,6 +1583,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode, { struct iattr attr; int error; + int open_flags = 0; dfprintk(VFS, "NFS: create(%s/%ld), %s\n", dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); @@ -1590,7 +1591,10 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode, attr.ia_mode = mode; attr.ia_valid = ATTR_MODE; - error = NFS_PROTO(dir)->create(dir, dentry, &attr, 0, NULL); + if ((nd->flags & LOOKUP_CREATE) != 0) + open_flags = nd->intent.open.flags; + + error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, NULL); if (error != 0) goto out_err; return 0; -- 1.7.3.4 -- Trond Myklebust Linux NFS client maintainer NetApp Trond.Myklebust@xxxxxxxxxx www.netapp.com -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html