From owner-svn-src-all@freebsd.org Fri Jul 3 01:15:22 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id F2012993DDC; Fri, 3 Jul 2015 01:15:21 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D6783162C; Fri, 3 Jul 2015 01:15:21 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.14.9/8.14.9) with ESMTP id t631FLkm020676; Fri, 3 Jul 2015 01:15:21 GMT (envelope-from rmacklem@FreeBSD.org) Received: (from rmacklem@localhost) by repo.freebsd.org (8.14.9/8.14.9/Submit) id t631FL6J020675; Fri, 3 Jul 2015 01:15:21 GMT (envelope-from rmacklem@FreeBSD.org) Message-Id: <201507030115.t631FL6J020675@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: rmacklem set sender to rmacklem@FreeBSD.org using -f From: Rick Macklem Date: Fri, 3 Jul 2015 01:15:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r285066 - head/sys/fs/nfsclient X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 03 Jul 2015 01:15:22 -0000 Author: rmacklem Date: Fri Jul 3 01:15:21 2015 New Revision: 285066 URL: https://svnweb.freebsd.org/changeset/base/285066 Log: Alex Burlyga reported a POLA violation for the new NFS client as compared to the old NFS client via email to the freebsd-fs@ mailing list. For the new client, when multiple clients attempted to create a symbolic link concurrently, more that one client would report success instead of EEXIST. This was caused by code in the new client that mapped EEXIST to OK assuming it was caused by a retried RPC request. Since the old client did not do this, the patch defaults to the old behaviour and permits the new behaviour to be enabled via a sysctl. Reported by: alex.burlyga.ietf@gmail.com Tested by: alex.burlyga.ietf@gmail.com MFC after: 2 weeks Modified: head/sys/fs/nfsclient/nfs_clrpcops.c Modified: head/sys/fs/nfsclient/nfs_clrpcops.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clrpcops.c Fri Jul 3 00:37:16 2015 (r285065) +++ head/sys/fs/nfsclient/nfs_clrpcops.c Fri Jul 3 01:15:21 2015 (r285066) @@ -46,6 +46,13 @@ __FBSDID("$FreeBSD$"); #include "opt_inet6.h" #include +#include + +SYSCTL_DECL(_vfs_nfs); + +static int nfsignore_eexist = 0; +SYSCTL_INT(_vfs_nfs, OID_AUTO, ignore_eexist, CTLFLAG_RW, + &nfsignore_eexist, 0, "NFS ignore EEXIST replies for mkdir/symlink"); /* * Global variables @@ -2530,8 +2537,12 @@ nfsrpc_symlink(vnode_t dvp, char *name, mbuf_freem(nd->nd_mrep); /* * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry. + * Only do this if vfs.nfs.ignore_eexist is set. + * Never do this for NFSv4.1 or later minor versions, since sessions + * should guarantee "exactly once" RPC semantics. */ - if (error == EEXIST) + if (error == EEXIST && nfsignore_eexist != 0 && (!NFSHASNFSV4(nmp) || + nmp->nm_minorvers == 0)) error = 0; return (error); } @@ -2550,10 +2561,12 @@ nfsrpc_mkdir(vnode_t dvp, char *name, in nfsattrbit_t attrbits; int error = 0; struct nfsfh *fhp; + struct nfsmount *nmp; *nfhpp = NULL; *attrflagp = 0; *dattrflagp = 0; + nmp = VFSTONFS(vnode_mount(dvp)); fhp = VTONFS(dvp)->n_fhp; if (namelen > NFS_MAXNAMLEN) return (ENAMETOOLONG); @@ -2605,9 +2618,13 @@ nfsrpc_mkdir(vnode_t dvp, char *name, in nfsmout: mbuf_freem(nd->nd_mrep); /* - * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry. + * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry. + * Only do this if vfs.nfs.ignore_eexist is set. + * Never do this for NFSv4.1 or later minor versions, since sessions + * should guarantee "exactly once" RPC semantics. */ - if (error == EEXIST) + if (error == EEXIST && nfsignore_eexist != 0 && (!NFSHASNFSV4(nmp) || + nmp->nm_minorvers == 0)) error = 0; return (error); }