Date: Sun, 21 Jun 2015 10:30:34 -0400 (EDT) From: Rick Macklem <rmacklem@uoguelph.ca> To: "alex.burlyga.ietf alex.burlyga.ietf" <alex.burlyga.ietf@gmail.com> Cc: freebsd-fs@freebsd.org Subject: Re: [nfs][client] - Question about handling of the NFS3_EEXIST error in SYMLINK rpc Message-ID: <1969046464.61534041.1434897034960.JavaMail.root@uoguelph.ca> In-Reply-To: <CA%2BJhTNTSC-xPVdpUGcQemVMLUwuQB6D8-3d2HD6WjU%2Bjd1SMNQ@mail.gmail.com>
index | next in thread | previous in thread | raw e-mail
[-- Attachment #1 --] Alex Burlyga wrote: > Hi, > > NFS client code in nfsrpc_symlink() masks server returned NFS3_EEXIST > error > code > by returning 0 to the upper layers. I'm assuming this was an attempt > to > work around > some server's broken replay cache out there, however, it breaks a > more > common > case where server is returning EEXIST for legitimate reason and > application > is expecting this error code and equipped to deal with it. > > To fix it I see three ways of doing this: > * Remove offending code > * Make it optional, sysctl? > * On NFS3_EEXIST send READLINK rpc to make sure symlink content is > right > > Which of the ways will maximize the chances of getting this fix > upstream? > I've attached a patch for testing/review that does essentially #2. It has no effect on trivial tests, since the syscall does a Lookup before trying to create the symlink and fails with EEXIST. Do you have a case where competing clients are trying to create the symlink or something like that, which runs into this? Please test the attached patch, since I don't know how to do that, rick > One more point, old client circa FreeBSD 7.0 does not exhibit this > problem. > > Alex > _______________________________________________ > freebsd-fs@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-fs > To unsubscribe, send any mail to "freebsd-fs-unsubscribe@freebsd.org" > [-- Attachment #2 --] --- fs/nfsclient/nfs_clrpcops.c.sav2 2015-06-21 09:27:38.640947000 -0400 +++ fs/nfsclient/nfs_clrpcops.c 2015-06-21 09:53:42.723085000 -0400 @@ -46,6 +46,13 @@ __FBSDID("$FreeBSD: head/sys/fs/nfsclien #include "opt_inet6.h" #include <fs/nfs/nfsport.h> +#include <sys/sysctl.h> + +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); }help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1969046464.61534041.1434897034960.JavaMail.root>
