From dcb19c38864409a593c6cdcabc6b0c12cd14c4c8 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 20 Oct 2016 23:53:16 +0000 Subject: [PATCH] A problem w.r.t. interoperation between the FreeBSD NFSv4.1 server with delegations enabled and the Linux NFSv4.1 client was reported in reviews.freebsd.org/D7891. I believe that the FreeBSD server behaviour conforms to the RFC and that the Linux client has a bug. Therefore, I do not think the proposed patch is appropriate. When nfsrv_writedelegifpos is non-zero, the FreeBSD server will issue a write delegation for a read open if possible. The Linux client then erroneously assumes that the credentials used for the read open can write the file. This patch reverses the default value for nfsrv_writedelegifpos to 0 so that the default behaviour is Linux compatible and adds a sysctl that can be used to set nfsrv_writedelegifpos. This change should only affect users that are mounting a FreeBSD server with delegations enabled (they are not enabled by default) with a Linux NFSv4.1 client mount. Reported by: fatih.acar@gandi.net Tested by: fatih.acar@gandi.net MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D7891 --- sys/fs/nfsserver/nfs_nfsdstate.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index 1b90d021d6c..c60f6436c6f 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -70,6 +70,11 @@ SYSCTL_INT(_vfs_nfsd, OID_AUTO, v4statelimit, CTLFLAG_RWTUN, &nfsrv_v4statelimit, 0, "High water limit for NFSv4 opens+locks+delegations"); +static int nfsrv_writedelegifpos = 0; +SYSCTL_INT(_vfs_nfsd, OID_AUTO, writedelegifpos, CTLFLAG_RW, + &nfsrv_writedelegifpos, 0, + "Issue a write delegation for read opens if possible"); + /* * Hash lists for nfs V4. */ @@ -80,7 +85,6 @@ struct nfssessionhash *nfssessionhash; static u_int32_t nfsrv_openpluslock = 0, nfsrv_delegatecnt = 0; static time_t nfsrvboottime; -static int nfsrv_writedelegifpos = 1; static int nfsrv_returnoldstateid = 0, nfsrv_clients = 0; static int nfsrv_clienthighwater = NFSRV_CLIENTHIGHWATER; static int nfsrv_nogsscallback = 0;