Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Sep 2020 02:03:24 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r366241 - stable/11/sys/fs/nfsserver
Message-ID:  <202009290203.08T23OrV083472@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Tue Sep 29 02:03:24 2020
New Revision: 366241
URL: https://svnweb.freebsd.org/changeset/base/366241

Log:
  MFC: r366189
  Bjorn reported a problem where the Linux NFSv4.1 client is
  using an open_to_lock_owner4 when that lock_owner4 has already
  been created by a previous open_to_lock_owner4. This caused the NFS server
  to reply NFSERR_INVAL.
  
  For NFSv4.0, this is an error, although the updated NFSv4.0 RFC7530 notes
  that the correct error reply is NFSERR_BADSEQID (RFC3530 did not specify
  what error to return).
  
  For NFSv4.1, it is not obvious whether or not this is allowed by RFC5661,
  but the NFSv4.1 server can handle this case without error.
  This patch changes the NFSv4.1 (and NFSv4.2) server to handle multiple
  uses of the same lock_owner in open_to_lock_owner so that it now correctly
  interoperates with the Linux NFS client.
  It also changes the error returned for NFSv4.0 to be NFSERR_BADSEQID.
  
  Thanks go to Bjorn for diagnosing this and testing the patch.
  He also provided a program that I could use to reproduce the problem.
  
  PR:		249567
  Reported by:	bf@cebitec.uni-bielefeld.de

Modified:
  stable/11/sys/fs/nfsserver/nfs_nfsdstate.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/fs/nfsserver/nfs_nfsdstate.c
==============================================================================
--- stable/11/sys/fs/nfsserver/nfs_nfsdstate.c	Tue Sep 29 01:56:21 2020	(r366240)
+++ stable/11/sys/fs/nfsserver/nfs_nfsdstate.c	Tue Sep 29 02:03:24 2020	(r366241)
@@ -1799,14 +1799,20 @@ tryagain:
 			}
 			if (!error)
 			    nfsrv_getowner(&stp->ls_open, new_stp, &lckstp);
-			if (lckstp)
+			if (lckstp) {
 			    /*
-			     * I believe this should be an error, but it
-			     * isn't obvious what NFSERR_xxx would be
-			     * appropriate, so I'll use NFSERR_INVAL for now.
+			     * For NFSv4.1 and NFSv4.2 allow an
+			     * open_to_lock_owner when the lock_owner already
+			     * exists.  Just clear NFSLCK_OPENTOLOCK so that
+			     * a new lock_owner will not be created.
+			     * RFC7530 states that the error for NFSv4.0
+			     * is NFS4ERR_BAD_SEQID.
 			     */
-			    error = NFSERR_INVAL;
-			else
+			    if ((nd->nd_flag & ND_NFSV41) != 0)
+				new_stp->ls_flags &= ~NFSLCK_OPENTOLOCK;
+			    else
+				error = NFSERR_BADSEQID;
+			} else
 			    lckstp = new_stp;
 		    } else if (new_stp->ls_flags&(NFSLCK_LOCK|NFSLCK_UNLOCK)) {
 			/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202009290203.08T23OrV083472>