git: 774a36851e0e - main - nfsd: fix NFS server for ERELOOKUP
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=774a36851e0e562a6428e5ac45fbfb2b23f3f58c commit 774a36851e0e562a6428e5ac45fbfb2b23f3f58c Author: Rick Macklem AuthorDate: 2021-01-01 21:55:51 + Commit: Rick Macklem CommitDate: 2021-01-01 21:55:51 + nfsd: fix NFS server for ERELOOKUP r367672 modified UFS such that certain VOPs, such as VOP_CREATE() will intermittently return ERELOOKUP. When this happens, the entire system call, or NFS operation in the case of the NFS server, must be redone. This patch adds that support to the NFS server by rolling back the state of the NFS request arguments and NFS reply arguments mbuf lists to the condition they were in before the operation and then redoing the operation. Tested by: pho Reviewed by:kib Differential Revision: https://reviews.freebsd.org/D27875 --- sys/fs/nfs/nfs_var.h | 2 ++ sys/fs/nfsserver/nfs_nfsdport.c | 4 +-- sys/fs/nfsserver/nfs_nfsdsocket.c | 63 ++- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index a3c53e80ace3..0a1fe3ce053d 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -753,6 +753,8 @@ int nfsvno_rmxattr(struct nfsrv_descript *, struct vnode *, char *, struct ucred *, struct thread *); int nfsvno_listxattr(struct vnode *, uint64_t, struct ucred *, struct thread *, u_char **, uint32_t *, bool *); +void nfsm_trimtrailing(struct nfsrv_descript *, struct mbuf *, char *, int, +int); /* nfs_commonkrpc.c */ int newnfs_nmcancelreqs(struct nfsmount *); diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index e867ecc350b4..e9a9443dc08c 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -146,8 +146,6 @@ static int nfsrv_dsremove(struct vnode *, char *, struct ucred *, NFSPROC_T *); static int nfsrv_dssetacl(struct vnode *, struct acl *, struct ucred *, NFSPROC_T *); static int nfsrv_pnfsstatfs(struct statfs *, struct mount *); -static void nfsm_trimtrailing(struct nfsrv_descript *, struct mbuf *, -char *, int, int); int nfs_pnfsio(task_fn_t *, void *); @@ -6564,7 +6562,7 @@ out: /* * Trim trailing data off the mbuf list being built. */ -static void +void nfsm_trimtrailing(struct nfsrv_descript *nd, struct mbuf *mb, char *bpos, int bextpg, int bextpgsiz) { diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c index a9fdc7fa8be3..1a54914fc9dc 100644 --- a/sys/fs/nfsserver/nfs_nfsdsocket.c +++ b/sys/fs/nfsserver/nfs_nfsdsocket.c @@ -534,9 +534,21 @@ nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram, u_char *tag, int taglen, { int error = 0, lktype; vnode_t vp; - mount_t mp = NULL; + mount_t mp; struct nfsrvfh fh; struct nfsexstuff nes; + struct mbuf *md; + char *dpos; + + /* +* Save the current position in the request mbuf list so +* that a rollback to this location can be done upon an +* ERELOOKUP error return from an RPC function. +*/ + md = nd->nd_md; + dpos = nd->nd_dpos; +tryagain: + mp = NULL; /* * Get a locked vnode for the first file handle @@ -634,6 +646,21 @@ nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram, u_char *tag, int taglen, if (mp != NULL && nfsrv_writerpc[nd->nd_procnum] != 0) vn_finished_write(mp); + if (error == 0 && nd->nd_repstat == ERELOOKUP) { + /* +* Roll back to the beginning of the RPC request +* arguments. +*/ + nd->nd_md = md; + nd->nd_dpos = dpos; + + /* Free the junk RPC reply and redo the RPC. */ + m_freem(nd->nd_mreq); + nd->nd_mreq = nd->nd_mb = NULL; + nd->nd_repstat = 0; + goto tryagain; + } + nfsrvd_statend(nfsv3to4op[nd->nd_procnum], /*bytes*/ 0, /*now*/ NULL, /*then*/ &start_time); } @@ -691,6 +718,9 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag, static u_int64_t compref = 0; struct bintime start_time; struct thread *p; + struct mbuf *mb, *md; + char *bpos, *dpos; + int bextpg, bextpgsiz; p = curthread; @@ -1045,6 +1075,20 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag, break; } } + + /* +* Save the current positions in the mbuf lists so +
git: dc78533a5204 - main - nfsd: fix NFSv4.0 seqid handling for ERELOOKUP
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=dc78533a5204ae487bf9b27badb134ffa40733ab commit dc78533a5204ae487bf9b27badb134ffa40733ab Author: Rick Macklem AuthorDate: 2021-01-01 22:21:51 + Commit: Rick Macklem CommitDate: 2021-01-01 22:21:51 + nfsd: fix NFSv4.0 seqid handling for ERELOOKUP Commit 774a36851e0e fixed the NFS server so that it could handle ERELOOKUP returns from VOP calls by redoing the operation/RPC. However, for NFSv4.0, redoing an Open would increment the open_owner's seqid multiple times, breaking the protocol. This patch sets a new flag called ND_ERELOOKUP on the RPC when a redo is in progress. Then the code that increments the seqid avoids the seqid increment/check when the flag is set, since it indicates this has already been done for the Open. --- sys/fs/nfs/nfs.h | 1 + sys/fs/nfsserver/nfs_nfsdsocket.c | 2 ++ sys/fs/nfsserver/nfs_nfsdstate.c | 5 + 3 files changed, 8 insertions(+) diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h index f6acb807fc6e..44b6042a2ce7 100644 --- a/sys/fs/nfs/nfs.h +++ b/sys/fs/nfs/nfs.h @@ -721,6 +721,7 @@ struct nfsrv_descript { #defineND_EXTLS0x80 #defineND_EXTLSCERT0x100 #defineND_EXTLSCERTUSER0x200 +#defineND_ERELOOKUP0x400 /* * ND_GSS should be the "or" of all GSS type authentications. diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c index 1a54914fc9dc..530ebb8a8cc8 100644 --- a/sys/fs/nfsserver/nfs_nfsdsocket.c +++ b/sys/fs/nfsserver/nfs_nfsdsocket.c @@ -1212,8 +1212,10 @@ tryagain: */ nfsm_trimtrailing(nd, mb, bpos, bextpg, bextpgsiz); nd->nd_repstat = 0; + nd->nd_flag |= ND_ERELOOKUP; goto tryagain; } + nd->nd_flag &= ~ND_ERELOOKUP; if (statsinprog != 0) { nfsrvd_statend(op, /*bytes*/ 0, /*now*/ NULL, diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index f80b386ae839..1f6e8b7ef526 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -4016,6 +4016,11 @@ nfsrv_checkseqid(struct nfsrv_descript *nd, u_int32_t seqid, printf("refcnt=%d\n", stp->ls_op->rc_refcnt); panic("nfsrvstate op refcnt"); } + + /* If ND_ERELOOKUP is set, the seqid has already been handled. */ + if ((nd->nd_flag & ND_ERELOOKUP) != 0) + goto out; + if ((stp->ls_seq + 1) == seqid) { if (stp->ls_op) nfsrvd_derefcache(stp->ls_op); ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: c98a764c681f - main - cp(1): fix performance issue for large non-sparse file copies
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=c98a764c681f8b70812a9f13a6e61c96aa1a69d2 commit c98a764c681f8b70812a9f13a6e61c96aa1a69d2 Author: Rick Macklem AuthorDate: 2021-01-03 00:58:43 + Commit: Rick Macklem CommitDate: 2021-01-03 00:58:43 + cp(1): fix performance issue for large non-sparse file copies PR252358 reported a serious performance problem when copying a large non-sparse file on a UFS file system. This problem seems to have been caused by a large number of SEEK_HOLE operations, with one done for each copy_file_range(2) call. This patch modifies cp(1) to use a large (SSIZE_MAX) len argument, reducing the number of system calls and resolving the performance issue. While here, convert the type of the "rcount" from "int" to "ssize_t" so that it is consistent with that returned by both read(2) and copy_file_range(2). PR: 252358 Reviewed by:asomers Differential Revision: https://reviews.freebsd.org/D27937 --- bin/cp/utils.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/bin/cp/utils.c b/bin/cp/utils.c index 1a3b5502145a..7742b0d0a516 100644 --- a/bin/cp/utils.c +++ b/bin/cp/utils.c @@ -74,11 +74,10 @@ __FBSDID("$FreeBSD$"); */ #define BUFSIZE_SMALL (MAXPHYS) -static int +static ssize_t copy_fallback(int from_fd, int to_fd, char *buf, size_t bufsize) { - int rcount; - ssize_t wresid, wcount = 0; + ssize_t rcount, wresid, wcount = 0; char *bufp; rcount = read(from_fd, buf, bufsize); @@ -100,10 +99,10 @@ copy_file(const FTSENT *entp, int dne) static char *buf = NULL; static size_t bufsize; struct stat *fs; - ssize_t wcount; + ssize_t rcount, wcount; size_t wresid; off_t wtotal; - int ch, checkch, from_fd, rcount, rval, to_fd; + int ch, checkch, from_fd, rval, to_fd; char *bufp; #ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED char *p; @@ -236,7 +235,7 @@ copy_file(const FTSENT *entp, int dne) do { if (use_copy_file_range) { rcount = copy_file_range(from_fd, NULL, - to_fd, NULL, bufsize, 0); + to_fd, NULL, SSIZE_MAX, 0); if (rcount < 0 && errno == EINVAL) { /* Prob a non-seekable FD */ use_copy_file_range = 0; ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: d189a74dfdcd - main - copy_file_range(2): add recommendation to use large "len"
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=d189a74dfdcd4a89c92a48ecbf8fcb6f6903f9b6 commit d189a74dfdcd4a89c92a48ecbf8fcb6f6903f9b6 Author: Rick Macklem AuthorDate: 2021-01-03 01:21:21 + Commit: Rick Macklem CommitDate: 2021-01-03 01:21:21 + copy_file_range(2): add recommendation to use large "len" PR#252358 reported a serious performance problem w.r.t. cp(1) when copying large non-sparse files. This problem appears to have been caused by cp(1) calling copy_file_range(2) with a small "len" argument. This patch adds a recommendation to use a large "len" value where possible, for performance reasons. Reviewed by:asomers Differential Revision: https://reviews.freebsd.org/D27935 --- lib/libc/sys/copy_file_range.2 | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/libc/sys/copy_file_range.2 b/lib/libc/sys/copy_file_range.2 index a3f714f0e7e8..22106b397ef2 100644 --- a/lib/libc/sys/copy_file_range.2 +++ b/lib/libc/sys/copy_file_range.2 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 30, 2020 +.Dd January 2, 2021 .Dt COPY_FILE_RANGE 2 .Os .Sh NAME @@ -117,6 +117,15 @@ with .Dv SEEK_DATA arguments and this system call for the data ranges found. +.Pp +For best performance, call +.Fn copy_file_range +with the largest +.Fa len +value possible. +It is interruptible on most file systems, +so there is no penalty for using very large len values, even SSIZE_MAX. +.Pp .Sh RETURN VALUES If it succeeds, the call returns the number of bytes copied, which can be fewer than ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: a0698341cd89 - main - getdirentries.2: fix for NFS mounts
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=a0698341cd894ba4a640e9a9bb0f72c2133d1228 commit a0698341cd894ba4a640e9a9bb0f72c2133d1228 Author: Rick Macklem AuthorDate: 2021-02-15 02:16:58 + Commit: Rick Macklem CommitDate: 2021-02-15 02:16:58 + getdirentries.2: fix for NFS mounts It was reported that getdirentries(2) was returning dirents with d_off set to 0 for an NFS mount. This is believed to be correct behaviour at this time (it may change for some NFS mounts in the future), but is inconsistent with what the getdirentries(2) man page says. This patch fixes the man page. This is a content change. PR: 253428 Reviewed by:asomers MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D28664 --- lib/libc/sys/getdirentries.2 | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/libc/sys/getdirentries.2 b/lib/libc/sys/getdirentries.2 index f2d1c05240d5..658be9459af5 100644 --- a/lib/libc/sys/getdirentries.2 +++ b/lib/libc/sys/getdirentries.2 @@ -28,7 +28,7 @@ .\"@(#)getdirentries.2 8.2 (Berkeley) 5/3/95 .\" $FreeBSD$ .\" -.Dd March 30, 2020 +.Dd February 14, 2021 .Dt GETDIRENTRIES 2 .Os .Sh NAME @@ -89,7 +89,7 @@ have the same .Fa d_fileno . The .Fa d_off -field returns a cookie which can be used with +field returns a cookie which, if non-zero, can be used with .Xr lseek 2 to position the directory descriptor to the next entry. The @@ -148,14 +148,16 @@ only .Pc , a value returned in the .Fa d_off -field, +field if it is non-zero, or zero. .Sh IMPLEMENTATION NOTES The .Fa d_off -field is being used as a cookie to readdir for nfs servers. -These cookies can be cached and allow to read directory entries at a specific -offset on demand. +field is currently set to 0 by the NFS client, since the +directory offset cookies returned by an NFS server cannot +be used by +.Xr lseek 2 +at this time. .Sh RETURN VALUES If successful, the number of bytes actually transferred is returned. Otherwise, -1 is returned and the global variable ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: cace1baa12a5 - stable/12 - mount_nfs: update man page description for oneopenown
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=cace1baa12a53dc089dcb49b8b34976bffa02702 commit cace1baa12a53dc089dcb49b8b34976bffa02702 Author: Rick Macklem AuthorDate: 2021-01-18 03:00:41 + Commit: Rick Macklem CommitDate: 2021-02-17 21:28:40 + mount_nfs: update man page description for oneopenown A recent email discussion indicated that a large accumulation of NFSv4 Opens was occurring on a mount. This appears to have been caused by a shared library within the mount being used by several processes, such that there is always at least one of these processes running. A new Open was created by each process and were not closed, since all the Opens were never closed. This is alleviated by using the "oneopenown" mount option. This man page update attempts to indicate the use of "oneopenown" for this case. This is a content change. (cherry picked from commit 448de00de556753575ec0a2e705712e7c606e680) --- sbin/mount_nfs/mount_nfs.8 | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/sbin/mount_nfs/mount_nfs.8 b/sbin/mount_nfs/mount_nfs.8 index debfb3fd7f1e..41fc8310fa84 100644 --- a/sbin/mount_nfs/mount_nfs.8 +++ b/sbin/mount_nfs/mount_nfs.8 @@ -28,7 +28,7 @@ .\"@(#)mount_nfs.8 8.3 (Berkeley) 3/29/95 .\" $FreeBSD$ .\" -.Dd November 30, 2020 +.Dd January 17, 2021 .Dt MOUNT_NFS 8 .Os .Sh NAME @@ -215,6 +215,19 @@ Make a minor version 1 of the NFS Version 4 protocol mount use a single OpenOwne for all Opens. This may be useful for a server with a very low limit on OpenOwners, such as AmazonEFS. +It may be required when an accumulation of NFS version 4 Opens occurs, +as indicated by the +.Dq Opens +count displayed by +.Xr nfsstat 8 +with the +.Fl c +and +.Fl E +command-line options. +A common case for an accumulation of Opens is a shared library within +the NFS mount that is used by several +processes, where at least one of these processes is always running. This option cannot be used for an NFS Version 4, minor version 0 mount. As such, this option requires the .Cm minorversion ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: b9cbc85d7272 - main - nfs-over-tls: add user space daemons rpc.tlsclntd and rpc.tlsservd
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=b9cbc85d727214cf3e13196ab7e7564e53037f77 commit b9cbc85d727214cf3e13196ab7e7564e53037f77 Author: Rick Macklem AuthorDate: 2021-02-18 22:08:19 + Commit: Rick Macklem CommitDate: 2021-02-18 22:15:03 + nfs-over-tls: add user space daemons rpc.tlsclntd and rpc.tlsservd The kernel changes needed for nfs-over-tls have been committed to main. However, nfs-over-tls requires user space daemons to handle the TLS handshake and other non-application data TLS records. There is one daemon (rpc.tlsclntd) for the client side and one daemon (rpc.tlsservd) for the server side, although they share a fair amount of code found in rpc.tlscommon.c and rpc.tlscommon.h. They use a KTLS enabled OpenSSL to perform the actual work and, as such, are only built when MK_OPENSSL_KTLS is set. Communication with the kernel is done via upcall RPCs done on AF_LOCAL sockets and the custom system call rpctls_syscall. Reviewed by:gbe (man pages only), jhb (usr.sbin/Makefile only) Comments by:jhb MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D28430 Relnotes: yes --- usr.sbin/Makefile | 2 + usr.sbin/rpc.tlsclntd/Makefile| 29 ++ usr.sbin/rpc.tlsclntd/rpc.tlsclntd.8 | 201 usr.sbin/rpc.tlsclntd/rpc.tlsclntd.c | 730 usr.sbin/rpc.tlsservd/Makefile| 29 ++ usr.sbin/rpc.tlsservd/rpc.tlscommon.c | 295 +++ usr.sbin/rpc.tlsservd/rpc.tlscommon.h | 68 +++ usr.sbin/rpc.tlsservd/rpc.tlsservd.8 | 348 + usr.sbin/rpc.tlsservd/rpc.tlsservd.c | 886 ++ 9 files changed, 2588 insertions(+) diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 39913a327b87..259ab72f2281 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -182,6 +182,8 @@ SUBDIR.${MK_NIS}+= ypserv SUBDIR.${MK_NIS}+= ypset SUBDIR.${MK_NTP}+= ntp SUBDIR.${MK_OPENSSL}+= keyserv +SUBDIR.${MK_OPENSSL_KTLS}+=rpc.tlsclntd +SUBDIR.${MK_OPENSSL_KTLS}+=rpc.tlsservd SUBDIR.${MK_PF}+= ftp-proxy SUBDIR.${MK_PKGBOOTSTRAP}+=pkg SUBDIR.${MK_PMC}+= pmc pmcannotate pmccontrol pmcstat pmcstudy diff --git a/usr.sbin/rpc.tlsclntd/Makefile b/usr.sbin/rpc.tlsclntd/Makefile new file mode 100644 index ..1c8481a7889c --- /dev/null +++ b/usr.sbin/rpc.tlsclntd/Makefile @@ -0,0 +1,29 @@ +# $FreeBSD$ + +.include + +PROG= rpc.tlsclntd +MAN= rpc.tlsclntd.8 +SRCS= rpc.tlsclntd.c rpc.tlscommon.c rpctlscd.h rpctlscd_svc.c rpctlscd_xdr.c + +CFLAGS+= -I. -I${SRCTOP}/usr.sbin/rpc.tlsservd + +LIBADD=ssl crypto util + +CLEANFILES= rpctlscd_svc.c rpctlscd_xdr.c rpctlscd.h + +RPCSRC=${SRCTOP}/sys/rpc/rpcsec_tls/rpctlscd.x +RPCGEN= RPCGEN_CPP=${CPP:Q} rpcgen -L -C -M + +rpctlscd_svc.c: ${RPCSRC} rpctlscd.h + ${RPCGEN} -m -o ${.TARGET} ${RPCSRC} + +rpctlscd_xdr.c: ${RPCSRC} rpctlscd.h + ${RPCGEN} -c -o ${.TARGET} ${RPCSRC} + +rpctlscd.h: ${RPCSRC} + ${RPCGEN} -h -o ${.TARGET} ${RPCSRC} + +.PATH: ${SRCTOP}/sys/rpc/rpcsec_tls ${SRCTOP}/usr.sbin/rpc.tlsservd + +.include diff --git a/usr.sbin/rpc.tlsclntd/rpc.tlsclntd.8 b/usr.sbin/rpc.tlsclntd/rpc.tlsclntd.8 new file mode 100644 index ..23a9d05495c1 --- /dev/null +++ b/usr.sbin/rpc.tlsclntd/rpc.tlsclntd.8 @@ -0,0 +1,201 @@ +.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/ +.\" Authors: Doug Rabson +.\" Developed with Red Inc: Alfred Perlstein +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"notice, this list of conditions and the following disclaimer in the +.\"documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE
git: 2f48313ab26e - main - nfs-over-tls: add rc scripts for rpc.tlsclntd and rpc.tlsservd
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=2f48313ab26ef257ca8d46052a33fb6ad6abdb4f commit 2f48313ab26ef257ca8d46052a33fb6ad6abdb4f Author: Rick Macklem AuthorDate: 2021-02-18 22:38:01 + Commit: Rick Macklem CommitDate: 2021-02-18 22:38:01 + nfs-over-tls: add rc scripts for rpc.tlsclntd and rpc.tlsservd Add rc.d scripts that control the recently committed rpc.tlsclntd(8) and rpc.tlsservd(8) daemons. Reviewed by:gbe MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D28432 --- libexec/rc/rc.conf | 4 libexec/rc/rc.d/Makefile | 4 libexec/rc/rc.d/tlsclntd | 21 + libexec/rc/rc.d/tlsservd | 25 + 4 files changed, 54 insertions(+) diff --git a/libexec/rc/rc.conf b/libexec/rc/rc.conf index d8c24853225f..55a7112b15ea 100644 --- a/libexec/rc/rc.conf +++ b/libexec/rc/rc.conf @@ -385,6 +385,10 @@ nfscbd_enable="NO" # NFSv4 client side callback daemon nfscbd_flags=""# Flags for nfscbd nfsuserd_enable="NO" # NFSv4 user/group name mapping daemon nfsuserd_flags="" # Flags for nfsuserd +tlsclntd_enable="NO" # Run rpc.tlsclntd needed for NFS-over-TLS mount +tlsclntd_flags="" # Flags for rpc.tlsclntd +tlsservd_enable="NO" # Run rpc.tlsservd needed for NFS-over-TLS nfsd +tlsservd_flags="" # Flags for rpc.tlsservd ### Network Time Services options: ### timed_enable="NO" # Run the time daemon (or NO). diff --git a/libexec/rc/rc.d/Makefile b/libexec/rc/rc.d/Makefile index a8277e08932c..1a61e89aa215 100644 --- a/libexec/rc/rc.d/Makefile +++ b/libexec/rc/rc.d/Makefile @@ -271,6 +271,10 @@ _opensm= opensm .if ${MK_OPENSSL} != "no" CONFS+=keyserv +.if ${MK_OPENSSL_KTLS} != "no" +CONFS+=tlsclntd \ + tlsservd +.endif .endif .if ${MK_OPENSSH} != "no" diff --git a/libexec/rc/rc.d/tlsclntd b/libexec/rc/rc.d/tlsclntd new file mode 100755 index ..4566ceb67abd --- /dev/null +++ b/libexec/rc/rc.d/tlsclntd @@ -0,0 +1,21 @@ +#!/bin/sh +# +# $FreeBSD$ +# + +# PROVIDE: tlsclntd +# REQUIRE: NETWORKING root mountcritlocal sysctl +# BEFORE: nfscbd +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="tlsclntd" +desc="NFS over TLS client side daemon" +rcvar="tlsclntd_enable" +command="/usr/sbin/rpc.${name}" +pidfile="/var/run/rpc.${name}.pid" + +load_rc_config $name + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/tlsservd b/libexec/rc/rc.d/tlsservd new file mode 100755 index ..cca28ed60ffe --- /dev/null +++ b/libexec/rc/rc.d/tlsservd @@ -0,0 +1,25 @@ +#!/bin/sh +# +# $FreeBSD$ +# + +# PROVIDE: tlsservd +# REQUIRE: NETWORKING root mountcritlocal sysctl +# BEFORE: nfsd +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="tlsservd" +desc="NFS over TLS server side daemon" +rcvar="tlsservd_enable" +command="/usr/sbin/rpc.${name}" + +pidfile="/var/run/rpc.${name}.pid" +required_files="/etc/rpc.tlsservd/cert.pem /etc/rpc.tlsservd/certkey.pem" +extra_commands="reload" + + +load_rc_config $name + +run_rc_command "$1" ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 3fe2c68ba20f - main - nfsclient: fix panic in cache_enter_time()
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=3fe2c68ba20fb3365ef91e0b85f88237b5369f38 commit 3fe2c68ba20fb3365ef91e0b85f88237b5369f38 Author: Rick Macklem AuthorDate: 2021-02-28 01:54:05 + Commit: Rick Macklem CommitDate: 2021-02-28 01:54:05 + nfsclient: fix panic in cache_enter_time() Juraj Lutter (otis@) reported a panic "dvp != vp not true" in cache_enter_time() called from the NFS client's nfsrpc_readdirplus() function. This is specific to an NFSv3 mount with the "rdirplus" mount option. Unlike NFSv4, NFSv3 replies to ReaddirPlus includes entries for the current directory. This trivial patch avoids doing a cache_enter_time() call for the current directory to avoid the panic. Reported by:otis Tested by: otis Reviewed by:mjg MFC after: 3 days Differential Revision: https://reviews.freebsd.org/D28969 --- sys/fs/nfsclient/nfs_clrpcops.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index b4f2d5301d13..c95d4dc58e7a 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -3761,6 +3761,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep, ndp->ni_vp = newvp; NFSCNHASH(cnp, HASHINIT); if (cnp->cn_namelen <= NCHNAMLEN && + ndp->ni_dvp != ndp->ni_vp && (newvp->v_type != VDIR || dctime.tv_sec != 0)) { cache_enter_time(ndp->ni_dvp, ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 3e04ab36ba5c - main - nfsclient: add checks for a server returning the current directory
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=3e04ab36ba5ce5cbbf6d22f17a01a391a04e465f commit 3e04ab36ba5ce5cbbf6d22f17a01a391a04e465f Author: Rick Macklem AuthorDate: 2021-02-28 22:15:32 + Commit: Rick Macklem CommitDate: 2021-02-28 22:15:32 + nfsclient: add checks for a server returning the current directory Commit 3fe2c68ba20f dealt with a panic in cache_enter_time() where the vnode referred to the directory argument. It would also be possible to get these panics if a broken NFS server were to return the directory as an new object being created within the directory or in a Lookup reply. This patch adds checks to avoid the panics and logs messages to indicate that the server is broken for the file object creation cases. Reviewd by: kib MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D28987 --- sys/fs/nfsclient/nfs_clvnops.c | 38 +- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 80317cfd7a50..fc5445ef1e76 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -1423,7 +1423,7 @@ nfs_lookup(struct vop_lookup_args *ap) } if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) cnp->cn_flags |= SAVENAME; - if ((cnp->cn_flags & MAKEENTRY) && + if ((cnp->cn_flags & MAKEENTRY) && dvp != newvp && (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN)) && attrflag != 0 && (newvp->v_type != VDIR || dattrflag != 0)) cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime, @@ -1752,9 +1752,14 @@ again: } } if (!error) { - if ((cnp->cn_flags & MAKEENTRY) && attrflag) - cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime, - NULL); + if ((cnp->cn_flags & MAKEENTRY) && attrflag) { + if (dvp != newvp) + cache_enter_time(dvp, newvp, cnp, + &nfsva.na_ctime, NULL); + else + printf("nfs_create: bogus NFS server returned " + "the directory as the new file object\n"); + } *ap->a_vpp = newvp; } else if (NFS_ISV4(dvp)) { error = nfscl_maperr(cnp->cn_thread, error, vap->va_uid, @@ -2126,7 +2131,11 @@ nfs_link(struct vop_link_args *ap) */ if (VFSTONFS(vp->v_mount)->nm_negnametimeo != 0 && (cnp->cn_flags & MAKEENTRY) && attrflag != 0 && error == 0) { - cache_enter_time(tdvp, vp, cnp, &nfsva.na_ctime, NULL); + if (tdvp != vp) + cache_enter_time(tdvp, vp, cnp, &nfsva.na_ctime, NULL); + else + printf("nfs_link: bogus NFS server returned " + "the directory as the new link\n"); } if (error && NFS_ISV4(vp)) error = nfscl_maperr(cnp->cn_thread, error, (uid_t)0, @@ -2205,7 +2214,12 @@ nfs_symlink(struct vop_symlink_args *ap) */ if (VFSTONFS(dvp->v_mount)->nm_negnametimeo != 0 && (cnp->cn_flags & MAKEENTRY) && attrflag != 0 && error == 0) { - cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime, NULL); + if (dvp != newvp) + cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime, + NULL); + else + printf("nfs_symlink: bogus NFS server returned " + "the directory as the new file object\n"); } return (error); } @@ -2278,9 +2292,15 @@ nfs_mkdir(struct vop_mkdir_args *ap) */ if (VFSTONFS(dvp->v_mount)->nm_negnametimeo != 0 && (cnp->cn_flags & MAKEENTRY) && - attrflag != 0 && dattrflag != 0) - cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime, - &dnfsva.na_ctime); + attrflag != 0 && dattrflag != 0) { + if (dvp != newvp) + cache_enter_time(dvp, newvp, cnp, + &nfsva.na_ctime, &dnfsva.na_ctime); + else + printf("nfs_mkdir: bogus NFS server returned " +
git: 15bed8c46b32 - main - nfsclient: add nfs node locking around uses of n_direofoffset
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=15bed8c46b32dec19e922cb89e12c8970867a303 commit 15bed8c46b32dec19e922cb89e12c8970867a303 Author: Rick Macklem AuthorDate: 2021-02-28 22:53:54 + Commit: Rick Macklem CommitDate: 2021-02-28 22:53:54 + nfsclient: add nfs node locking around uses of n_direofoffset During code inspection I noticed that the n_direofoffset field of the NFS node was being manipulated without any lock being held to make it SMP safe. This patch adds locking of the NFS node's mutex around handling of n_direofoffset to make it SMP safe. I have not seen any failure that could be attributed to n_direofoffset being manipulated concurrently by multiple processors, but I think this is possible, since directories are read with shared vnode locking, plus locks only on individual buffer cache blocks. However, there have been as yet unexplained issues w.r.t reading large directories over NFS that could have conceivably been caused by concurrent manipulation of n_direofoffset. MFC after: 2 weeks --- sys/fs/nfsclient/nfs_clbio.c | 10 ++ sys/fs/nfsclient/nfs_clsubs.c | 3 ++- sys/fs/nfsclient/nfs_clvnops.c | 21 - 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c index 832b44b99c8d..ff9f446ff1ef 100644 --- a/sys/fs/nfsclient/nfs_clbio.c +++ b/sys/fs/nfsclient/nfs_clbio.c @@ -584,11 +584,14 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) break; case VDIR: NFSINCRGLOBAL(nfsstatsv1.biocache_readdirs); + NFSLOCKNODE(np); if (np->n_direofoffset && uio->uio_offset >= np->n_direofoffset) { + NFSUNLOCKNODE(np); error = 0; goto out; } + NFSUNLOCKNODE(np); lbn = (uoff_t)uio->uio_offset / NFS_DIRBLKSIZ; on = uio->uio_offset & (NFS_DIRBLKSIZ - 1); bp = nfs_getcacheblk(vp, lbn, NFS_DIRBLKSIZ, td); @@ -620,11 +623,14 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) * NFSERR_BAD_COOKIE (double yuch!). */ for (i = 0; i <= lbn && !error; i++) { + NFSLOCKNODE(np); if (np->n_direofoffset && (i * NFS_DIRBLKSIZ) >= np->n_direofoffset) { + NFSUNLOCKNODE(np); error = 0; goto out; } + NFSUNLOCKNODE(np); bp = nfs_getcacheblk(vp, i, NFS_DIRBLKSIZ, td); if (!bp) { error = newnfs_sigintr(nmp, td); @@ -667,11 +673,13 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) * (You need the current block first, so that you have the * directory offset cookie of the next block.) */ + NFSLOCKNODE(np); if (nmp->nm_readahead > 0 && (bp->b_flags & B_INVAL) == 0 && (np->n_direofoffset == 0 || (lbn + 1) * NFS_DIRBLKSIZ < np->n_direofoffset) && incore(&vp->v_bufobj, lbn + 1) == NULL) { + NFSUNLOCKNODE(np); rabp = nfs_getcacheblk(vp, lbn + 1, NFS_DIRBLKSIZ, td); if (rabp) { if ((rabp->b_flags & (B_CACHE|B_DELWRI)) == 0) { @@ -688,6 +696,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) brelse(rabp); } } + NFSLOCKNODE(np); } /* * Unlike VREG files, whos buffer size ( bp->b_bcount ) is @@ -704,6 +713,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) n = lmin(uio->uio_resid, NFS_DIRBLKSIZ - bp->b_resid - on); if (np->n_direofoffset && n > np->n_direofoffset - uio->uio_offset) n = np->n_direofoffset - uio->uio_offset; + NFSUNLOCKNODE(np); break; default: printf(" ncl_bioread: type %x unexpected\n", vp->v_type); diff --git a/sys/fs/nfsclient/nfs_clsubs.c b/sys/fs/nfsclient/nfs_clsubs.c index f26ad0452e07..d36
git: a5f9fe2bab78 - main - copy_file_range(2): Fix for small values of input file offset and len
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=a5f9fe2bab789f49e8b53da3a62dbd34725e23ea commit a5f9fe2bab789f49e8b53da3a62dbd34725e23ea Author: Rick Macklem AuthorDate: 2021-03-01 14:28:30 + Commit: Rick Macklem CommitDate: 2021-03-01 14:31:10 + copy_file_range(2): Fix for small values of input file offset and len r366302 broke copy_file_range(2) for small values of input file offset and len. It was possible for rem to be greater than len and then "len - rem" was a large value, since both variables are unsigned. Reported by: koobs, Pablo (Python) Reviewed by:asomers, koobs MFC after: 3 days Differential Revision: https://reviews.freebsd.org/D28981 --- sys/kern/vfs_vnops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 781968f2db53..7a0951fb07ca 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -3143,7 +3143,7 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, rem = *inoffp % blksize; if (rem > 0) rem = blksize - rem; - if (len - rem > blksize) + if (len > rem && len - rem > blksize) len = savlen = rounddown(len - rem, blksize) + rem; } ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 94f2e42f5e0b - main - nfsclient: Fix the stripe unit size for a File Layout pNFS layout
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=94f2e42f5e0b78a7a4684d4a4eb62ea470a57eb1 commit 94f2e42f5e0b78a7a4684d4a4eb62ea470a57eb1 Author: Rick Macklem AuthorDate: 2021-03-01 20:49:32 + Commit: Rick Macklem CommitDate: 2021-03-01 20:49:32 + nfsclient: Fix the stripe unit size for a File Layout pNFS layout During a recent virtual NFSv4 testing event, a bug in the FreeBSD client was detected when doing a File Layout pNFS DS I/O operation. The size of the I/O operation was smaller than expected. The I/O size is specified as a stripe unit size in bits 6->31 of nflh_util in the layout. I had misinterpreted RFC5661 and had shifted the value right by 6 bits. The correct interpretation is to use the value as presented (it is always an exact multiple of 64), clearing bits 0->5. This patch fixes this. Without the patch, I/O through the DSs work, but the I/O size is 1/64th of what is optimal. MFC after: 2 weeks --- sys/fs/nfsclient/nfs_clrpcops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index c95d4dc58e7a..0e503e34810b 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -6024,7 +6024,7 @@ nfscl_doflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, np = VTONFS(vp); rel_off = off - flp->nfsfl_patoff; - stripe_unit_size = (flp->nfsfl_util >> 6) & 0x3ff; + stripe_unit_size = flp->nfsfl_util & NFSFLAYUTIL_STRIPE_MASK; stripe_pos = (rel_off / stripe_unit_size + flp->nfsfl_stripe1) % dp->nfsdi_stripecnt; transfer = stripe_unit_size - (rel_off % stripe_unit_size); ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: b96e66349ed8 - stable/13 - getdirentries.2: fix for NFS mounts
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=b96e66349ed80f253c0cc04266de1a3768b0 commit b96e66349ed80f253c0cc04266de1a3768b0 Author: Rick Macklem AuthorDate: 2021-02-15 02:16:58 + Commit: Rick Macklem CommitDate: 2021-03-01 21:00:38 + getdirentries.2: fix for NFS mounts It was reported that getdirentries(2) was returning dirents with d_off set to 0 for an NFS mount. This is believed to be correct behaviour at this time (it may change for some NFS mounts in the future), but is inconsistent with what the getdirentries(2) man page says. This patch fixes the man page. This is a content change. PR: 253428 (cherry picked from commit a0698341cd894ba4a640e9a9bb0f72c2133d1228) --- lib/libc/sys/getdirentries.2 | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/libc/sys/getdirentries.2 b/lib/libc/sys/getdirentries.2 index f2d1c05240d5..658be9459af5 100644 --- a/lib/libc/sys/getdirentries.2 +++ b/lib/libc/sys/getdirentries.2 @@ -28,7 +28,7 @@ .\"@(#)getdirentries.2 8.2 (Berkeley) 5/3/95 .\" $FreeBSD$ .\" -.Dd March 30, 2020 +.Dd February 14, 2021 .Dt GETDIRENTRIES 2 .Os .Sh NAME @@ -89,7 +89,7 @@ have the same .Fa d_fileno . The .Fa d_off -field returns a cookie which can be used with +field returns a cookie which, if non-zero, can be used with .Xr lseek 2 to position the directory descriptor to the next entry. The @@ -148,14 +148,16 @@ only .Pc , a value returned in the .Fa d_off -field, +field if it is non-zero, or zero. .Sh IMPLEMENTATION NOTES The .Fa d_off -field is being used as a cookie to readdir for nfs servers. -These cookies can be cached and allow to read directory entries at a specific -offset on demand. +field is currently set to 0 by the NFS client, since the +directory offset cookies returned by an NFS server cannot +be used by +.Xr lseek 2 +at this time. .Sh RETURN VALUES If successful, the number of bytes actually transferred is returned. Otherwise, -1 is returned and the global variable ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: c04199affeac - main - nfsclient: Fix ReadDS/WriteDS/CommitDS nfsstats RPC counts for a NFSv3 DS
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=c04199affeacbd9e9dda3aaf5ca0b1b180031e78 commit c04199affeacbd9e9dda3aaf5ca0b1b180031e78 Author: Rick Macklem AuthorDate: 2021-03-02 22:18:23 + Commit: Rick Macklem CommitDate: 2021-03-02 22:18:23 + nfsclient: Fix ReadDS/WriteDS/CommitDS nfsstats RPC counts for a NFSv3 DS During a recent virtual NFSv4 testing event, a bug in the FreeBSD client was detected when doing I/O DS operations on a Flexible File Layout pNFS server. For an NFSv3 DS, the Read/Write/Commit nfsstats were incremented instead of the ReadDS/WriteDS/CommitDS counts. This patch fixes this. Only the RPC counts reported by nfsstat(1) were affected by this bug, the I/O operations were performed correctly. MFC after: 2 weeks --- sys/fs/nfs/nfsport.h| 1 + sys/fs/nfsclient/nfs_clrpcops.c | 12 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h index 9f2789f57bec..255c9a47ebdf 100644 --- a/sys/fs/nfs/nfsport.h +++ b/sys/fs/nfs/nfsport.h @@ -1006,6 +1006,7 @@ bool ncl_pager_setsize(struct vnode *vp, u_quad_t *nsizep); * "out by one" without disastrous consequences. */ #defineNFSINCRGLOBAL(a)((a)++) +#defineNFSDECRGLOBAL(a)((a)--) /* * Assorted funky stuff to make things work under Darwin8. diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 0e503e34810b..527a47338b3f 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -65,6 +65,7 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, dssameconn, CTLFLAG_RW, /* * Global variables */ +extern struct nfsstatsv1 nfsstatsv1; extern int nfs_numnfscbd; extern struct timeval nfsboottime; extern u_int32_t newnfs_false, newnfs_true; @@ -6320,6 +6321,8 @@ nfsrpc_readds(vnode_t vp, struct uio *uiop, nfsv4stateid_t *stateidp, int *eofp, } else { nfscl_reqstart(nd, NFSPROC_READ, nmp, fhp->nfh_fh, fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSDECRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_READ]); + NFSINCRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_READDS]); NFSCL_DEBUG(4, "nfsrpc_readds: vers3\n"); } NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED * 3); @@ -6395,6 +6398,8 @@ nfsrpc_writeds(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, } else { nfscl_reqstart(nd, NFSPROC_WRITE, nmp, fhp->nfh_fh, fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSDECRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_WRITE]); + NFSINCRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_WRITEDS]); NFSCL_DEBUG(4, "nfsrpc_writeds: vers3\n"); NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + 3 * NFSX_UNSIGNED); } @@ -6522,6 +6527,8 @@ nfsrpc_writedsmir(vnode_t vp, int *iomode, int *must_commit, } else { nfscl_reqstart(nd, NFSPROC_WRITE, nmp, fhp->nfh_fh, fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSDECRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_WRITE]); + NFSINCRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_WRITEDS]); NFSCL_DEBUG(4, "nfsrpc_writedsmir: vers3\n"); NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + 3 * NFSX_UNSIGNED); } @@ -6737,9 +6744,12 @@ nfsrpc_commitds(vnode_t vp, uint64_t offset, int cnt, struct nfsclds *dsp, nfscl_reqstart(nd, NFSPROC_COMMITDS, nmp, fhp->nfh_fh, fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); vers = NFS_VER4; - } else + } else { nfscl_reqstart(nd, NFSPROC_COMMIT, nmp, fhp->nfh_fh, fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSDECRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_COMMIT]); + NFSINCRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_COMMITDS]); + } NFSCL_DEBUG(4, "nfsrpc_commitds: vers=%d minvers=%d\n", vers, minorvers); NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + NFSX_UNSIGNED); ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 902a18d50aef - stable/13 - copy_file_range(2): Fix for small values of input file offset and len
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=902a18d50aef8775aa833dde3638356f994e28e8 commit 902a18d50aef8775aa833dde3638356f994e28e8 Author: Rick Macklem AuthorDate: 2021-03-01 14:28:30 + Commit: Rick Macklem CommitDate: 2021-03-03 14:46:33 + copy_file_range(2): Fix for small values of input file offset and len r366302 broke copy_file_range(2) for small values of input file offset and len. It was possible for rem to be greater than len and then "len - rem" was a large value, since both variables are unsigned. (cherry picked from commit a5f9fe2bab789f49e8b53da3a62dbd34725e23ea) --- sys/kern/vfs_vnops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 781968f2db53..7a0951fb07ca 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -3143,7 +3143,7 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, rem = *inoffp % blksize; if (rem > 0) rem = blksize - rem; - if (len - rem > blksize) + if (len > rem && len - rem > blksize) len = savlen = rounddown(len - rem, blksize) + rem; } ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: a2a4cfc3157f - stable/13 - nfsclient: fix panic in cache_enter_time()
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=a2a4cfc3157ff19a192eff96c017169ede15c054 commit a2a4cfc3157ff19a192eff96c017169ede15c054 Author: Rick Macklem AuthorDate: 2021-02-28 01:54:05 + Commit: Rick Macklem CommitDate: 2021-03-03 15:10:51 + nfsclient: fix panic in cache_enter_time() Juraj Lutter (otis@) reported a panic "dvp != vp not true" in cache_enter_time() called from the NFS client's nfsrpc_readdirplus() function. This is specific to an NFSv3 mount with the "rdirplus" mount option. Unlike NFSv4, NFSv3 replies to ReaddirPlus includes entries for the current directory. This trivial patch avoids doing a cache_enter_time() call for the current directory to avoid the panic. (cherry picked from commit 3fe2c68ba20fb3365ef91e0b85f88237b5369f38) --- sys/fs/nfsclient/nfs_clrpcops.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index b4f2d5301d13..c95d4dc58e7a 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -3761,6 +3761,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep, ndp->ni_vp = newvp; NFSCNHASH(cnp, HASHINIT); if (cnp->cn_namelen <= NCHNAMLEN && + ndp->ni_dvp != ndp->ni_vp && (newvp->v_type != VDIR || dctime.tv_sec != 0)) { cache_enter_time(ndp->ni_dvp, ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 2d379aed1e5c - releng/13.0 - copy_file_range(2): Fix for small values of input file offset and len
The branch releng/13.0 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=2d379aed1e5c52956c5257d286a781e9a32e68b3 commit 2d379aed1e5c52956c5257d286a781e9a32e68b3 Author: Rick Macklem AuthorDate: 2021-03-01 14:28:30 + Commit: Rick Macklem CommitDate: 2021-03-03 15:40:39 + copy_file_range(2): Fix for small values of input file offset and len r366302 broke copy_file_range(2) for small values of input file offset and len. It was possible for rem to be greater than len and then "len - rem" was a large value, since both variables are unsigned. Approved by:re (gjb) (cherry picked from commit a5f9fe2bab789f49e8b53da3a62dbd34725e23ea) --- sys/kern/vfs_vnops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 71dd379558cb..9ea792833255 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -3126,7 +3126,7 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, rem = *inoffp % blksize; if (rem > 0) rem = blksize - rem; - if (len - rem > blksize) + if (len > rem && len - rem > blksize) len = savlen = rounddown(len - rem, blksize) + rem; } ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 3664067ea91a - releng/13.0 - nfsclient: fix panic in cache_enter_time()
The branch releng/13.0 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=3664067ea91a5484e0f75c9938d559ec1134a565 commit 3664067ea91a5484e0f75c9938d559ec1134a565 Author: Rick Macklem AuthorDate: 2021-02-28 01:54:05 + Commit: Rick Macklem CommitDate: 2021-03-03 16:27:06 + nfsclient: fix panic in cache_enter_time() Juraj Lutter (otis@) reported a panic "dvp != vp not true" in cache_enter_time() called from the NFS client's nfsrpc_readdirplus() function. This is specific to an NFSv3 mount with the "rdirplus" mount option. Unlike NFSv4, NFSv3 replies to ReaddirPlus includes entries for the current directory. This trivial patch avoids doing a cache_enter_time() call for the current directory to avoid the panic. Approved by:re (gjb) (cherry picked from commit 3fe2c68ba20fb3365ef91e0b85f88237b5369f38) --- sys/fs/nfsclient/nfs_clrpcops.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index b4f2d5301d13..c95d4dc58e7a 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -3761,6 +3761,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep, ndp->ni_vp = newvp; NFSCNHASH(cnp, HASHINIT); if (cnp->cn_namelen <= NCHNAMLEN && + ndp->ni_dvp != ndp->ni_vp && (newvp->v_type != VDIR || dctime.tv_sec != 0)) { cache_enter_time(ndp->ni_dvp, ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 0dcfb6d761cc - stable/12 - getdirentries.2: fix for NFS mounts
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=0dcfb6d761ccc8bd45b68231f9a5f4ff4c6d989f commit 0dcfb6d761ccc8bd45b68231f9a5f4ff4c6d989f Author: Rick Macklem AuthorDate: 2021-02-15 02:16:58 + Commit: Rick Macklem CommitDate: 2021-03-04 01:30:23 + getdirentries.2: fix for NFS mounts It was reported that getdirentries(2) was returning dirents with d_off set to 0 for an NFS mount. This is believed to be correct behaviour at this time (it may change for some NFS mounts in the future), but is inconsistent with what the getdirentries(2) man page says. This patch fixes the man page. This is a content change. PR: 253428 (cherry picked from commit a0698341cd894ba4a640e9a9bb0f72c2133d1228) --- lib/libc/sys/getdirentries.2 | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/libc/sys/getdirentries.2 b/lib/libc/sys/getdirentries.2 index f2d1c05240d5..658be9459af5 100644 --- a/lib/libc/sys/getdirentries.2 +++ b/lib/libc/sys/getdirentries.2 @@ -28,7 +28,7 @@ .\"@(#)getdirentries.2 8.2 (Berkeley) 5/3/95 .\" $FreeBSD$ .\" -.Dd March 30, 2020 +.Dd February 14, 2021 .Dt GETDIRENTRIES 2 .Os .Sh NAME @@ -89,7 +89,7 @@ have the same .Fa d_fileno . The .Fa d_off -field returns a cookie which can be used with +field returns a cookie which, if non-zero, can be used with .Xr lseek 2 to position the directory descriptor to the next entry. The @@ -148,14 +148,16 @@ only .Pc , a value returned in the .Fa d_off -field, +field if it is non-zero, or zero. .Sh IMPLEMENTATION NOTES The .Fa d_off -field is being used as a cookie to readdir for nfs servers. -These cookies can be cached and allow to read directory entries at a specific -offset on demand. +field is currently set to 0 by the NFS client, since the +directory offset cookies returned by an NFS server cannot +be used by +.Xr lseek 2 +at this time. .Sh RETURN VALUES If successful, the number of bytes actually transferred is returned. Otherwise, -1 is returned and the global variable ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 2c76eebca71b - stable/13 - nfs-over-tls: add user space daemons rpc.tlsclntd and rpc.tlsservd
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=2c76eebca71b8e17881dfcc01faeb0537d87e0af commit 2c76eebca71b8e17881dfcc01faeb0537d87e0af Author: Rick Macklem AuthorDate: 2021-02-18 22:08:19 + Commit: Rick Macklem CommitDate: 2021-03-05 21:49:46 + nfs-over-tls: add user space daemons rpc.tlsclntd and rpc.tlsservd The kernel changes needed for nfs-over-tls have been committed to main. However, nfs-over-tls requires user space daemons to handle the TLS handshake and other non-application data TLS records. There is one daemon (rpc.tlsclntd) for the client side and one daemon (rpc.tlsservd) for the server side, although they share a fair amount of code found in rpc.tlscommon.c and rpc.tlscommon.h. They use a KTLS enabled OpenSSL to perform the actual work and, as such, are only built when MK_OPENSSL_KTLS is set. Communication with the kernel is done via upcall RPCs done on AF_LOCAL sockets and the custom system call rpctls_syscall. Relnotes: yes (cherry picked from commit b9cbc85d727214cf3e13196ab7e7564e53037f77) --- usr.sbin/Makefile | 2 + usr.sbin/rpc.tlsclntd/Makefile| 29 ++ usr.sbin/rpc.tlsclntd/rpc.tlsclntd.8 | 201 usr.sbin/rpc.tlsclntd/rpc.tlsclntd.c | 730 usr.sbin/rpc.tlsservd/Makefile| 29 ++ usr.sbin/rpc.tlsservd/rpc.tlscommon.c | 295 +++ usr.sbin/rpc.tlsservd/rpc.tlscommon.h | 68 +++ usr.sbin/rpc.tlsservd/rpc.tlsservd.8 | 348 + usr.sbin/rpc.tlsservd/rpc.tlsservd.c | 886 ++ 9 files changed, 2588 insertions(+) diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 39913a327b87..259ab72f2281 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -182,6 +182,8 @@ SUBDIR.${MK_NIS}+= ypserv SUBDIR.${MK_NIS}+= ypset SUBDIR.${MK_NTP}+= ntp SUBDIR.${MK_OPENSSL}+= keyserv +SUBDIR.${MK_OPENSSL_KTLS}+=rpc.tlsclntd +SUBDIR.${MK_OPENSSL_KTLS}+=rpc.tlsservd SUBDIR.${MK_PF}+= ftp-proxy SUBDIR.${MK_PKGBOOTSTRAP}+=pkg SUBDIR.${MK_PMC}+= pmc pmcannotate pmccontrol pmcstat pmcstudy diff --git a/usr.sbin/rpc.tlsclntd/Makefile b/usr.sbin/rpc.tlsclntd/Makefile new file mode 100644 index ..1c8481a7889c --- /dev/null +++ b/usr.sbin/rpc.tlsclntd/Makefile @@ -0,0 +1,29 @@ +# $FreeBSD$ + +.include + +PROG= rpc.tlsclntd +MAN= rpc.tlsclntd.8 +SRCS= rpc.tlsclntd.c rpc.tlscommon.c rpctlscd.h rpctlscd_svc.c rpctlscd_xdr.c + +CFLAGS+= -I. -I${SRCTOP}/usr.sbin/rpc.tlsservd + +LIBADD=ssl crypto util + +CLEANFILES= rpctlscd_svc.c rpctlscd_xdr.c rpctlscd.h + +RPCSRC=${SRCTOP}/sys/rpc/rpcsec_tls/rpctlscd.x +RPCGEN= RPCGEN_CPP=${CPP:Q} rpcgen -L -C -M + +rpctlscd_svc.c: ${RPCSRC} rpctlscd.h + ${RPCGEN} -m -o ${.TARGET} ${RPCSRC} + +rpctlscd_xdr.c: ${RPCSRC} rpctlscd.h + ${RPCGEN} -c -o ${.TARGET} ${RPCSRC} + +rpctlscd.h: ${RPCSRC} + ${RPCGEN} -h -o ${.TARGET} ${RPCSRC} + +.PATH: ${SRCTOP}/sys/rpc/rpcsec_tls ${SRCTOP}/usr.sbin/rpc.tlsservd + +.include diff --git a/usr.sbin/rpc.tlsclntd/rpc.tlsclntd.8 b/usr.sbin/rpc.tlsclntd/rpc.tlsclntd.8 new file mode 100644 index ..23a9d05495c1 --- /dev/null +++ b/usr.sbin/rpc.tlsclntd/rpc.tlsclntd.8 @@ -0,0 +1,201 @@ +.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/ +.\" Authors: Doug Rabson +.\" Developed with Red Inc: Alfred Perlstein +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\"notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\"notice, this list of conditions and the following disclaimer in the +.\"documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\&quo
git: 59f6f5e23c1a - stable/13 - nfs-over-tls: add rc scripts for rpc.tlsclntd and rpc.tlsservd
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=59f6f5e23c1a33ce0b335b52870fdd9c0223284a commit 59f6f5e23c1a33ce0b335b52870fdd9c0223284a Author: Rick Macklem AuthorDate: 2021-02-18 22:38:01 + Commit: Rick Macklem CommitDate: 2021-03-05 21:55:44 + nfs-over-tls: add rc scripts for rpc.tlsclntd and rpc.tlsservd Add rc.d scripts that control the recently committed rpc.tlsclntd(8) and rpc.tlsservd(8) daemons. (cherry picked from commit 2f48313ab26ef257ca8d46052a33fb6ad6abdb4f) --- libexec/rc/rc.conf | 4 libexec/rc/rc.d/Makefile | 4 libexec/rc/rc.d/tlsclntd | 21 + libexec/rc/rc.d/tlsservd | 25 + 4 files changed, 54 insertions(+) diff --git a/libexec/rc/rc.conf b/libexec/rc/rc.conf index 56d6bb30f811..53bd8c81c2d7 100644 --- a/libexec/rc/rc.conf +++ b/libexec/rc/rc.conf @@ -385,6 +385,10 @@ nfscbd_enable="NO" # NFSv4 client side callback daemon nfscbd_flags=""# Flags for nfscbd nfsuserd_enable="NO" # NFSv4 user/group name mapping daemon nfsuserd_flags="" # Flags for nfsuserd +tlsclntd_enable="NO" # Run rpc.tlsclntd needed for NFS-over-TLS mount +tlsclntd_flags="" # Flags for rpc.tlsclntd +tlsservd_enable="NO" # Run rpc.tlsservd needed for NFS-over-TLS nfsd +tlsservd_flags="" # Flags for rpc.tlsservd ### Network Time Services options: ### timed_enable="NO" # Run the time daemon (or NO). diff --git a/libexec/rc/rc.d/Makefile b/libexec/rc/rc.d/Makefile index a8277e08932c..1a61e89aa215 100644 --- a/libexec/rc/rc.d/Makefile +++ b/libexec/rc/rc.d/Makefile @@ -271,6 +271,10 @@ _opensm= opensm .if ${MK_OPENSSL} != "no" CONFS+=keyserv +.if ${MK_OPENSSL_KTLS} != "no" +CONFS+=tlsclntd \ + tlsservd +.endif .endif .if ${MK_OPENSSH} != "no" diff --git a/libexec/rc/rc.d/tlsclntd b/libexec/rc/rc.d/tlsclntd new file mode 100755 index ..4566ceb67abd --- /dev/null +++ b/libexec/rc/rc.d/tlsclntd @@ -0,0 +1,21 @@ +#!/bin/sh +# +# $FreeBSD$ +# + +# PROVIDE: tlsclntd +# REQUIRE: NETWORKING root mountcritlocal sysctl +# BEFORE: nfscbd +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="tlsclntd" +desc="NFS over TLS client side daemon" +rcvar="tlsclntd_enable" +command="/usr/sbin/rpc.${name}" +pidfile="/var/run/rpc.${name}.pid" + +load_rc_config $name + +run_rc_command "$1" diff --git a/libexec/rc/rc.d/tlsservd b/libexec/rc/rc.d/tlsservd new file mode 100755 index ..cca28ed60ffe --- /dev/null +++ b/libexec/rc/rc.d/tlsservd @@ -0,0 +1,25 @@ +#!/bin/sh +# +# $FreeBSD$ +# + +# PROVIDE: tlsservd +# REQUIRE: NETWORKING root mountcritlocal sysctl +# BEFORE: nfsd +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="tlsservd" +desc="NFS over TLS server side daemon" +rcvar="tlsservd_enable" +command="/usr/sbin/rpc.${name}" + +pidfile="/var/run/rpc.${name}.pid" +required_files="/etc/rpc.tlsservd/cert.pem /etc/rpc.tlsservd/certkey.pem" +extra_commands="reload" + + +load_rc_config $name + +run_rc_command "$1" ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 4663b1baa8ac - stable/13 - Add an entry for NFS-over-TLS.
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=4663b1baa8acc35e3bf0ae8dde1ce534c86268e3 commit 4663b1baa8acc35e3bf0ae8dde1ce534c86268e3 Author: Rick Macklem AuthorDate: 2021-03-07 15:11:50 + Commit: Rick Macklem CommitDate: 2021-03-07 15:11:50 + Add an entry for NFS-over-TLS. --- RELNOTES | 9 + 1 file changed, 9 insertions(+) diff --git a/RELNOTES b/RELNOTES index 602170394523..40fae9249b53 100644 --- a/RELNOTES +++ b/RELNOTES @@ -10,6 +10,15 @@ newline. Entries should be separated by a newline. Changes to this file should not be MFCed. +2c76eebca71b, 59f6f5e23c1a: + Add two daemons rpc.tlsclntd(8) and rpc.tlsservd(8) that provide + support for NFS-over-TLS as described in the Internet Draft titled + "Towards Remote Procedure Call Encryption By Default". + These daemons are only built when WITH_OPENSSL_KTLS is specified + and are only tested on amd64 at this time. + They use KTLS to encrypt/decrypt all NFS RPC message traffic, plus + optional verification of machine identity via X.509 certificates. + f76393a6305b6: Add AES-GCM support to armv8crypto(4) providing accelerated support for KTLS, IPsec, and other crypto API consumers. ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 09673fc0f36d - main - mountd(8): generate a syslog message when the "V4:" line is missing
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=09673fc0f36dd1cca74940a240a9ed0f62228084 commit 09673fc0f36dd1cca74940a240a9ed0f62228084 Author: Rick Macklem AuthorDate: 2021-03-09 00:08:02 + Commit: Rick Macklem CommitDate: 2021-03-09 00:08:02 + mountd(8): generate a syslog message when the "V4:" line is missing Daniel reported that NFSv4 mounts were not working despite having set "nfsv4_server_enable=YES" in /etc/rc.conf. Mountd was logging a message that there was no /etc/exports file. He noted that creating a /etc/exports file with a "V4:" line in it was needed make NFSv4 mounts work. At least one "V4:" line in one of the exports(5) file(s) is needed to make NFSv4 mounts work. This patch fixes mountd.c so that it logs a message indicting that there is no "V4:" line in any exports(5) file when NFSv4 mounts are enabled. To avoid this message being generated erroneously, /etc/rc.d/mountd is updated to make sure vfs.nfsd.server_max_nfsvers is properly set before mountd(8) is started. Reported by:debdrup PR: 253901 MFC after: 2 weeks --- libexec/rc/rc.d/mountd | 3 +++ usr.sbin/mountd/mountd.c | 18 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/libexec/rc/rc.d/mountd b/libexec/rc/rc.d/mountd index 85d04c37a018..ba573ad732cc 100755 --- a/libexec/rc/rc.d/mountd +++ b/libexec/rc/rc.d/mountd @@ -34,6 +34,9 @@ mountd_precmd() rc_flags="${rc_flags} -R" else force_depend rpcbind || return 1 + if ! checkyesno nfsv4_server_enable; then + sysctl vfs.nfsd.server_max_nfsvers=3 > /dev/null + fi fi # mountd flags will differ depending on rc.conf settings diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c index 76972c66a6ed..c66ac13b3016 100644 --- a/usr.sbin/mountd/mountd.c +++ b/usr.sbin/mountd/mountd.c @@ -1888,10 +1888,11 @@ get_exportlist(int passno) struct iovec *iov; struct statfs *mntbufp; char errmsg[255]; - int num, i; + int error, i, nfs_maxvers, num; int iovlen; struct nfsex_args eargs; FILE *debug_file; + size_t nfs_maxvers_size; if ((debug_file = fopen(_PATH_MOUNTDDEBUG, "r")) != NULL) { fclose(debug_file); @@ -2015,6 +2016,21 @@ get_exportlist(int passno) read_exportfile(0); } + if (strlen(v4root_dirpath) == 0) { + /* Check to see if a V4: line is needed. */ + nfs_maxvers_size = sizeof(nfs_maxvers); + error = sysctlbyname("vfs.nfsd.server_max_nfsvers", + &nfs_maxvers, &nfs_maxvers_size, NULL, 0); + if (error != 0 || nfs_maxvers < NFS_VER2 || nfs_maxvers > + NFS_VER4) { + syslog(LOG_ERR, "sysctlbyname(vfs.nfsd." + "server_max_nfsvers) failed, defaulting to NFSv3"); + nfs_maxvers = NFS_VER3; + } + if (nfs_maxvers == NFS_VER4) + syslog(LOG_ERR, "NFSv4 requires at least one V4: line"); + } + if (iov != NULL) { /* Free strings allocated by strdup() in getmntopts.c */ free(iov[0].iov_base); /* fstype */ ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: f365c5b0e917 - stable/13 - nfsclient: add checks for a server returning the current directory
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=f365c5b0e917d300d9b4e85443e16b430e57cc51 commit f365c5b0e917d300d9b4e85443e16b430e57cc51 Author: Rick Macklem AuthorDate: 2021-02-28 22:15:32 + Commit: Rick Macklem CommitDate: 2021-03-15 19:31:13 + nfsclient: add checks for a server returning the current directory Commit 3fe2c68ba20f dealt with a panic in cache_enter_time() where the vnode referred to the directory argument. It would also be possible to get these panics if a broken NFS server were to return the directory as an new object being created within the directory or in a Lookup reply. This patch adds checks to avoid the panics and logs messages to indicate that the server is broken for the file object creation cases. (cherry picked from commit 3e04ab36ba5ce5cbbf6d22f17a01a391a04e465f) --- sys/fs/nfsclient/nfs_clvnops.c | 38 +- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 80317cfd7a50..fc5445ef1e76 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -1423,7 +1423,7 @@ nfs_lookup(struct vop_lookup_args *ap) } if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) cnp->cn_flags |= SAVENAME; - if ((cnp->cn_flags & MAKEENTRY) && + if ((cnp->cn_flags & MAKEENTRY) && dvp != newvp && (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN)) && attrflag != 0 && (newvp->v_type != VDIR || dattrflag != 0)) cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime, @@ -1752,9 +1752,14 @@ again: } } if (!error) { - if ((cnp->cn_flags & MAKEENTRY) && attrflag) - cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime, - NULL); + if ((cnp->cn_flags & MAKEENTRY) && attrflag) { + if (dvp != newvp) + cache_enter_time(dvp, newvp, cnp, + &nfsva.na_ctime, NULL); + else + printf("nfs_create: bogus NFS server returned " + "the directory as the new file object\n"); + } *ap->a_vpp = newvp; } else if (NFS_ISV4(dvp)) { error = nfscl_maperr(cnp->cn_thread, error, vap->va_uid, @@ -2126,7 +2131,11 @@ nfs_link(struct vop_link_args *ap) */ if (VFSTONFS(vp->v_mount)->nm_negnametimeo != 0 && (cnp->cn_flags & MAKEENTRY) && attrflag != 0 && error == 0) { - cache_enter_time(tdvp, vp, cnp, &nfsva.na_ctime, NULL); + if (tdvp != vp) + cache_enter_time(tdvp, vp, cnp, &nfsva.na_ctime, NULL); + else + printf("nfs_link: bogus NFS server returned " + "the directory as the new link\n"); } if (error && NFS_ISV4(vp)) error = nfscl_maperr(cnp->cn_thread, error, (uid_t)0, @@ -2205,7 +2214,12 @@ nfs_symlink(struct vop_symlink_args *ap) */ if (VFSTONFS(dvp->v_mount)->nm_negnametimeo != 0 && (cnp->cn_flags & MAKEENTRY) && attrflag != 0 && error == 0) { - cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime, NULL); + if (dvp != newvp) + cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime, + NULL); + else + printf("nfs_symlink: bogus NFS server returned " + "the directory as the new file object\n"); } return (error); } @@ -2278,9 +2292,15 @@ nfs_mkdir(struct vop_mkdir_args *ap) */ if (VFSTONFS(dvp->v_mount)->nm_negnametimeo != 0 && (cnp->cn_flags & MAKEENTRY) && - attrflag != 0 && dattrflag != 0) - cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime, - &dnfsva.na_ctime); + attrflag != 0 && dattrflag != 0) { + if (dvp != newvp) + cache_enter_time(dvp, newvp, cnp, + &nfsva.na_ctime, &dnfsva.na_ctime); + else + printf("nfs_mkdir: bogus NFS server returned " + "the directory that th
git: 3481445f20e2 - stable/13 - nfsclient: add nfs node locking around uses of n_direofoffset
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=3481445f20e2e5b5013fb9b61706032d0e9f3816 commit 3481445f20e2e5b5013fb9b61706032d0e9f3816 Author: Rick Macklem AuthorDate: 2021-02-28 22:53:54 + Commit: Rick Macklem CommitDate: 2021-03-15 19:34:13 + nfsclient: add nfs node locking around uses of n_direofoffset During code inspection I noticed that the n_direofoffset field of the NFS node was being manipulated without any lock being held to make it SMP safe. This patch adds locking of the NFS node's mutex around handling of n_direofoffset to make it SMP safe. I have not seen any failure that could be attributed to n_direofoffset being manipulated concurrently by multiple processors, but I think this is possible, since directories are read with shared vnode locking, plus locks only on individual buffer cache blocks. However, there have been as yet unexplained issues w.r.t reading large directories over NFS that could have conceivably been caused by concurrent manipulation of n_direofoffset. (cherry picked from commit 15bed8c46b32dec19e922cb89e12c8970867a303) --- sys/fs/nfsclient/nfs_clbio.c | 10 ++ sys/fs/nfsclient/nfs_clsubs.c | 3 ++- sys/fs/nfsclient/nfs_clvnops.c | 21 - 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c index 09fedaa47eb8..67bc3b7ce4d5 100644 --- a/sys/fs/nfsclient/nfs_clbio.c +++ b/sys/fs/nfsclient/nfs_clbio.c @@ -584,11 +584,14 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) break; case VDIR: NFSINCRGLOBAL(nfsstatsv1.biocache_readdirs); + NFSLOCKNODE(np); if (np->n_direofoffset && uio->uio_offset >= np->n_direofoffset) { + NFSUNLOCKNODE(np); error = 0; goto out; } + NFSUNLOCKNODE(np); lbn = (uoff_t)uio->uio_offset / NFS_DIRBLKSIZ; on = uio->uio_offset & (NFS_DIRBLKSIZ - 1); bp = nfs_getcacheblk(vp, lbn, NFS_DIRBLKSIZ, td); @@ -620,11 +623,14 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) * NFSERR_BAD_COOKIE (double yuch!). */ for (i = 0; i <= lbn && !error; i++) { + NFSLOCKNODE(np); if (np->n_direofoffset && (i * NFS_DIRBLKSIZ) >= np->n_direofoffset) { + NFSUNLOCKNODE(np); error = 0; goto out; } + NFSUNLOCKNODE(np); bp = nfs_getcacheblk(vp, i, NFS_DIRBLKSIZ, td); if (!bp) { error = newnfs_sigintr(nmp, td); @@ -667,11 +673,13 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) * (You need the current block first, so that you have the * directory offset cookie of the next block.) */ + NFSLOCKNODE(np); if (nmp->nm_readahead > 0 && (bp->b_flags & B_INVAL) == 0 && (np->n_direofoffset == 0 || (lbn + 1) * NFS_DIRBLKSIZ < np->n_direofoffset) && incore(&vp->v_bufobj, lbn + 1) == NULL) { + NFSUNLOCKNODE(np); rabp = nfs_getcacheblk(vp, lbn + 1, NFS_DIRBLKSIZ, td); if (rabp) { if ((rabp->b_flags & (B_CACHE|B_DELWRI)) == 0) { @@ -688,6 +696,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) brelse(rabp); } } + NFSLOCKNODE(np); } /* * Unlike VREG files, whos buffer size ( bp->b_bcount ) is @@ -704,6 +713,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) n = lmin(uio->uio_resid, NFS_DIRBLKSIZ - bp->b_resid - on); if (np->n_direofoffset && n > np->n_direofoffset - uio->uio_offset) n = np->n_direofoffset - uio->uio_offset; + NFSUNLOCKNODE(np); break; default: printf(" ncl_bioread: type %x unexpected\n", vp->v_type); diff --git a/sys/fs/nfsclient/nfs_clsubs.c b/s
git: 5d1da3a15b8d - stable/13 - nfsclient: Fix the stripe unit size for a File Layout pNFS layout
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=5d1da3a15b8d62839194dbf02c24b794b43c1fc0 commit 5d1da3a15b8d62839194dbf02c24b794b43c1fc0 Author: Rick Macklem AuthorDate: 2021-03-01 20:49:32 + Commit: Rick Macklem CommitDate: 2021-03-15 19:37:13 + nfsclient: Fix the stripe unit size for a File Layout pNFS layout During a recent virtual NFSv4 testing event, a bug in the FreeBSD client was detected when doing a File Layout pNFS DS I/O operation. The size of the I/O operation was smaller than expected. The I/O size is specified as a stripe unit size in bits 6->31 of nflh_util in the layout. I had misinterpreted RFC5661 and had shifted the value right by 6 bits. The correct interpretation is to use the value as presented (it is always an exact multiple of 64), clearing bits 0->5. This patch fixes this. Without the patch, I/O through the DSs work, but the I/O size is 1/64th of what is optimal. (cherry picked from commit 94f2e42f5e0b78a7a4684d4a4eb62ea470a57eb1) --- sys/fs/nfsclient/nfs_clrpcops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index c95d4dc58e7a..0e503e34810b 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -6024,7 +6024,7 @@ nfscl_doflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, np = VTONFS(vp); rel_off = off - flp->nfsfl_patoff; - stripe_unit_size = (flp->nfsfl_util >> 6) & 0x3ff; + stripe_unit_size = flp->nfsfl_util & NFSFLAYUTIL_STRIPE_MASK; stripe_pos = (rel_off / stripe_unit_size + flp->nfsfl_stripe1) % dp->nfsdi_stripecnt; transfer = stripe_unit_size - (rel_off % stripe_unit_size); ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 3a0ffc48b739 - stable/13 - nfsclient: Fix ReadDS/WriteDS/CommitDS nfsstats RPC counts for a NFSv3 DS
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=3a0ffc48b7391ae07bc5f679e34c3facdad5cf8b commit 3a0ffc48b7391ae07bc5f679e34c3facdad5cf8b Author: Rick Macklem AuthorDate: 2021-03-02 22:18:23 + Commit: Rick Macklem CommitDate: 2021-03-15 19:38:49 + nfsclient: Fix ReadDS/WriteDS/CommitDS nfsstats RPC counts for a NFSv3 DS During a recent virtual NFSv4 testing event, a bug in the FreeBSD client was detected when doing I/O DS operations on a Flexible File Layout pNFS server. For an NFSv3 DS, the Read/Write/Commit nfsstats were incremented instead of the ReadDS/WriteDS/CommitDS counts. This patch fixes this. Only the RPC counts reported by nfsstat(1) were affected by this bug, the I/O operations were performed correctly. (cherry picked from commit c04199affeacbd9e9dda3aaf5ca0b1b180031e78) --- sys/fs/nfs/nfsport.h| 1 + sys/fs/nfsclient/nfs_clrpcops.c | 12 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h index 9f2789f57bec..255c9a47ebdf 100644 --- a/sys/fs/nfs/nfsport.h +++ b/sys/fs/nfs/nfsport.h @@ -1006,6 +1006,7 @@ bool ncl_pager_setsize(struct vnode *vp, u_quad_t *nsizep); * "out by one" without disastrous consequences. */ #defineNFSINCRGLOBAL(a)((a)++) +#defineNFSDECRGLOBAL(a)((a)--) /* * Assorted funky stuff to make things work under Darwin8. diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 0e503e34810b..527a47338b3f 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -65,6 +65,7 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, dssameconn, CTLFLAG_RW, /* * Global variables */ +extern struct nfsstatsv1 nfsstatsv1; extern int nfs_numnfscbd; extern struct timeval nfsboottime; extern u_int32_t newnfs_false, newnfs_true; @@ -6320,6 +6321,8 @@ nfsrpc_readds(vnode_t vp, struct uio *uiop, nfsv4stateid_t *stateidp, int *eofp, } else { nfscl_reqstart(nd, NFSPROC_READ, nmp, fhp->nfh_fh, fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSDECRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_READ]); + NFSINCRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_READDS]); NFSCL_DEBUG(4, "nfsrpc_readds: vers3\n"); } NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED * 3); @@ -6395,6 +6398,8 @@ nfsrpc_writeds(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, } else { nfscl_reqstart(nd, NFSPROC_WRITE, nmp, fhp->nfh_fh, fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSDECRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_WRITE]); + NFSINCRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_WRITEDS]); NFSCL_DEBUG(4, "nfsrpc_writeds: vers3\n"); NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + 3 * NFSX_UNSIGNED); } @@ -6522,6 +6527,8 @@ nfsrpc_writedsmir(vnode_t vp, int *iomode, int *must_commit, } else { nfscl_reqstart(nd, NFSPROC_WRITE, nmp, fhp->nfh_fh, fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSDECRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_WRITE]); + NFSINCRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_WRITEDS]); NFSCL_DEBUG(4, "nfsrpc_writedsmir: vers3\n"); NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + 3 * NFSX_UNSIGNED); } @@ -6737,9 +6744,12 @@ nfsrpc_commitds(vnode_t vp, uint64_t offset, int cnt, struct nfsclds *dsp, nfscl_reqstart(nd, NFSPROC_COMMITDS, nmp, fhp->nfh_fh, fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); vers = NFS_VER4; - } else + } else { nfscl_reqstart(nd, NFSPROC_COMMIT, nmp, fhp->nfh_fh, fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSDECRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_COMMIT]); + NFSINCRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_COMMITDS]); + } NFSCL_DEBUG(4, "nfsrpc_commitds: vers=%d minvers=%d\n", vers, minorvers); NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + NFSX_UNSIGNED); ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: c33a5277a0dd - stable/12 - nfsclient: fix panic in cache_enter_time()
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=c33a5277a0dd605356f905c9f5e0934362c0c877 commit c33a5277a0dd605356f905c9f5e0934362c0c877 Author: Rick Macklem AuthorDate: 2021-02-28 01:54:05 + Commit: Rick Macklem CommitDate: 2021-03-15 19:44:39 + nfsclient: fix panic in cache_enter_time() Juraj Lutter (otis@) reported a panic "dvp != vp not true" in cache_enter_time() called from the NFS client's nfsrpc_readdirplus() function. This is specific to an NFSv3 mount with the "rdirplus" mount option. Unlike NFSv4, NFSv3 replies to ReaddirPlus includes entries for the current directory. This trivial patch avoids doing a cache_enter_time() call for the current directory to avoid the panic. (cherry picked from commit 3fe2c68ba20fb3365ef91e0b85f88237b5369f38) --- sys/fs/nfsclient/nfs_clrpcops.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 901f5f7e906d..e1c5c7ff3316 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -3668,6 +3668,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep, ndp->ni_vp = newvp; NFSCNHASH(cnp, HASHINIT); if (cnp->cn_namelen <= NCHNAMLEN && + ndp->ni_dvp != ndp->ni_vp && (newvp->v_type != VDIR || dctime.tv_sec != 0)) { cache_enter_time(ndp->ni_dvp, ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: b6b901f8f8a7 - stable/12 - nfsclient: add checks for a server returning the current directory
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=b6b901f8f8a77ce37a7807ac152e971d43e2291e commit b6b901f8f8a77ce37a7807ac152e971d43e2291e Author: Rick Macklem AuthorDate: 2021-02-28 22:15:32 + Commit: Rick Macklem CommitDate: 2021-03-15 19:46:23 + nfsclient: add checks for a server returning the current directory Commit 3fe2c68ba20f dealt with a panic in cache_enter_time() where the vnode referred to the directory argument. It would also be possible to get these panics if a broken NFS server were to return the directory as an new object being created within the directory or in a Lookup reply. This patch adds checks to avoid the panics and logs messages to indicate that the server is broken for the file object creation cases. (cherry picked from commit 3e04ab36ba5ce5cbbf6d22f17a01a391a04e465f) --- sys/fs/nfsclient/nfs_clvnops.c | 38 +- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 478ee059fe84..9fbf9173434f 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -1378,7 +1378,7 @@ nfs_lookup(struct vop_lookup_args *ap) } if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) cnp->cn_flags |= SAVENAME; - if ((cnp->cn_flags & MAKEENTRY) && + if ((cnp->cn_flags & MAKEENTRY) && dvp != newvp && (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN)) && attrflag != 0 && (newvp->v_type != VDIR || dattrflag != 0)) cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime, @@ -1707,9 +1707,14 @@ again: } } if (!error) { - if ((cnp->cn_flags & MAKEENTRY) && attrflag) - cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime, - NULL); + if ((cnp->cn_flags & MAKEENTRY) && attrflag) { + if (dvp != newvp) + cache_enter_time(dvp, newvp, cnp, + &nfsva.na_ctime, NULL); + else + printf("nfs_create: bogus NFS server returned " + "the directory as the new file object\n"); + } *ap->a_vpp = newvp; } else if (NFS_ISV4(dvp)) { error = nfscl_maperr(cnp->cn_thread, error, vap->va_uid, @@ -2081,7 +2086,11 @@ nfs_link(struct vop_link_args *ap) */ if (VFSTONFS(vp->v_mount)->nm_negnametimeo != 0 && (cnp->cn_flags & MAKEENTRY) && attrflag != 0 && error == 0) { - cache_enter_time(tdvp, vp, cnp, &nfsva.na_ctime, NULL); + if (tdvp != vp) + cache_enter_time(tdvp, vp, cnp, &nfsva.na_ctime, NULL); + else + printf("nfs_link: bogus NFS server returned " + "the directory as the new link\n"); } if (error && NFS_ISV4(vp)) error = nfscl_maperr(cnp->cn_thread, error, (uid_t)0, @@ -2160,7 +2169,12 @@ nfs_symlink(struct vop_symlink_args *ap) */ if (VFSTONFS(dvp->v_mount)->nm_negnametimeo != 0 && (cnp->cn_flags & MAKEENTRY) && attrflag != 0 && error == 0) { - cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime, NULL); + if (dvp != newvp) + cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime, + NULL); + else + printf("nfs_symlink: bogus NFS server returned " + "the directory as the new file object\n"); } return (error); } @@ -2233,9 +2247,15 @@ nfs_mkdir(struct vop_mkdir_args *ap) */ if (VFSTONFS(dvp->v_mount)->nm_negnametimeo != 0 && (cnp->cn_flags & MAKEENTRY) && - attrflag != 0 && dattrflag != 0) - cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime, - &dnfsva.na_ctime); + attrflag != 0 && dattrflag != 0) { + if (dvp != newvp) + cache_enter_time(dvp, newvp, cnp, + &nfsva.na_ctime, &dnfsva.na_ctime); + else + printf("nfs_mkdir: bogus NFS server returned " + "the directory that th
git: a1224bee90c6 - stable/12 - nfsclient: add nfs node locking around uses of n_direofoffset
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=a1224bee90c6a54909d279ec631ea2ad8241ddf4 commit a1224bee90c6a54909d279ec631ea2ad8241ddf4 Author: Rick Macklem AuthorDate: 2021-02-28 22:53:54 + Commit: Rick Macklem CommitDate: 2021-03-15 19:48:37 + nfsclient: add nfs node locking around uses of n_direofoffset During code inspection I noticed that the n_direofoffset field of the NFS node was being manipulated without any lock being held to make it SMP safe. This patch adds locking of the NFS node's mutex around handling of n_direofoffset to make it SMP safe. I have not seen any failure that could be attributed to n_direofoffset being manipulated concurrently by multiple processors, but I think this is possible, since directories are read with shared vnode locking, plus locks only on individual buffer cache blocks. However, there have been as yet unexplained issues w.r.t reading large directories over NFS that could have conceivably been caused by concurrent manipulation of n_direofoffset. (cherry picked from commit 15bed8c46b32dec19e922cb89e12c8970867a303) --- sys/fs/nfsclient/nfs_clbio.c | 10 ++ sys/fs/nfsclient/nfs_clsubs.c | 3 ++- sys/fs/nfsclient/nfs_clvnops.c | 21 - 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c index 01595eea414b..5ba75491a800 100644 --- a/sys/fs/nfsclient/nfs_clbio.c +++ b/sys/fs/nfsclient/nfs_clbio.c @@ -584,11 +584,14 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) break; case VDIR: NFSINCRGLOBAL(nfsstatsv1.biocache_readdirs); + NFSLOCKNODE(np); if (np->n_direofoffset && uio->uio_offset >= np->n_direofoffset) { + NFSUNLOCKNODE(np); error = 0; goto out; } + NFSUNLOCKNODE(np); lbn = (uoff_t)uio->uio_offset / NFS_DIRBLKSIZ; on = uio->uio_offset & (NFS_DIRBLKSIZ - 1); bp = nfs_getcacheblk(vp, lbn, NFS_DIRBLKSIZ, td); @@ -620,11 +623,14 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) * NFSERR_BAD_COOKIE (double yuch!). */ for (i = 0; i <= lbn && !error; i++) { + NFSLOCKNODE(np); if (np->n_direofoffset && (i * NFS_DIRBLKSIZ) >= np->n_direofoffset) { + NFSUNLOCKNODE(np); error = 0; goto out; } + NFSUNLOCKNODE(np); bp = nfs_getcacheblk(vp, i, NFS_DIRBLKSIZ, td); if (!bp) { error = newnfs_sigintr(nmp, td); @@ -667,11 +673,13 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) * (You need the current block first, so that you have the * directory offset cookie of the next block.) */ + NFSLOCKNODE(np); if (nmp->nm_readahead > 0 && (bp->b_flags & B_INVAL) == 0 && (np->n_direofoffset == 0 || (lbn + 1) * NFS_DIRBLKSIZ < np->n_direofoffset) && incore(&vp->v_bufobj, lbn + 1) == NULL) { + NFSUNLOCKNODE(np); rabp = nfs_getcacheblk(vp, lbn + 1, NFS_DIRBLKSIZ, td); if (rabp) { if ((rabp->b_flags & (B_CACHE|B_DELWRI)) == 0) { @@ -688,6 +696,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) brelse(rabp); } } + NFSLOCKNODE(np); } /* * Unlike VREG files, whos buffer size ( bp->b_bcount ) is @@ -704,6 +713,7 @@ ncl_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) n = lmin(uio->uio_resid, NFS_DIRBLKSIZ - bp->b_resid - on); if (np->n_direofoffset && n > np->n_direofoffset - uio->uio_offset) n = np->n_direofoffset - uio->uio_offset; + NFSUNLOCKNODE(np); break; default: printf(" ncl_bioread: type %x unexpected\n", vp->v_type); diff --git a/sys/fs/nfsclient/nfs_clsubs.c b/s
git: f419fd9ad817 - stable/12 - nfsclient: Fix the stripe unit size for a File Layout pNFS layout
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=f419fd9ad81707f831a48412ecbc5c958675d38c commit f419fd9ad81707f831a48412ecbc5c958675d38c Author: Rick Macklem AuthorDate: 2021-03-01 20:49:32 + Commit: Rick Macklem CommitDate: 2021-03-15 19:51:26 + nfsclient: Fix the stripe unit size for a File Layout pNFS layout During a recent virtual NFSv4 testing event, a bug in the FreeBSD client was detected when doing a File Layout pNFS DS I/O operation. The size of the I/O operation was smaller than expected. The I/O size is specified as a stripe unit size in bits 6->31 of nflh_util in the layout. I had misinterpreted RFC5661 and had shifted the value right by 6 bits. The correct interpretation is to use the value as presented (it is always an exact multiple of 64), clearing bits 0->5. This patch fixes this. Without the patch, I/O through the DSs work, but the I/O size is 1/64th of what is optimal. (cherry picked from commit 94f2e42f5e0b78a7a4684d4a4eb62ea470a57eb1) --- sys/fs/nfsclient/nfs_clrpcops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index e1c5c7ff3316..cab5ec4005ba 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -5911,7 +5911,7 @@ nfscl_doflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, np = VTONFS(vp); rel_off = off - flp->nfsfl_patoff; - stripe_unit_size = (flp->nfsfl_util >> 6) & 0x3ff; + stripe_unit_size = flp->nfsfl_util & NFSFLAYUTIL_STRIPE_MASK; stripe_pos = (rel_off / stripe_unit_size + flp->nfsfl_stripe1) % dp->nfsdi_stripecnt; transfer = stripe_unit_size - (rel_off % stripe_unit_size); ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 960f07a448d0 - stable/12 - nfsclient: Fix ReadDS/WriteDS/CommitDS nfsstats RPC counts for a NFSv3 DS
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=960f07a448d01b09595732cf87afe7ba657564b4 commit 960f07a448d01b09595732cf87afe7ba657564b4 Author: Rick Macklem AuthorDate: 2021-03-02 22:18:23 + Commit: Rick Macklem CommitDate: 2021-03-15 19:52:46 + nfsclient: Fix ReadDS/WriteDS/CommitDS nfsstats RPC counts for a NFSv3 DS During a recent virtual NFSv4 testing event, a bug in the FreeBSD client was detected when doing I/O DS operations on a Flexible File Layout pNFS server. For an NFSv3 DS, the Read/Write/Commit nfsstats were incremented instead of the ReadDS/WriteDS/CommitDS counts. This patch fixes this. Only the RPC counts reported by nfsstat(1) were affected by this bug, the I/O operations were performed correctly. MFC after: 2 weeks (cherry picked from commit c04199affeacbd9e9dda3aaf5ca0b1b180031e78) --- sys/fs/nfs/nfsport.h| 1 + sys/fs/nfsclient/nfs_clrpcops.c | 12 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h index 8d9f5ac42225..177fcad5443d 100644 --- a/sys/fs/nfs/nfsport.h +++ b/sys/fs/nfs/nfsport.h @@ -885,6 +885,7 @@ bool ncl_pager_setsize(struct vnode *vp, u_quad_t *nsizep); * "out by one" without disastrous consequences. */ #defineNFSINCRGLOBAL(a)((a)++) +#defineNFSDECRGLOBAL(a)((a)--) /* * Assorted funky stuff to make things work under Darwin8. diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index cab5ec4005ba..6143edb93895 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -63,6 +63,7 @@ SYSCTL_INT(_vfs_nfs, OID_AUTO, dssameconn, CTLFLAG_RW, /* * Global variables */ +extern struct nfsstatsv1 nfsstatsv1; extern int nfs_numnfscbd; extern struct timeval nfsboottime; extern u_int32_t newnfs_false, newnfs_true; @@ -6177,6 +6178,8 @@ nfsrpc_readds(vnode_t vp, struct uio *uiop, nfsv4stateid_t *stateidp, int *eofp, } else { nfscl_reqstart(nd, NFSPROC_READ, nmp, fhp->nfh_fh, fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSDECRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_READ]); + NFSINCRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_READDS]); NFSCL_DEBUG(4, "nfsrpc_readds: vers3\n"); } NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED * 3); @@ -6252,6 +6255,8 @@ nfsrpc_writeds(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, } else { nfscl_reqstart(nd, NFSPROC_WRITE, nmp, fhp->nfh_fh, fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSDECRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_WRITE]); + NFSINCRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_WRITEDS]); NFSCL_DEBUG(4, "nfsrpc_writeds: vers3\n"); NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + 3 * NFSX_UNSIGNED); } @@ -6378,6 +6383,8 @@ nfsrpc_writedsmir(vnode_t vp, int *iomode, int *must_commit, } else { nfscl_reqstart(nd, NFSPROC_WRITE, nmp, fhp->nfh_fh, fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSDECRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_WRITE]); + NFSINCRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_WRITEDS]); NFSCL_DEBUG(4, "nfsrpc_writedsmir: vers3\n"); NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + 3 * NFSX_UNSIGNED); } @@ -6600,9 +6607,12 @@ nfsrpc_commitds(vnode_t vp, uint64_t offset, int cnt, struct nfsclds *dsp, nfscl_reqstart(nd, NFSPROC_COMMITDS, nmp, fhp->nfh_fh, fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); vers = NFS_VER4; - } else + } else { nfscl_reqstart(nd, NFSPROC_COMMIT, nmp, fhp->nfh_fh, fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers); + NFSDECRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_COMMIT]); + NFSINCRGLOBAL(nfsstatsv1.rpccnt[NFSPROC_COMMITDS]); + } NFSCL_DEBUG(4, "nfsrpc_commitds: vers=%d minvers=%d\n", vers, minorvers); NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + NFSX_UNSIGNED); ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: cd5edc7db261 - main - nfsd: Avoid acquiring a vnode for some NFSv4 Readdir operations
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=cd5edc7db261fb228be4044e6fdd38850eb4e9c4 commit cd5edc7db261fb228be4044e6fdd38850eb4e9c4 Author: Rick Macklem AuthorDate: 2023-10-17 20:55:48 + Commit: Rick Macklem CommitDate: 2023-10-17 20:55:48 + nfsd: Avoid acquiring a vnode for some NFSv4 Readdir operations Without this patch, a NFSv4 Readdir operation acquires the vnode for each entry in the directory. If only the Type, Fileid, Mounted_on_fileid and ReaddirError attributes are requested by a client, acquiring the vnode is not necessary for non-directories. Directory vnodes must be acquired to check for server file system mount points. This patch avoids acquiring the vnode, as above, resulting in a 3-8% improvement in Readdir RPC RTT for some simple tests I did. Note that only non-rdirplus NFSv4 mounts will benefit from this change. Tested during a recent IETF NFSv4 Bakeathon testing event. MFC after: 1 month --- sys/fs/nfsserver/nfs_nfsdport.c | 30 +++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 570ae653e06c..776d5c50861c 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -117,6 +117,11 @@ extern int nfsrv_issuedelegs; extern int nfsrv_dolocallocks; extern struct nfsdevicehead nfsrv_devidhead; +/* Map d_type to vnode type. */ +static uint8_t dtype_to_vnode[DT_WHT + 1] = { VNON, VFIFO, VCHR, VNON, VDIR, +VNON, VBLK, VNON, VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON }; +#defineNFS_DTYPETOVTYPE(t) ((t) <= DT_WHT ? dtype_to_vnode[(t)] : VNON) + static int nfsrv_createiovec(int, struct mbuf **, struct mbuf **, struct iovec **); static int nfsrv_createiovec_extpgs(int, int, struct mbuf **, @@ -2310,7 +2315,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram, caddr_t bpos0, bpos1; u_int64_t off, toff, verf __unused; uint64_t *cookies = NULL, *cookiep; - nfsattrbit_t attrbits, rderrbits, savbits; + nfsattrbit_t attrbits, rderrbits, savbits, refbits; struct uio io; struct iovec iv; struct componentname cn; @@ -2361,9 +2366,20 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram, if (error) goto nfsmout; NFSSET_ATTRBIT(&savbits, &attrbits); + NFSSET_ATTRBIT(&refbits, &attrbits); NFSCLRNOTFILLABLE_ATTRBIT(&attrbits, nd); NFSZERO_ATTRBIT(&rderrbits); NFSSETBIT_ATTRBIT(&rderrbits, NFSATTRBIT_RDATTRERROR); + /* +* If these 4 bits are the only attributes requested by the +* client, they can be satisfied without acquiring the vnode +* for the file object unless it is a directory. +* This will be indicated by savbits being all 0s. +*/ + NFSCLRBIT_ATTRBIT(&savbits, NFSATTRBIT_TYPE); + NFSCLRBIT_ATTRBIT(&savbits, NFSATTRBIT_FILEID); + NFSCLRBIT_ATTRBIT(&savbits, NFSATTRBIT_MOUNTEDONFILEID); + NFSCLRBIT_ATTRBIT(&savbits, NFSATTRBIT_RDATTRERROR); } else { NFSZERO_ATTRBIT(&attrbits); } @@ -2606,7 +2622,10 @@ again: new_mp = mp; mounted_on_fileno = (uint64_t)dp->d_fileno; if ((nd->nd_flag & ND_NFSV3) || - NFSNONZERO_ATTRBIT(&savbits)) { + NFSNONZERO_ATTRBIT(&savbits) || + dp->d_type == DT_UNKNOWN || + (dp->d_type == DT_DIR && +nfsrv_enable_crossmntpt != 0)) { if (nd->nd_flag & ND_NFSV4) refp = nfsv4root_getreferral(NULL, vp, dp->d_fileno); @@ -2743,6 +2762,11 @@ again: break; } } + } else if (NFSNONZERO_ATTRBIT(&attrbits)) { + /* Only need Type and/or Fileid. */ + VATTR_NULL(&nvap->na_vattr); + nvap->na_fileid = dp->d_fileno; + nvap->na_type = NFS_DTYPETOVTYPE(dp->d_type); } /* @@ -2774,7 +2798,7 @@ again: supports_nfsv4acls = 0; if (refp != NULL) { dirlen += nfsrv_putreferralattr(nd, -
git: db7257ef972e - main - nfsd: Fix a server crash
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=db7257ef972ed75e33929d39fd791d3699b53c63 commit db7257ef972ed75e33929d39fd791d3699b53c63 Author: Rick Macklem AuthorDate: 2023-10-18 02:40:23 + Commit: Rick Macklem CommitDate: 2023-10-18 02:43:25 + nfsd: Fix a server crash PR#274346 reports a crash which appears to be caused by a NULL default session being destroyed. This patch should avoid the crash. Tested by: Joshua Kinard PR: 274346 MFC after: 2 weeks --- sys/fs/nfs/nfs_commonkrpc.c | 9 + sys/fs/nfs/nfs_commonsubs.c | 6 -- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 936373c79366..29c7cdbd671c 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -1208,6 +1208,14 @@ tryagain: NFSCL_DEBUG(1, "Got badsession\n"); NFSLOCKCLSTATE(); NFSLOCKMNT(nmp); + if (TAILQ_EMPTY(&nmp->nm_sess)) { + NFSUNLOCKMNT(nmp); + NFSUNLOCKCLSTATE(); + printf("If server has not rebooted, " + "check NFS clients for unique " + "/etc/hostid's\n"); + goto out; + } sep = NFSMNT_MDSSESSION(nmp); if (bcmp(sep->nfsess_sessionid, nd->nd_sequence, NFSX_V4SESSIONID) == 0) { @@ -1388,6 +1396,7 @@ tryagain: nd->nd_repstat = NFSERR_STALEDONTRECOVER; } } +out: #ifdef KDTRACE_HOOKS if (nmp != NULL && dtrace_nfscl_nfs234_done_probe != NULL) { diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index ffe1ec542492..f2305795e53e 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -5141,11 +5141,13 @@ nfsrpc_destroysession(struct nfsmount *nmp, struct nfsclsession *tsep, struct nfsrv_descript *nd = &nfsd; int error; + if (tsep == NULL) + tsep = nfsmnt_mdssession(nmp); + if (tsep == NULL) + return (0); nfscl_reqstart(nd, NFSPROC_DESTROYSESSION, nmp, NULL, 0, NULL, NULL, 0, 0, NULL); NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID); - if (tsep == NULL) - tsep = nfsmnt_mdssession(nmp); bcopy(tsep->nfsess_sessionid, tl, NFSX_V4SESSIONID); nd->nd_flag |= ND_USEGSSNAME; error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred,
git: c4e298251ab0 - main - nfscl: Handle the NFSERR_RETRYUNCACHEDREP error from a NFSv4 server
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=c4e298251ab01665f5bb3edeb740a51331818a45 commit c4e298251ab01665f5bb3edeb740a51331818a45 Author: Rick Macklem AuthorDate: 2023-10-18 19:42:12 + Commit: Rick Macklem CommitDate: 2023-10-18 19:42:12 + nfscl: Handle the NFSERR_RETRYUNCACHEDREP error from a NFSv4 server In a recent email list discussion related to NFSv4 mount problems against a non-FreeBSD NFSv4 server, the reporter of the issue noted that the server had replied 10068 (NFSERR_RETRYUNCACHEDREP). This did not seem related to the mount problem, but I had never seen this error before. It indicates that an RPC retry after a new TCP connection has been established failed because the server did not cache the reply. Since this should only happen for idempotent operations, redoing the RPC should be safe. This patch modifies the NFSv4.1/4.2 client to redo the RPC instead of considering the server error fatal. It should only affect the unusual case where TCP connections to NFSv4 servers are breaking without the NFSv4 server rebooting. Reported by:J David MFC after: 2 weeks --- sys/fs/nfs/nfs_commonkrpc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 29c7cdbd671c..29fbb8dc4351 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -1300,7 +1300,8 @@ tryagain: nd->nd_procnum != NFSPROC_LOCKU))) || (nd->nd_repstat == NFSERR_DELAY && (nd->nd_flag & ND_NFSV4) == 0) || - nd->nd_repstat == NFSERR_RESOURCE) { + nd->nd_repstat == NFSERR_RESOURCE || + nd->nd_repstat == NFSERR_RETRYUNCACHEDREP) { /* Clip at NFS_TRYLATERDEL. */ if (timespeccmp(&trylater_delay, &nfs_trylater_max, >))
git: 57ce37f9dcd0 - main - nfscl: Make NFSv4.2 Copy set atime on infd
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=57ce37f9dcd0ec749e5e4512e1e44eb963565c68 commit 57ce37f9dcd0ec749e5e4512e1e44eb963565c68 Author: Rick Macklem AuthorDate: 2023-10-18 20:07:39 + Commit: Rick Macklem CommitDate: 2023-10-18 20:07:39 + nfscl: Make NFSv4.2 Copy set atime on infd RFC7862 does not specify infile atime behaviour when a NFSv4.2 Copy operation is performed. Since the collective opinion of a mailing list discussion (on freebsd-hackers@) seemed to indicate that copy_file_range(2) should update atime on the infd, even if there is no data copied, this patch attempts to ensure that behaviour. For Copy, it preceeds the Copy operation with a Setattr of TimeAccess_Set(NFSv4. speak for atime) for the invp. For the case where no data will be copied, it does a Setattr RPC to set TimeAccess_Set for the invp. A __FreeBSD_version bump will be done as a separate commit, since this patch changes the internal interface between the nfscommon and nfscl modules. MFC after: 1 month --- sys/fs/nfs/nfs_commonsubs.c | 2 +- sys/fs/nfsclient/nfs_clrpcops.c | 35 +++ sys/fs/nfsclient/nfs_clvnops.c | 21 ++--- 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index f2305795e53e..832713e6c1de 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -296,7 +296,7 @@ static struct { { NFSV4OP_OPEN, 8, "CreateLayGet", 12, }, { NFSV4OP_IOADVISE, 1, "Advise", 6, }, { NFSV4OP_ALLOCATE, 2, "Allocate", 8, }, - { NFSV4OP_SAVEFH, 5, "Copy", 4, }, + { NFSV4OP_SAVEFH, 6, "Copy", 4, }, { NFSV4OP_SEEK, 2, "Seek", 4, }, { NFSV4OP_SEEK, 1, "SeekDS", 6, }, { NFSV4OP_GETXATTR, 2, "Getxattr", 8, }, diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 8fe9158384a0..14351d915ba2 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -8617,6 +8617,7 @@ nfsrpc_copyrpc(vnode_t invp, off_t inoff, vnode_t outvp, off_t outoff, struct nfsrv_descript *nd = &nfsd; struct nfsmount *nmp; nfsattrbit_t attrbits; + struct vattr va; uint64_t len; nmp = VFSTONFS(outvp->v_mount); @@ -8627,14 +8628,35 @@ nfsrpc_copyrpc(vnode_t invp, off_t inoff, vnode_t outvp, off_t outoff, if (len > nfs_maxcopyrange) len = nfs_maxcopyrange; NFSCL_REQSTART(nd, NFSPROC_COPY, invp, cred); + /* +* First do a Setattr of atime to the server's clock +* time. The FreeBSD "collective" was of the opinion +* that setting atime was necessary for this syscall. +* Do the Setattr before the Copy, so that it can be +* handled well if the server replies NFSERR_DELAY to +* the Setattr operation. +*/ + NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV4OP_SETATTR); + nfsm_stateidtom(nd, instateidp, NFSSTATEID_PUTSTATEID); + VATTR_NULL(&va); + va.va_atime.tv_sec = va.va_atime.tv_nsec = 0; + va.va_vaflags = VA_UTIMES_NULL; + nfscl_fillsattr(nd, &va, invp, 0, 0); + + /* Now Getattr the invp attributes. */ NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(NFSV4OP_GETATTR); NFSGETATTR_ATTRBIT(&attrbits); nfsrv_putattrbit(nd, &attrbits); + + /* Set outvp. */ NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(NFSV4OP_PUTFH); (void)nfsm_fhtom(nmp, nd, VTONFS(outvp)->n_fhp->nfh_fh, VTONFS(outvp)->n_fhp->nfh_len, 0); + + /* Do the Copy. */ NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(NFSV4OP_COPY); nfsm_stateidtom(nd, instateidp, NFSSTATEID_PUTSTATEID); @@ -8649,12 +8671,25 @@ nfsrpc_copyrpc(vnode_t invp, off_t inoff, vnode_t outvp, off_t outoff, *tl++ = newnfs_false; *tl++ = newnfs_true; *tl++ = 0; + + /* Get the outvp attributes. */ *tl = txdr_unsigned(NFSV4OP_GETATTR); NFSWRITEGETATTR_ATTRBIT(&attrbits); nfsrv_putattrbit(nd, &attrbits); + error = nfscl_request(nd, invp, p, cred); if (error != 0) return (error); + /* Skip over the Setattr reply. */ + if ((nd->nd_flag & ND_NOMOREDATA) == 0) { + NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED); + if (*(tl + 1) == 0) { + error = nfsrv_getattrbits(nd, &attrbits, NULL, NULL); + if (error != 0) + goto nfsmout; + }
git: 17f5e2b904af - main - param.h: Bump __FreeBSD_version for commit 57ce37f9dcd0
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=17f5e2b904aff8e4863199a137ee21ef0939bcf4 commit 17f5e2b904aff8e4863199a137ee21ef0939bcf4 Author: Rick Macklem AuthorDate: 2023-10-18 20:12:26 + Commit: Rick Macklem CommitDate: 2023-10-18 20:12:26 + param.h: Bump __FreeBSD_version for commit 57ce37f9dcd0 Commit 57ce37f9dcc0 changed the internal KAPI between the nfscommon and nfscl modules. Both must be rebuilt from sources. --- sys/sys/param.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/sys/param.h b/sys/sys/param.h index 2e4310dac111..929458626a85 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -75,7 +75,7 @@ * cannot include sys/param.h and should only be updated here. */ #undef __FreeBSD_version -#define __FreeBSD_version 151 +#define __FreeBSD_version 152 /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
git: fb7140b1f928 - main - UPDATING: Add entry for commit 57ce37f9dcd0
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=fb7140b1f928a00d03ce2c11a9e6e1b7515272fe commit fb7140b1f928a00d03ce2c11a9e6e1b7515272fe Author: Rick Macklem AuthorDate: 2023-10-18 20:17:42 + Commit: Rick Macklem CommitDate: 2023-10-18 20:17:42 + UPDATING: Add entry for commit 57ce37f9dcd0 --- UPDATING | 4 1 file changed, 4 insertions(+) diff --git a/UPDATING b/UPDATING index b750b2b913b5..9334ebf0dd5e 100644 --- a/UPDATING +++ b/UPDATING @@ -27,6 +27,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 15.x IS SLOW: world, or to merely disable the most expensive debugging functionality at runtime, run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20231018: + Commit 57ce37f9dcd0 changed the internal KAPI between the + nfscommon and nfscl modules. Both must be rebuilt from sources. + 20231010: dialog(1) has been replaced in base by bsddialog(1), while most of the time replacing a dialog(1) call by a bsddialog(1) call works out of the
git: f300335d9aeb - main - nfsd: Fix NFSv4.1/4.2 Claim_Deleg_Cur_FH
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=f300335d9aebf2e99862bf783978bd44ede23550 commit f300335d9aebf2e99862bf783978bd44ede23550 Author: Rick Macklem AuthorDate: 2023-10-19 19:35:35 + Commit: Rick Macklem CommitDate: 2023-10-19 19:35:35 + nfsd: Fix NFSv4.1/4.2 Claim_Deleg_Cur_FH When I implemented a test patch using Open Claim_Deleg_Cur_FH I discovered that the NFSv4.1/4.2 server was broken for this Open option. Fortunately it is never used by the FreeBSD client and never used by other clients unless delegations are enabled. (The FreeBSD NFSv4 server does not have delegations enabled by default.) Claim_Deleg_Cur_FH was broken because the code mistakenly assumed a stateID argument, which is not the case. This patch fixes the bug by changing the XDR parser to not expect a stateID and to fill most of the stateID in from the clientID. The clientID is the first two elements of the "other" array for the stateID and is sufficient to identify which client the delegation is issued to. Since there is only one delegation issued to a client per file, this is sufficient to locate the correct delegation. If you are running non-FreeBSD NFSv4.1/4.2 mounts against the FreeBSD server, you need this patch if you have delegations enabled. PR: 274574 MFC after: 2 weeks --- sys/fs/nfsserver/nfs_nfsdserv.c | 10 -- sys/fs/nfsserver/nfs_nfsdstate.c | 16 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 7d3ebc683d16..3daee65ab83a 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -3000,12 +3000,18 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, */ NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); claim = fxdr_unsigned(int, *tl); - if (claim == NFSV4OPEN_CLAIMDELEGATECUR || claim == - NFSV4OPEN_CLAIMDELEGATECURFH) { + if (claim == NFSV4OPEN_CLAIMDELEGATECUR) { NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID); stateid.seqid = fxdr_unsigned(u_int32_t, *tl++); NFSBCOPY((caddr_t)tl,(caddr_t)stateid.other,NFSX_STATEIDOTHER); stp->ls_flags |= NFSLCK_DELEGCUR; + } else if (claim == NFSV4OPEN_CLAIMDELEGATECURFH) { + /* Fill in most of the stateid from the clientid. */ + stateid.seqid = 0; + stateid.other[0] = clientid.lval[0]; + stateid.other[1] = clientid.lval[1]; + stateid.other[2] = 0; + stp->ls_flags |= NFSLCK_DELEGCUR; } else if (claim == NFSV4OPEN_CLAIMDELEGATEPREV || claim == NFSV4OPEN_CLAIMDELEGATEPREVFH) { stp->ls_flags |= NFSLCK_DELEGPREV; diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index c73840277022..da57ebde7a52 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -2568,6 +2568,10 @@ tryagain: /* * For Delegate_Cur, search for the matching Delegation, * which indicates no conflict. +* For NFSv4.1/4.2 Claim_Deleg_Cur_FH only provides +* the clientid, which is the first two "other" elements +* for the stateid. This should be sufficient, since there +* is only one delegation per client and file. * An old delegation should have been recovered by the * client doing a Claim_DELEGATE_Prev, so I won't let * it match and return NFSERR_EXPIRED. Should I let it @@ -2578,8 +2582,8 @@ tryagain: (((nd->nd_flag & ND_NFSV41) != 0 && stateidp->seqid == 0) || stateidp->seqid == stp->ls_stateid.seqid) && - !NFSBCMP(stateidp->other, stp->ls_stateid.other, - NFSX_STATEIDOTHER)) + stateidp->other[0] == stp->ls_stateid.other[0] && + stateidp->other[1] == stp->ls_stateid.other[1]) break; } if (stp == LIST_END(&lfp->lf_deleg) || @@ -2830,6 +2834,10 @@ tryagain: /* * For Delegate_Cur, search for the matching Delegation, * which indicates no conflict. +* For NFSv4.1/4.2 Claim_Deleg_Cur_FH only provides +* the clientid, which is the first two "other" elements +* for the stateid. This should be sufficient, since there +* is only one delegation per client and file. * An old delegation should have been recovered by the * client doing a Claim_DELEGATE_Prev, so I won't let * it m
git: 196787f79e67 - main - nfscl: Use Claim_Null_FH and Claim_Deleg_Cur_FH
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=196787f79e67374527a1d528a42efa8b31acd9af commit 196787f79e67374527a1d528a42efa8b31acd9af Author: Rick Macklem AuthorDate: 2023-10-20 23:10:25 + Commit: Rick Macklem CommitDate: 2023-10-20 23:10:25 + nfscl: Use Claim_Null_FH and Claim_Deleg_Cur_FH For NFSv4.1/4.2, there are two new options for the Open operation. These two options use the file handle for the file instead of the file handle for the directory plus a file name. By doing so, the client code is simplified (it no longer needs the "nfsv4node" structure attached to the NFS vnode). It also avoids problems caused by another NFS client (or process running locally in the NFS server) doing a rename or remove of the file name between the Lookup and Open. Unfortunately, there was a bug (fixed recently by commit X) in the NFS server which mis-parsed the Claim_Deleg_Cur_FH arguments. To allow this patch to work with the broken FreeBSD NFSv4.1/4.2 server, NFSMNTP_BUGGYFBSDSRV is defined and is set when a correctly formatted Claim_Deleg_Cur_FH fails with NFSERR_EXPIRED. (This is what the old, broken NFS server does, since it erroneously uses the Getattr arguments as a stateID.) Once this flag is set, the client fills in a stateID, to make the broken NFS server happy. Tested at a recent IETF NFSv4 Bakeathon. MFC after: 1 month --- sys/fs/nfsclient/nfs_clport.c | 4 +- sys/fs/nfsclient/nfs_clrpcops.c | 92 +++-- sys/fs/nfsclient/nfs_clstate.c | 47 + sys/fs/nfsclient/nfs_clvnops.c | 16 --- sys/fs/nfsclient/nfsmount.h | 1 + 5 files changed, 114 insertions(+), 46 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c index 8ea50d80ae19..c0318b692d86 100644 --- a/sys/fs/nfsclient/nfs_clport.c +++ b/sys/fs/nfsclient/nfs_clport.c @@ -264,10 +264,10 @@ nfscl_nget(struct mount *mntp, struct vnode *dvp, struct nfsfh *nfhp, np->n_fhp = nfhp; /* -* For NFSv4, we have to attach the directory file handle and +* For NFSv4.0, we have to attach the directory file handle and * file name, so that Open Ops can be done later. */ - if (nmp->nm_flag & NFSMNT_NFSV4) { + if (NFSHASNFSV4(nmp) && !NFSHASNFSV4N(nmp)) { np->n_v4 = malloc(sizeof (struct nfsv4node) + dnp->n_fhp->nfh_len + cnp->cn_namelen - 1, M_NFSV4NODE, M_WAITOK); diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 14351d915ba2..2276e09f6e7e 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -392,16 +392,6 @@ nfsrpc_open(vnode_t vp, int amode, struct ucred *cred, NFSPROC_T *p) nfhp = np->n_fhp; retrycnt = 0; -#ifdef notdef -{ char name[100]; int namel; -namel = (np->n_v4->n4_namelen < 100) ? np->n_v4->n4_namelen : 99; -bcopy(NFS4NODENAME(np->n_v4), name, namel); -name[namel] = '\0'; -printf("rpcopen p=0x%x name=%s",p->p_pid,name); -if (nfhp->nfh_len > 0) printf(" fh=0x%x\n",nfhp->nfh_fh[12]); -else printf(" fhl=0\n"); -} -#endif do { dp = NULL; error = nfscl_open(vp, nfhp->nfh_fh, nfhp->nfh_len, mode, 1, @@ -452,6 +442,39 @@ else printf(" fhl=0\n"); op->nfso_own->nfsow_clp, nfhp->nfh_fh, nfhp->nfh_len, cred, p, &dp); } + } else if (NFSHASNFSV4N(nmp)) { + /* +* For the first attempt, try and get a layout, if +* pNFS is enabled for the mount. +*/ + if (!NFSHASPNFS(nmp) || nfscl_enablecallb == 0 || + nfs_numnfscbd == 0 || + (np->n_flag & NNOLAYOUT) != 0 || retrycnt > 0) + error = nfsrpc_openrpc(nmp, vp, nfhp->nfh_fh, + nfhp->nfh_len, nfhp->nfh_fh, nfhp->nfh_len, + mode, op, NULL, 0, &dp, 0, 0x0, cred, p, 0, + 0); + else + error = nfsrpc_getopenlayout(nmp, vp, + nfhp->nfh_fh, nfhp->nfh_len, nfhp->nfh_fh, + nfhp->nfh_len, mode, op, NULL, 0, &dp, + cred, p); + if (dp != NULL) { + NFSLOCKNODE(np); + np->n_flag &= ~N
git: 14bbf4fe5abb - main - nfscl: Handle a Getattr failure with NFSERR_DELAY following Open
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=14bbf4fe5abb20f1126168e66b03127ae920f78e commit 14bbf4fe5abb20f1126168e66b03127ae920f78e Author: Rick Macklem AuthorDate: 2023-10-22 01:33:33 + Commit: Rick Macklem CommitDate: 2023-10-22 01:33:33 + nfscl: Handle a Getattr failure with NFSERR_DELAY following Open During testing at a recent IETF NFSv4 Bakeathon, a non-FreeBSD server was rebooted. After the reboot, the FreeBSD client sent an Open/Claim_previous with a Getattr after the Open in the same compound. The Open/Claim_previous was done to recover the Open and a Delegation for for a file. The Open succeeded, but the Getattr after the Open failed with NFSERR_DELAY. This resulted in the FreeBSD client retrying the entire RPC over and over again, until the server's recovery grace period ended. Since the Open succeeded, there was no need to retry the entire RPC. This patch modifies the NFSv4 client side recovery Open/Claim_previous RPC reply handling to deal with this case. With this patch, the Getattr reply of NFSERR_DELAY is ignored and the successful Open reply is processed. This bug will not normally affect users, since this non-FreeBSD server is not widely used (it may not even have shipped to any customers). MFC after: 1 month --- sys/fs/nfsclient/nfs_clrpcops.c | 32 +++- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 2276e09f6e7e..87362f2e744f 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -609,7 +609,8 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen, if (error) return (error); NFSCL_INCRSEQID(op->nfso_own->nfsow_seqid, nd); - if (!nd->nd_repstat) { + if (nd->nd_repstat == 0 || (nd->nd_repstat == NFSERR_DELAY && + reclaim != 0 && (nd->nd_flag & ND_NOMOREDATA) == 0)) { NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID + 6 * NFSX_UNSIGNED); op->nfso_stateid.seqid = *tl++; @@ -681,16 +682,29 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen, goto nfsmout; } NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - error = nfsv4_loadattr(nd, NULL, &nfsva, NULL, - NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, - NULL, NULL, NULL, p, cred); - if (error) - goto nfsmout; + /* If the 2nd element == NFS_OK, the Getattr succeeded. */ + if (*++tl == 0) { + KASSERT(nd->nd_repstat == 0, + ("nfsrpc_openrpc: Getattr repstat")); + error = nfsv4_loadattr(nd, NULL, &nfsva, NULL, + NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, + NULL, NULL, NULL, p, cred); + if (error) + goto nfsmout; + } if (ndp != NULL) { - ndp->nfsdl_change = nfsva.na_filerev; - ndp->nfsdl_modtime = nfsva.na_mtime; - ndp->nfsdl_flags |= NFSCLDL_MODTIMESET; + if (reclaim != 0 && dp != NULL) { + ndp->nfsdl_change = dp->nfsdl_change; + ndp->nfsdl_modtime = dp->nfsdl_modtime; + ndp->nfsdl_flags |= NFSCLDL_MODTIMESET; + } else if (nd->nd_repstat == 0) { + ndp->nfsdl_change = nfsva.na_filerev; + ndp->nfsdl_modtime = nfsva.na_mtime; + ndp->nfsdl_flags |= NFSCLDL_MODTIMESET; + } else + ndp->nfsdl_flags |= NFSCLDL_RECALL; } + nd->nd_repstat = 0; if (!reclaim && (rflags & NFSV4OPEN_RESULTCONFIRM)) { do { ret = nfsrpc_openconfirm(vp, newfhp, newfhlen, op,
git: 428879dc9110 - main - kgssapi: Add a new file with a function for a future commit
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=428879dc9110240ad0940c7ac8cd69bcaf6e686e commit 428879dc9110240ad0940c7ac8cd69bcaf6e686e Author: Rick Macklem AuthorDate: 2023-10-23 20:17:16 + Commit: Rick Macklem CommitDate: 2023-10-23 20:17:16 + kgssapi: Add a new file with a function for a future commit A future commit needs a new upcall function that can do reverse DNS in order to generate a "service principal". This patch adds the file. MFC after: 1 month --- sys/kgssapi/gss_ip_to_dns.c | 85 + 1 file changed, 85 insertions(+) diff --git a/sys/kgssapi/gss_ip_to_dns.c b/sys/kgssapi/gss_ip_to_dns.c new file mode 100644 index ..d2be006d5b3e --- /dev/null +++ b/sys/kgssapi/gss_ip_to_dns.c @@ -0,0 +1,85 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2008 Isilon Inc http://www.isilon.com/ + * Authors: Doug Rabson + * Developed with Red Inc: Alfred Perlstein + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *notice, this list of conditions and the following disclaimer in the + *documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "gssd.h" + +OM_uint32 +gss_ip_to_dns(OM_uint32 *minor_status, +char *ip_addr, +char *dns_name) +{ + struct ip_to_dns_res res; + struct ip_to_dns_args args; + enum clnt_stat stat; + CLIENT *cl; + + *minor_status = 0; + cl = kgss_gssd_client(); + if (cl == NULL) + return (GSS_S_FAILURE); + + args.ip_addr.ip_addr_len = strlen(ip_addr); + args.ip_addr.ip_addr_val = mem_alloc(args.ip_addr.ip_addr_len); + memcpy(args.ip_addr.ip_addr_val, ip_addr, args.ip_addr.ip_addr_len); + + bzero(&res, sizeof(res)); + stat = gssd_ip_to_dns_1(&args, &res, cl); + CLNT_RELEASE(cl); + if (stat != RPC_SUCCESS) { + *minor_status = stat; + return (GSS_S_FAILURE); + } + + if (res.major_status != GSS_S_COMPLETE) { + *minor_status = res.minor_status; + return (res.major_status); + } + + if (res.dns_name.dns_name_len == 0 || + res.dns_name.dns_name_len >= NI_MAXHOST) { + *minor_status = 0; + return (GSS_S_FAILURE); + } + + memcpy(dns_name, res.dns_name.dns_name_val, res.dns_name.dns_name_len); + dns_name[res.dns_name.dns_name_len] = '\0'; + + return (GSS_S_COMPLETE); +}
git: dd7d42a1fae5 - main - nfscl/kgssapi: Fix Kerberized NFS mounts to pNFS servers
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=dd7d42a1fae5a4879b62689a165238082421f343 commit dd7d42a1fae5a4879b62689a165238082421f343 Author: Rick Macklem AuthorDate: 2023-10-23 20:21:14 + Commit: Rick Macklem CommitDate: 2023-10-23 20:21:14 + nfscl/kgssapi: Fix Kerberized NFS mounts to pNFS servers During recent testing related to the IETF NFSv4 Bakeathon, it was discovered that Kerberized NFSv4.1/4.2 mounts to pNFS servers (sec=krb5[ip],pnfs mount options) was broken. The FreeBSD client was using the "service principal" for the MDS to try and establish a rpcsec_gss credential for a DS, which is incorrect. (A "service principal" looks like "nfs@" and the for the DS is not the same as the MDS for most pNFS servers.) To fix this, the rpcsec_gss code needs to be able to do a reverse DNS lookup of the DS's IP address. A new kgssapi upcall to the gssd(8) daemon is added by this patch to do the reverse DNS along with a new rpcsec_gss function to generate the "service principal". A separate patch to the gssd(8) will be committed, so that this patch will fix the problem. Without the gssd(8) patch, the new upcall fails and current/incorrect behaviour remains. This bug only affects the rare case of a Kerberized (sec=krb5[ip],pnfs) mount using pNFS. This patch changes the internal KAPI between the kgssapi and nfscl modules, but since I did a version bump a few days ago, I will not do one this time. MFC after: 1 month --- sys/conf/files | 1 + sys/fs/nfs/nfs.h| 1 + sys/fs/nfs/nfs_commonkrpc.c | 13 --- sys/fs/nfsclient/nfs_clrpcops.c | 44 +++-- sys/kgssapi/gss_impl.c | 2 ++ sys/kgssapi/gssapi.h| 18 +++ sys/kgssapi/gssd.x | 14 sys/modules/kgssapi/Makefile| 1 + sys/rpc/rpcsec_gss.h| 17 ++ sys/rpc/rpcsec_gss/svc_rpcsec_gss.c | 31 ++ 10 files changed, 137 insertions(+), 5 deletions(-) diff --git a/sys/conf/files b/sys/conf/files index c127ce7e7103..51d052e3c31d 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -3983,6 +3983,7 @@ kgssapi/gss_get_mic.c optional kgssapi kgssapi/gss_init_sec_context.c optional kgssapi kgssapi/gss_impl.c optional kgssapi kgssapi/gss_import_name.c optional kgssapi +kgssapi/gss_ip_to_dns.coptional kgssapi kgssapi/gss_names.coptional kgssapi kgssapi/gss_pname_to_uid.c optional kgssapi kgssapi/gss_release_buffer.c optional kgssapi diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h index 0ed96fe43c0a..9b09520b3257 100644 --- a/sys/fs/nfs/nfs.h +++ b/sys/fs/nfs/nfs.h @@ -636,6 +636,7 @@ struct nfssockreq { u_int32_t nr_vers; struct __rpc_client *nr_client; AUTH*nr_auth; + charnr_srvprinc[1]; }; /* diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 29fbb8dc4351..7ca150d4f54c 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -599,10 +599,14 @@ nfs_getauth(struct nfssockreq *nrp, int secflavour, char *clnt_principal, else svc = rpc_gss_svc_privacy; - if (clnt_principal == NULL) + if (clnt_principal == NULL) { + NFSCL_DEBUG(1, "nfs_getauth: clnt princ=NULL, " + "srv princ=%s\n", srv_principal); auth = rpc_gss_secfind_call(nrp->nr_client, cred, srv_principal, mech_oid, svc); - else { + } else { + NFSCL_DEBUG(1, "nfs_getauth: clnt princ=%s " + "srv princ=%s\n", clnt_principal, srv_principal); auth = rpc_gss_seccreate_call(nrp->nr_client, cred, clnt_principal, srv_principal, "kerberosv5", svc, NULL, NULL, NULL); @@ -799,7 +803,10 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, secflavour = RPCSEC_GSS_KRB5P; else secflavour = RPCSEC_GSS_KRB5; - srv_principal = NFSMNT_SRVKRBNAME(nmp); + if (nrp->nr_srvprinc[0] == '\0') + srv_principal = NFSMNT_SRVKRBNAME(nmp); + else + srv_principal = nrp->nr_srvprinc; } else if (nmp != NULL && (!NFSHASKERB(nmp) || NFSHASSYSKRB5(nmp)) && nd->nd_procnum != NFSPROC_NULL && (nd->nd_flag & ND_
git: 82ea0132c8b1 - main - gssd: Add support for the new upcall required by commit 428879dc9110
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=82ea0132c8b17a7a6067c8a36c6434e587ede6de commit 82ea0132c8b17a7a6067c8a36c6434e587ede6de Author: Rick Macklem AuthorDate: 2023-10-23 21:41:26 + Commit: Rick Macklem CommitDate: 2023-10-23 21:41:26 + gssd: Add support for the new upcall required by commit 428879dc9110 Commit 428879dc9110 adds a requirement for a new upcall for the gssd(8). This patch adds that upcall. Unfortunately, the old gssd.c would not build against the new patched gssd.x. This patch will fix the build. MFC after: 1 month --- usr.sbin/gssd/gssd.c | 68 1 file changed, 68 insertions(+) diff --git a/usr.sbin/gssd/gssd.c b/usr.sbin/gssd/gssd.c index 59e0fc057f84..a22891f3bebf 100644 --- a/usr.sbin/gssd/gssd.c +++ b/usr.sbin/gssd/gssd.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,7 @@ #ifndef WITHOUT_KERBEROS #include #endif +#include #include #include #include @@ -49,6 +51,8 @@ #include #include #include +#include +#include #include #include #include @@ -624,6 +628,51 @@ gssd_import_name_1_svc(import_name_args *argp, import_name_res *result, struct s return (TRUE); } +/* + * If the name is a numeric IP host address, do a DNS lookup on it and + * return the DNS name in a malloc'd string. + */ +static char * +gssd_conv_ip_to_dns(int len, char *name) +{ + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + char *retcp; + + retcp = NULL; + if (len > 0) { + retcp = mem_alloc(NI_MAXHOST); + memcpy(retcp, name, len); + retcp[len] = '\0'; + if (inet_pton(AF_INET, retcp, &sin.sin_addr) != 0) { + sin.sin_family = AF_INET; + sin.sin_len = sizeof(sin); + sin.sin_port = 0; + if (getnameinfo((struct sockaddr *)&sin, + sizeof(sin), retcp, NI_MAXHOST, + NULL, 0, NI_NAMEREQD) != 0) { + mem_free(retcp, NI_MAXHOST); + return (NULL); + } + } else if (inet_pton(AF_INET6, retcp, &sin6.sin6_addr) != 0) { + sin6.sin6_family = AF_INET6; + sin6.sin6_len = sizeof(sin6); + sin6.sin6_port = 0; + if (getnameinfo((struct sockaddr *)&sin6, + sizeof(sin6), retcp, NI_MAXHOST, + NULL, 0, NI_NAMEREQD) != 0) { + mem_free(retcp, NI_MAXHOST); + return (NULL); + } + } else { + mem_free(retcp, NI_MAXHOST); + return (NULL); + } + gssd_verbose_out("gssd_conv_ip_to_dns: %s\n", retcp); + } + return (retcp); +} + bool_t gssd_canonicalize_name_1_svc(canonicalize_name_args *argp, canonicalize_name_res *result, struct svc_req *rqstp) { @@ -933,6 +982,25 @@ gssd_display_status_1_svc(display_status_args *argp, display_status_res *result, return (TRUE); } +bool_t +gssd_ip_to_dns_1_svc(ip_to_dns_args *argp, ip_to_dns_res *result, struct svc_req *rqstp) +{ + char *host; + + memset(result, 0, sizeof(*result)); + /* Check to see if the name is actually an IP address. */ + host = gssd_conv_ip_to_dns(argp->ip_addr.ip_addr_len, + argp->ip_addr.ip_addr_val); + if (host != NULL) { + result->major_status = GSS_S_COMPLETE; + result->dns_name.dns_name_len = strlen(host); + result->dns_name.dns_name_val = host; + return (TRUE); + } + result->major_status = GSS_S_FAILURE; + return (TRUE); +} + int gssd_1_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result) {
git: 1a878807006c - main - krpc: Display stats of TLS usage
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=1a878807006cc10a5698cbca9e24a38b3412d7ed commit 1a878807006cc10a5698cbca9e24a38b3412d7ed Author: Rick Macklem AuthorDate: 2023-11-02 21:07:01 + Commit: Rick Macklem CommitDate: 2023-11-02 21:07:01 + krpc: Display stats of TLS usage This patch adds some sysctls: kern.rpc.unenc.tx_msgcnt kern.rpc.unenc.tx_msgbytes kern.rpc.unenc.rx_msgcnt kern.rpc.unenc.rx_msgbytes kern.rpc.tls.tx_msgcnt kern.rpc.tls.tx_msgbytes kern.rpc.tls.rx_msgcnt kern.rpc.tls.rx_msgbytes kern.rpc.tls.handshake_success kern.rpc.tls.handshake_failed kern.rpc.tls.alerts which allow a NFS server sysadmin to determine how much NFS-over-TLS is being used. A large number of failed handshakes might also indicate an NFS confirguration problem. This patch moves the definition of "kern.rpc" from the kgssapi module to the krpc module. As such, both modules need to be rebuilt from sources. Since __FreeBSD_version was bumped yesterday, I will not bump it again. Suggested by: gwollman Discussed on: freebsd-current MFC after: 1 month --- sys/rpc/rpcsec_gss/svc_rpcsec_gss.c | 3 +- sys/rpc/rpcsec_tls.h| 4 ++ sys/rpc/rpcsec_tls/rpctls_impl.c| 21 -- sys/rpc/svc_vc.c| 81 + 4 files changed, 104 insertions(+), 5 deletions(-) diff --git a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c index 90aa9e0d7d4f..89526544639a 100644 --- a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c +++ b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c @@ -174,8 +174,7 @@ struct svc_rpc_gss_cookedcred { u_int svc_rpc_gss_client_max = CLIENT_MAX; u_int svc_rpc_gss_client_hash_size = CLIENT_HASH_SIZE; -SYSCTL_NODE(_kern, OID_AUTO, rpc, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, -"RPC"); +SYSCTL_DECL(_kern_rpc); SYSCTL_NODE(_kern_rpc, OID_AUTO, gss, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "GSS"); diff --git a/sys/rpc/rpcsec_tls.h b/sys/rpc/rpcsec_tls.h index 1445c5c35f19..e3eed64863a1 100644 --- a/sys/rpc/rpcsec_tls.h +++ b/sys/rpc/rpcsec_tls.h @@ -86,10 +86,14 @@ boolrpctls_getinfo(u_int *maxlen, bool rpctlscd_run, /* Macros for VIMAGE. */ /* Just define the KRPC_VNETxxx() macros as VNETxxx() macros. */ +#defineKRPC_VNET_NAME(n) VNET_NAME(n) +#defineKRPC_VNET_DECLARE(t, n) VNET_DECLARE(t, n) #defineKRPC_VNET_DEFINE(t, n) VNET_DEFINE(t, n) #defineKRPC_VNET_DEFINE_STATIC(t, n) VNET_DEFINE_STATIC(t, n) #defineKRPC_VNET(n)VNET(n) +#defineCTLFLAG_KRPC_VNET CTLFLAG_VNET + #defineKRPC_CURVNET_SET(n) CURVNET_SET(n) #defineKRPC_CURVNET_SET_QUIET(n) CURVNET_SET_QUIET(n) #defineKRPC_CURVNET_RESTORE() CURVNET_RESTORE() diff --git a/sys/rpc/rpcsec_tls/rpctls_impl.c b/sys/rpc/rpcsec_tls/rpctls_impl.c index c0e269e55932..64111eed62c0 100644 --- a/sys/rpc/rpcsec_tls/rpctls_impl.c +++ b/sys/rpc/rpcsec_tls/rpctls_impl.c @@ -78,6 +78,9 @@ static CLIENT *rpctls_connect_cl = NULL; static struct mtx rpctls_server_lock; static struct opaque_auth rpctls_null_verf; +KRPC_VNET_DECLARE(uint64_t, svc_vc_tls_handshake_success); +KRPC_VNET_DECLARE(uint64_t, svc_vc_tls_handshake_failed); + KRPC_VNET_DEFINE_STATIC(CLIENT **, rpctls_server_handle); KRPC_VNET_DEFINE_STATIC(struct socket *, rpctls_server_so) = NULL; KRPC_VNET_DEFINE_STATIC(SVCXPRT *, rpctls_server_xprt) = NULL; @@ -748,25 +751,33 @@ _svcauth_rpcsec_tls(struct svc_req *rqst, struct rpc_msg *msg) u_int maxlen; #endif + KRPC_CURVNET_SET_QUIET(KRPC_TD_TO_VNET(curthread)); + KRPC_VNET(svc_vc_tls_handshake_failed)++; /* Initialize reply. */ rqst->rq_verf = rpctls_null_verf; /* Check client credentials. */ if (rqst->rq_cred.oa_length != 0 || msg->rm_call.cb_verf.oa_length != 0 || - msg->rm_call.cb_verf.oa_flavor != AUTH_NULL) + msg->rm_call.cb_verf.oa_flavor != AUTH_NULL) { + KRPC_CURVNET_RESTORE(); return (AUTH_BADCRED); + } - if (rqst->rq_proc != NULLPROC) + if (rqst->rq_proc != NULLPROC) { + KRPC_CURVNET_RESTORE(); return (AUTH_REJECTEDCRED); + } call_stat = FALSE; #ifdef KERN_TLS if (rpctls_getinfo(&maxlen, false, true)) call_stat = TRUE; #endif - if (!call_stat) + if (!call_stat) { + KRPC_CURVNET_RESTORE(); return (AUTH_REJECTEDCRED); + } /* * Disable reception for the krpc so that the TLS handshake can @@ -787,6 +798,7 @@ _svcauth_rpcsec_tls(struct svc_req *rqst, struct
git: d9e28d5d40c9 - stable/14 - nfsd: Fix NFSv4.1/4.2 Claim_Deleg_Cur_FH
The branch stable/14 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=d9e28d5d40c9888f996e895d4bde51b49e7b0946 commit d9e28d5d40c9888f996e895d4bde51b49e7b0946 Author: Rick Macklem AuthorDate: 2023-10-19 19:35:35 + Commit: Rick Macklem CommitDate: 2023-11-02 22:00:48 + nfsd: Fix NFSv4.1/4.2 Claim_Deleg_Cur_FH When I implemented a test patch using Open Claim_Deleg_Cur_FH I discovered that the NFSv4.1/4.2 server was broken for this Open option. Fortunately it is never used by the FreeBSD client and never used by other clients unless delegations are enabled. (The FreeBSD NFSv4 server does not have delegations enabled by default.) Claim_Deleg_Cur_FH was broken because the code mistakenly assumed a stateID argument, which is not the case. This patch fixes the bug by changing the XDR parser to not expect a stateID and to fill most of the stateID in from the clientID. The clientID is the first two elements of the "other" array for the stateID and is sufficient to identify which client the delegation is issued to. Since there is only one delegation issued to a client per file, this is sufficient to locate the correct delegation. If you are running non-FreeBSD NFSv4.1/4.2 mounts against the FreeBSD server, you need this patch if you have delegations enabled. PR: 274574 (cherry picked from commit f300335d9aebf2e99862bf783978bd44ede23550) --- sys/fs/nfsserver/nfs_nfsdserv.c | 10 -- sys/fs/nfsserver/nfs_nfsdstate.c | 16 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 7d3ebc683d16..3daee65ab83a 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -3000,12 +3000,18 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, */ NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); claim = fxdr_unsigned(int, *tl); - if (claim == NFSV4OPEN_CLAIMDELEGATECUR || claim == - NFSV4OPEN_CLAIMDELEGATECURFH) { + if (claim == NFSV4OPEN_CLAIMDELEGATECUR) { NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID); stateid.seqid = fxdr_unsigned(u_int32_t, *tl++); NFSBCOPY((caddr_t)tl,(caddr_t)stateid.other,NFSX_STATEIDOTHER); stp->ls_flags |= NFSLCK_DELEGCUR; + } else if (claim == NFSV4OPEN_CLAIMDELEGATECURFH) { + /* Fill in most of the stateid from the clientid. */ + stateid.seqid = 0; + stateid.other[0] = clientid.lval[0]; + stateid.other[1] = clientid.lval[1]; + stateid.other[2] = 0; + stp->ls_flags |= NFSLCK_DELEGCUR; } else if (claim == NFSV4OPEN_CLAIMDELEGATEPREV || claim == NFSV4OPEN_CLAIMDELEGATEPREVFH) { stp->ls_flags |= NFSLCK_DELEGPREV; diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index c73840277022..da57ebde7a52 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -2568,6 +2568,10 @@ tryagain: /* * For Delegate_Cur, search for the matching Delegation, * which indicates no conflict. +* For NFSv4.1/4.2 Claim_Deleg_Cur_FH only provides +* the clientid, which is the first two "other" elements +* for the stateid. This should be sufficient, since there +* is only one delegation per client and file. * An old delegation should have been recovered by the * client doing a Claim_DELEGATE_Prev, so I won't let * it match and return NFSERR_EXPIRED. Should I let it @@ -2578,8 +2582,8 @@ tryagain: (((nd->nd_flag & ND_NFSV41) != 0 && stateidp->seqid == 0) || stateidp->seqid == stp->ls_stateid.seqid) && - !NFSBCMP(stateidp->other, stp->ls_stateid.other, - NFSX_STATEIDOTHER)) + stateidp->other[0] == stp->ls_stateid.other[0] && + stateidp->other[1] == stp->ls_stateid.other[1]) break; } if (stp == LIST_END(&lfp->lf_deleg) || @@ -2830,6 +2834,10 @@ tryagain: /* * For Delegate_Cur, search for the matching Delegation, * which indicates no conflict. +* For NFSv4.1/4.2 Claim_Deleg_Cur_FH only provides +* the clientid, which is the first two "other" elements +* for the stateid. This should be sufficient, since there +* is only one delegation per client and file. * An old delegation should have been recovered by the * client doing a Clai
git: 098273e649c6 - stable/14 - nfsd: Fix a server crash
The branch stable/14 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=098273e649c647d5472d518c5023477ad15b7c3f commit 098273e649c647d5472d518c5023477ad15b7c3f Author: Rick Macklem AuthorDate: 2023-10-18 02:40:23 + Commit: Rick Macklem CommitDate: 2023-11-02 22:02:22 + nfsd: Fix a server crash PR#274346 reports a crash which appears to be caused by a NULL default session being destroyed. This patch should avoid the crash. PR: 274346 (cherry picked from commit db7257ef972ed75e33929d39fd791d3699b53c63) --- sys/fs/nfs/nfs_commonkrpc.c | 9 + sys/fs/nfs/nfs_commonsubs.c | 6 -- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 936373c79366..29c7cdbd671c 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -1208,6 +1208,14 @@ tryagain: NFSCL_DEBUG(1, "Got badsession\n"); NFSLOCKCLSTATE(); NFSLOCKMNT(nmp); + if (TAILQ_EMPTY(&nmp->nm_sess)) { + NFSUNLOCKMNT(nmp); + NFSUNLOCKCLSTATE(); + printf("If server has not rebooted, " + "check NFS clients for unique " + "/etc/hostid's\n"); + goto out; + } sep = NFSMNT_MDSSESSION(nmp); if (bcmp(sep->nfsess_sessionid, nd->nd_sequence, NFSX_V4SESSIONID) == 0) { @@ -1388,6 +1396,7 @@ tryagain: nd->nd_repstat = NFSERR_STALEDONTRECOVER; } } +out: #ifdef KDTRACE_HOOKS if (nmp != NULL && dtrace_nfscl_nfs234_done_probe != NULL) { diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index ffe1ec542492..f2305795e53e 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -5141,11 +5141,13 @@ nfsrpc_destroysession(struct nfsmount *nmp, struct nfsclsession *tsep, struct nfsrv_descript *nd = &nfsd; int error; + if (tsep == NULL) + tsep = nfsmnt_mdssession(nmp); + if (tsep == NULL) + return (0); nfscl_reqstart(nd, NFSPROC_DESTROYSESSION, nmp, NULL, 0, NULL, NULL, 0, 0, NULL); NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID); - if (tsep == NULL) - tsep = nfsmnt_mdssession(nmp); bcopy(tsep->nfsess_sessionid, tl, NFSX_V4SESSIONID); nd->nd_flag |= ND_USEGSSNAME; error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred,
git: f33609bc7799 - stable/13 - nfsd: Fix NFSv4.1/4.2 Claim_Deleg_Cur_FH
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=f33609bc7799bd1ebefa2f7cad02be646bcf21e9 commit f33609bc7799bd1ebefa2f7cad02be646bcf21e9 Author: Rick Macklem AuthorDate: 2023-10-19 19:35:35 + Commit: Rick Macklem CommitDate: 2023-11-02 23:33:48 + nfsd: Fix NFSv4.1/4.2 Claim_Deleg_Cur_FH When I implemented a test patch using Open Claim_Deleg_Cur_FH I discovered that the NFSv4.1/4.2 server was broken for this Open option. Fortunately it is never used by the FreeBSD client and never used by other clients unless delegations are enabled. (The FreeBSD NFSv4 server does not have delegations enabled by default.) Claim_Deleg_Cur_FH was broken because the code mistakenly assumed a stateID argument, which is not the case. This patch fixes the bug by changing the XDR parser to not expect a stateID and to fill most of the stateID in from the clientID. The clientID is the first two elements of the "other" array for the stateID and is sufficient to identify which client the delegation is issued to. Since there is only one delegation issued to a client per file, this is sufficient to locate the correct delegation. If you are running non-FreeBSD NFSv4.1/4.2 mounts against the FreeBSD server, you need this patch if you have delegations enabled. PR: 274574 (cherry picked from commit f300335d9aebf2e99862bf783978bd44ede23550) --- sys/fs/nfsserver/nfs_nfsdserv.c | 10 -- sys/fs/nfsserver/nfs_nfsdstate.c | 16 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 24d290c4cf5d..7020053be330 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -3003,12 +3003,18 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, */ NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); claim = fxdr_unsigned(int, *tl); - if (claim == NFSV4OPEN_CLAIMDELEGATECUR || claim == - NFSV4OPEN_CLAIMDELEGATECURFH) { + if (claim == NFSV4OPEN_CLAIMDELEGATECUR) { NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID); stateid.seqid = fxdr_unsigned(u_int32_t, *tl++); NFSBCOPY((caddr_t)tl,(caddr_t)stateid.other,NFSX_STATEIDOTHER); stp->ls_flags |= NFSLCK_DELEGCUR; + } else if (claim == NFSV4OPEN_CLAIMDELEGATECURFH) { + /* Fill in most of the stateid from the clientid. */ + stateid.seqid = 0; + stateid.other[0] = clientid.lval[0]; + stateid.other[1] = clientid.lval[1]; + stateid.other[2] = 0; + stp->ls_flags |= NFSLCK_DELEGCUR; } else if (claim == NFSV4OPEN_CLAIMDELEGATEPREV || claim == NFSV4OPEN_CLAIMDELEGATEPREVFH) { stp->ls_flags |= NFSLCK_DELEGPREV; diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index 06d0b79f10d5..f54459947f44 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -2555,6 +2555,10 @@ tryagain: /* * For Delegate_Cur, search for the matching Delegation, * which indicates no conflict. +* For NFSv4.1/4.2 Claim_Deleg_Cur_FH only provides +* the clientid, which is the first two "other" elements +* for the stateid. This should be sufficient, since there +* is only one delegation per client and file. * An old delegation should have been recovered by the * client doing a Claim_DELEGATE_Prev, so I won't let * it match and return NFSERR_EXPIRED. Should I let it @@ -2565,8 +2569,8 @@ tryagain: (((nd->nd_flag & ND_NFSV41) != 0 && stateidp->seqid == 0) || stateidp->seqid == stp->ls_stateid.seqid) && - !NFSBCMP(stateidp->other, stp->ls_stateid.other, - NFSX_STATEIDOTHER)) + stateidp->other[0] == stp->ls_stateid.other[0] && + stateidp->other[1] == stp->ls_stateid.other[1]) break; } if (stp == LIST_END(&lfp->lf_deleg) || @@ -2817,6 +2821,10 @@ tryagain: /* * For Delegate_Cur, search for the matching Delegation, * which indicates no conflict. +* For NFSv4.1/4.2 Claim_Deleg_Cur_FH only provides +* the clientid, which is the first two "other" elements +* for the stateid. This should be sufficient, since there +* is only one delegation per client and file. * An old delegation should have been recovered by the * client doing a Clai
git: 18d51c3c305f - stable/13 - nfsd: Fix a server crash
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=18d51c3c305f233a75fc64f8e5711306dd05a8fc commit 18d51c3c305f233a75fc64f8e5711306dd05a8fc Author: Rick Macklem AuthorDate: 2023-10-18 02:40:23 + Commit: Rick Macklem CommitDate: 2023-11-02 23:35:25 + nfsd: Fix a server crash PR#274346 reports a crash which appears to be caused by a NULL default session being destroyed. This patch should avoid the crash. PR: 274346 (cherry picked from commit db7257ef972ed75e33929d39fd791d3699b53c63) --- sys/fs/nfs/nfs_commonkrpc.c | 9 + sys/fs/nfs/nfs_commonsubs.c | 6 -- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 936373c79366..29c7cdbd671c 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -1208,6 +1208,14 @@ tryagain: NFSCL_DEBUG(1, "Got badsession\n"); NFSLOCKCLSTATE(); NFSLOCKMNT(nmp); + if (TAILQ_EMPTY(&nmp->nm_sess)) { + NFSUNLOCKMNT(nmp); + NFSUNLOCKCLSTATE(); + printf("If server has not rebooted, " + "check NFS clients for unique " + "/etc/hostid's\n"); + goto out; + } sep = NFSMNT_MDSSESSION(nmp); if (bcmp(sep->nfsess_sessionid, nd->nd_sequence, NFSX_V4SESSIONID) == 0) { @@ -1388,6 +1396,7 @@ tryagain: nd->nd_repstat = NFSERR_STALEDONTRECOVER; } } +out: #ifdef KDTRACE_HOOKS if (nmp != NULL && dtrace_nfscl_nfs234_done_probe != NULL) { diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 44cddc6d5b34..a9659079ed5f 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -5083,11 +5083,13 @@ nfsrpc_destroysession(struct nfsmount *nmp, struct nfsclsession *tsep, struct nfsrv_descript *nd = &nfsd; int error; + if (tsep == NULL) + tsep = nfsmnt_mdssession(nmp); + if (tsep == NULL) + return (0); nfscl_reqstart(nd, NFSPROC_DESTROYSESSION, nmp, NULL, 0, NULL, NULL, 0, 0, NULL); NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID); - if (tsep == NULL) - tsep = nfsmnt_mdssession(nmp); bcopy(tsep->nfsess_sessionid, tl, NFSX_V4SESSIONID); nd->nd_flag |= ND_USEGSSNAME; error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred,
git: f383f4ad30a6 - stable/12 - nfsd: Fix NFSv4.1/4.2 Claim_Deleg_Cur_FH
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=f383f4ad30a61fd0cd5104bb5c730aff139b993d commit f383f4ad30a61fd0cd5104bb5c730aff139b993d Author: Rick Macklem AuthorDate: 2023-10-19 19:35:35 + Commit: Rick Macklem CommitDate: 2023-11-02 23:44:27 + nfsd: Fix NFSv4.1/4.2 Claim_Deleg_Cur_FH When I implemented a test patch using Open Claim_Deleg_Cur_FH I discovered that the NFSv4.1/4.2 server was broken for this Open option. Fortunately it is never used by the FreeBSD client and never used by other clients unless delegations are enabled. (The FreeBSD NFSv4 server does not have delegations enabled by default.) Claim_Deleg_Cur_FH was broken because the code mistakenly assumed a stateID argument, which is not the case. This patch fixes the bug by changing the XDR parser to not expect a stateID and to fill most of the stateID in from the clientID. The clientID is the first two elements of the "other" array for the stateID and is sufficient to identify which client the delegation is issued to. Since there is only one delegation issued to a client per file, this is sufficient to locate the correct delegation. If you are running non-FreeBSD NFSv4.1/4.2 mounts against the FreeBSD server, you need this patch if you have delegations enabled. PR: 274574 (cherry picked from commit f300335d9aebf2e99862bf783978bd44ede23550) --- sys/fs/nfsserver/nfs_nfsdserv.c | 10 -- sys/fs/nfsserver/nfs_nfsdstate.c | 16 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index e283e8611944..e5eced9c8a69 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -2913,12 +2913,18 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram, */ NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); claim = fxdr_unsigned(int, *tl); - if (claim == NFSV4OPEN_CLAIMDELEGATECUR || claim == - NFSV4OPEN_CLAIMDELEGATECURFH) { + if (claim == NFSV4OPEN_CLAIMDELEGATECUR) { NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID); stateid.seqid = fxdr_unsigned(u_int32_t, *tl++); NFSBCOPY((caddr_t)tl,(caddr_t)stateid.other,NFSX_STATEIDOTHER); stp->ls_flags |= NFSLCK_DELEGCUR; + } else if (claim == NFSV4OPEN_CLAIMDELEGATECURFH) { + /* Fill in most of the stateid from the clientid. */ + stateid.seqid = 0; + stateid.other[0] = clientid.lval[0]; + stateid.other[1] = clientid.lval[1]; + stateid.other[2] = 0; + stp->ls_flags |= NFSLCK_DELEGCUR; } else if (claim == NFSV4OPEN_CLAIMDELEGATEPREV || claim == NFSV4OPEN_CLAIMDELEGATEPREVFH) { stp->ls_flags |= NFSLCK_DELEGPREV; diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index cb4597ec1575..f5f498f61b6b 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -2529,6 +2529,10 @@ tryagain: /* * For Delegate_Cur, search for the matching Delegation, * which indicates no conflict. +* For NFSv4.1/4.2 Claim_Deleg_Cur_FH only provides +* the clientid, which is the first two "other" elements +* for the stateid. This should be sufficient, since there +* is only one delegation per client and file. * An old delegation should have been recovered by the * client doing a Claim_DELEGATE_Prev, so I won't let * it match and return NFSERR_EXPIRED. Should I let it @@ -2539,8 +2543,8 @@ tryagain: (((nd->nd_flag & ND_NFSV41) != 0 && stateidp->seqid == 0) || stateidp->seqid == stp->ls_stateid.seqid) && - !NFSBCMP(stateidp->other, stp->ls_stateid.other, - NFSX_STATEIDOTHER)) + stateidp->other[0] == stp->ls_stateid.other[0] && + stateidp->other[1] == stp->ls_stateid.other[1]) break; } if (stp == LIST_END(&lfp->lf_deleg) || @@ -2791,6 +2795,10 @@ tryagain: /* * For Delegate_Cur, search for the matching Delegation, * which indicates no conflict. +* For NFSv4.1/4.2 Claim_Deleg_Cur_FH only provides +* the clientid, which is the first two "other" elements +* for the stateid. This should be sufficient, since there +* is only one delegation per client and file. * An old delegation should have been recovered by the * client doing a Clai
git: 7c5146da1286 - main - mountd: Add support for spaces in exported directories
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=7c5146da128688ba2bb6bdad5e98716087a47281 commit 7c5146da128688ba2bb6bdad5e98716087a47281 Author: Dan Mcgregor AuthorDate: 2023-11-04 22:07:56 + Commit: Rick Macklem CommitDate: 2023-11-04 22:07:56 + mountd: Add support for spaces in exported directories The previous code would correctly parse strings including quotation marks (") or backslash (/), but the tests when creating the export includes them in the final string. This prevents exporting paths with embedded spaces, for example "/exports/with space". Trying results in log lines resembling: mountd[1337]: bad exports list line '/exports/with\ space': /exports/with\ space: lstat() failed: No such file or directory. Turns out that when creating its exports list, zfs escapes strings in a format compatible with vis(3). Since I expect that zfs sharenfs is the dominating use case for generating an exports list, use strunvis(3) to parse the export path. The result is lines like the following allowing spaces: /exports/with\040space -network 192.168.0 -mask 255.255.255.0 A man page update will be done as a separate commit. MFC after: 1 month Reviewed by:rmacklem Differential Revision: https://reviews.freebsd.org/D42432 --- usr.sbin/mountd/mountd.c | 32 +++- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c index 6602dbc09aa0..33c19a81a0cf 100644 --- a/usr.sbin/mountd/mountd.c +++ b/usr.sbin/mountd/mountd.c @@ -83,6 +83,7 @@ static char sccsid[] = "@(#)mountd.c 8.15 (Berkeley) 5/1/95"; #include #include #include +#include #include "pathnames.h" #include "mntopts.h" @@ -1561,10 +1562,13 @@ get_exportlist_one(int passno) char *err_msg = NULL; int len, has_host, got_nondir, dirplen, netgrp; uint64_t exflags; + char unvis_dir[PATH_MAX + 1]; + int unvis_len; v4root_phase = 0; anon.cr_groups = NULL; dirhead = (struct dirlist *)NULL; + unvis_dir[0] = '\0'; while (get_line()) { if (debug) warnx("got line %s", line); @@ -1631,17 +1635,25 @@ get_exportlist_one(int passno) } else if (*cp == '/') { savedc = *endcp; *endcp = '\0'; + unvis_len = strnunvis(unvis_dir, sizeof(unvis_dir), + cp); + if (unvis_len <= 0) { + getexp_err(ep, tgrp, "Cannot strunvis " + "decode dir"); + goto nextline; + } if (v4root_phase > 1) { if (dirp != NULL) { getexp_err(ep, tgrp, "Multiple V4 dirs"); goto nextline; } } - if (check_dirpath(cp, &err_msg) && - check_statfs(cp, &fsb, &err_msg)) { + if (check_dirpath(unvis_dir, &err_msg) && + check_statfs(unvis_dir, &fsb, &err_msg)) { if ((fsb.f_flags & MNT_AUTOMOUNTED) != 0) syslog(LOG_ERR, "Warning: exporting of " - "automounted fs %s not supported", cp); + "automounted fs %s not supported", + unvis_dir); if (got_nondir) { getexp_err(ep, tgrp, "dirs must be first"); goto nextline; @@ -1652,16 +1664,17 @@ get_exportlist_one(int passno) goto nextline; } if (strlen(v4root_dirpath) == 0) { - strlcpy(v4root_dirpath, cp, + strlcpy(v4root_dirpath, unvis_dir, sizeof (v4root_dirpath)); - } else if (strcmp(v4root_dirpath, cp) + } else if (strcmp(v4root_dirpath, unvis_dir) != 0) { syslog(LOG_ERR, - "dif
git: 501bdf300119 - main - nfscl: newnfs_copycred() cannot be called when a mutex is held
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=501bdf3001190686bf55d9d333cb533858c2cf2f commit 501bdf3001190686bf55d9d333cb533858c2cf2f Author: Rick Macklem AuthorDate: 2023-11-06 22:25:30 + Commit: Rick Macklem CommitDate: 2023-11-06 22:25:30 + nfscl: newnfs_copycred() cannot be called when a mutex is held Since newnfs_copycred() calls crsetgroups() which in turn calls crextend() which might do a malloc(M_WAITOK), newnfs_copycred() cannot be called with a mutex held. Fortunately, the malloc() call is rarely done, since XU_GROUPS is 16 and the NFS client uses a maximum of 17 (only 17 groups will cause the malloc() to be called). Further, it is only a problem if the malloc() tries to sleep(). As such, this bug does not seem to have caused problems in practice. This patch fixes the one place in the NFS client where newnfs_copycred() is called while a mutex is held by moving the call to after where the mutex is released. Found by inspection while working on an experimental patch. MFC after: 2 weeks --- sys/fs/nfsclient/nfs_clstate.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index 579210941802..ebc11efea637 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -526,6 +526,7 @@ nfscl_getstateid(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t mode, struct nfscldeleg *dp; struct nfsnode *np; struct nfsmount *nmp; + struct nfscred ncr; u_int8_t own[NFSV4CL_LOCKNAMELEN], lockown[NFSV4CL_LOCKNAMELEN]; int error; bool done; @@ -683,7 +684,7 @@ nfscl_getstateid(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t mode, * A read ahead or write behind is indicated by p == NULL. */ if (p == NULL) - newnfs_copycred(&op->nfso_cred, cred); + memcpy(&ncr, &op->nfso_cred, sizeof(ncr)); } /* @@ -697,6 +698,8 @@ nfscl_getstateid(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t mode, stateidp->other[1] = op->nfso_stateid.other[1]; stateidp->other[2] = op->nfso_stateid.other[2]; NFSUNLOCKCLSTATE(); + if (p == NULL) + newnfs_copycred(&ncr, cred); return (0); }
git: 260e63b3d53c - stable/14 - nfscl: Handle the NFSERR_RETRYUNCACHEDREP error from a NFSv4 server
The branch stable/14 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=260e63b3d53c7df51fbe3169a7b96d7c479275af commit 260e63b3d53c7df51fbe3169a7b96d7c479275af Author: Rick Macklem AuthorDate: 2023-10-18 19:42:12 + Commit: Rick Macklem CommitDate: 2023-11-14 02:03:14 + nfscl: Handle the NFSERR_RETRYUNCACHEDREP error from a NFSv4 server In a recent email list discussion related to NFSv4 mount problems against a non-FreeBSD NFSv4 server, the reporter of the issue noted that the server had replied 10068 (NFSERR_RETRYUNCACHEDREP). This did not seem related to the mount problem, but I had never seen this error before. It indicates that an RPC retry after a new TCP connection has been established failed because the server did not cache the reply. Since this should only happen for idempotent operations, redoing the RPC should be safe. This patch modifies the NFSv4.1/4.2 client to redo the RPC instead of considering the server error fatal. It should only affect the unusual case where TCP connections to NFSv4 servers are breaking without the NFSv4 server rebooting. MFC after: 2 weeks (cherry picked from commit c4e298251ab01665f5bb3edeb740a51331818a45) --- sys/fs/nfs/nfs_commonkrpc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 29c7cdbd671c..29fbb8dc4351 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -1300,7 +1300,8 @@ tryagain: nd->nd_procnum != NFSPROC_LOCKU))) || (nd->nd_repstat == NFSERR_DELAY && (nd->nd_flag & ND_NFSV4) == 0) || - nd->nd_repstat == NFSERR_RESOURCE) { + nd->nd_repstat == NFSERR_RESOURCE || + nd->nd_repstat == NFSERR_RETRYUNCACHEDREP) { /* Clip at NFS_TRYLATERDEL. */ if (timespeccmp(&trylater_delay, &nfs_trylater_max, >))
git: bcbbacb7d014 - stable/13 - nfscl: Handle the NFSERR_RETRYUNCACHEDREP error from a NFSv4 server
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=bcbbacb7d014161b2f98b25d81f530cccbc49845 commit bcbbacb7d014161b2f98b25d81f530cccbc49845 Author: Rick Macklem AuthorDate: 2023-10-18 19:42:12 + Commit: Rick Macklem CommitDate: 2023-11-14 02:07:17 + nfscl: Handle the NFSERR_RETRYUNCACHEDREP error from a NFSv4 server In a recent email list discussion related to NFSv4 mount problems against a non-FreeBSD NFSv4 server, the reporter of the issue noted that the server had replied 10068 (NFSERR_RETRYUNCACHEDREP). This did not seem related to the mount problem, but I had never seen this error before. It indicates that an RPC retry after a new TCP connection has been established failed because the server did not cache the reply. Since this should only happen for idempotent operations, redoing the RPC should be safe. This patch modifies the NFSv4.1/4.2 client to redo the RPC instead of considering the server error fatal. It should only affect the unusual case where TCP connections to NFSv4 servers are breaking without the NFSv4 server rebooting. MFC after: 2 weeks (cherry picked from commit c4e298251ab01665f5bb3edeb740a51331818a45) --- sys/fs/nfs/nfs_commonkrpc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 29c7cdbd671c..29fbb8dc4351 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -1300,7 +1300,8 @@ tryagain: nd->nd_procnum != NFSPROC_LOCKU))) || (nd->nd_repstat == NFSERR_DELAY && (nd->nd_flag & ND_NFSV4) == 0) || - nd->nd_repstat == NFSERR_RESOURCE) { + nd->nd_repstat == NFSERR_RESOURCE || + nd->nd_repstat == NFSERR_RETRYUNCACHEDREP) { /* Clip at NFS_TRYLATERDEL. */ if (timespeccmp(&trylater_delay, &nfs_trylater_max, >))
git: f40c9502c438 - stable/14 - nfsd: Avoid acquiring a vnode for some NFSv4 Readdir operations
The branch stable/14 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=f40c9502c438d230a06157ec7f9be1c21ae46541 commit f40c9502c438d230a06157ec7f9be1c21ae46541 Author: Rick Macklem AuthorDate: 2023-10-17 20:55:48 + Commit: Rick Macklem CommitDate: 2023-11-16 23:46:17 + nfsd: Avoid acquiring a vnode for some NFSv4 Readdir operations Without this patch, a NFSv4 Readdir operation acquires the vnode for each entry in the directory. If only the Type, Fileid, Mounted_on_fileid and ReaddirError attributes are requested by a client, acquiring the vnode is not necessary for non-directories. Directory vnodes must be acquired to check for server file system mount points. This patch avoids acquiring the vnode, as above, resulting in a 3-8% improvement in Readdir RPC RTT for some simple tests I did. Note that only non-rdirplus NFSv4 mounts will benefit from this change. Tested during a recent IETF NFSv4 Bakeathon testing event. (cherry picked from commit cd5edc7db261fb228be4044e6fdd38850eb4e9c4) --- sys/fs/nfsserver/nfs_nfsdport.c | 30 +++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 570ae653e06c..776d5c50861c 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -117,6 +117,11 @@ extern int nfsrv_issuedelegs; extern int nfsrv_dolocallocks; extern struct nfsdevicehead nfsrv_devidhead; +/* Map d_type to vnode type. */ +static uint8_t dtype_to_vnode[DT_WHT + 1] = { VNON, VFIFO, VCHR, VNON, VDIR, +VNON, VBLK, VNON, VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON }; +#defineNFS_DTYPETOVTYPE(t) ((t) <= DT_WHT ? dtype_to_vnode[(t)] : VNON) + static int nfsrv_createiovec(int, struct mbuf **, struct mbuf **, struct iovec **); static int nfsrv_createiovec_extpgs(int, int, struct mbuf **, @@ -2310,7 +2315,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram, caddr_t bpos0, bpos1; u_int64_t off, toff, verf __unused; uint64_t *cookies = NULL, *cookiep; - nfsattrbit_t attrbits, rderrbits, savbits; + nfsattrbit_t attrbits, rderrbits, savbits, refbits; struct uio io; struct iovec iv; struct componentname cn; @@ -2361,9 +2366,20 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram, if (error) goto nfsmout; NFSSET_ATTRBIT(&savbits, &attrbits); + NFSSET_ATTRBIT(&refbits, &attrbits); NFSCLRNOTFILLABLE_ATTRBIT(&attrbits, nd); NFSZERO_ATTRBIT(&rderrbits); NFSSETBIT_ATTRBIT(&rderrbits, NFSATTRBIT_RDATTRERROR); + /* +* If these 4 bits are the only attributes requested by the +* client, they can be satisfied without acquiring the vnode +* for the file object unless it is a directory. +* This will be indicated by savbits being all 0s. +*/ + NFSCLRBIT_ATTRBIT(&savbits, NFSATTRBIT_TYPE); + NFSCLRBIT_ATTRBIT(&savbits, NFSATTRBIT_FILEID); + NFSCLRBIT_ATTRBIT(&savbits, NFSATTRBIT_MOUNTEDONFILEID); + NFSCLRBIT_ATTRBIT(&savbits, NFSATTRBIT_RDATTRERROR); } else { NFSZERO_ATTRBIT(&attrbits); } @@ -2606,7 +2622,10 @@ again: new_mp = mp; mounted_on_fileno = (uint64_t)dp->d_fileno; if ((nd->nd_flag & ND_NFSV3) || - NFSNONZERO_ATTRBIT(&savbits)) { + NFSNONZERO_ATTRBIT(&savbits) || + dp->d_type == DT_UNKNOWN || + (dp->d_type == DT_DIR && +nfsrv_enable_crossmntpt != 0)) { if (nd->nd_flag & ND_NFSV4) refp = nfsv4root_getreferral(NULL, vp, dp->d_fileno); @@ -2743,6 +2762,11 @@ again: break; } } + } else if (NFSNONZERO_ATTRBIT(&attrbits)) { + /* Only need Type and/or Fileid. */ + VATTR_NULL(&nvap->na_vattr); + nvap->na_fileid = dp->d_fileno; + nvap->na_type = NFS_DTYPETOVTYPE(dp->d_type); } /* @@ -2774,7 +2798,7 @@ again: supports_nfsv4acls = 0; if (refp != NULL) {
git: 0948d2a9cfea - stable/13 - nfsd: Avoid acquiring a vnode for some NFSv4 Readdir operations
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=0948d2a9cfea5a469a9505fb314a6f9af38bb6fa commit 0948d2a9cfea5a469a9505fb314a6f9af38bb6fa Author: Rick Macklem AuthorDate: 2023-10-17 20:55:48 + Commit: Rick Macklem CommitDate: 2023-11-16 23:54:20 + nfsd: Avoid acquiring a vnode for some NFSv4 Readdir operations Without this patch, a NFSv4 Readdir operation acquires the vnode for each entry in the directory. If only the Type, Fileid, Mounted_on_fileid and ReaddirError attributes are requested by a client, acquiring the vnode is not necessary for non-directories. Directory vnodes must be acquired to check for server file system mount points. This patch avoids acquiring the vnode, as above, resulting in a 3-8% improvement in Readdir RPC RTT for some simple tests I did. Note that only non-rdirplus NFSv4 mounts will benefit from this change. Tested during a recent IETF NFSv4 Bakeathon testing event. (cherry picked from commit cd5edc7db261fb228be4044e6fdd38850eb4e9c4) --- sys/fs/nfsserver/nfs_nfsdport.c | 30 +++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index e2a3ff7e3b93..05cebdd13f7d 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -117,6 +117,11 @@ extern int nfsrv_issuedelegs; extern int nfsrv_dolocallocks; extern struct nfsdevicehead nfsrv_devidhead; +/* Map d_type to vnode type. */ +static uint8_t dtype_to_vnode[DT_WHT + 1] = { VNON, VFIFO, VCHR, VNON, VDIR, +VNON, VBLK, VNON, VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON }; +#defineNFS_DTYPETOVTYPE(t) ((t) <= DT_WHT ? dtype_to_vnode[(t)] : VNON) + static int nfsrv_createiovec(int, struct mbuf **, struct mbuf **, struct iovec **); static int nfsrv_createiovec_extpgs(int, int, struct mbuf **, @@ -2319,7 +2324,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram, caddr_t bpos0, bpos1; u_int64_t off, toff, verf; u_long *cookies = NULL, *cookiep; - nfsattrbit_t attrbits, rderrbits, savbits; + nfsattrbit_t attrbits, rderrbits, savbits, refbits; struct uio io; struct iovec iv; struct componentname cn; @@ -2370,9 +2375,20 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram, if (error) goto nfsmout; NFSSET_ATTRBIT(&savbits, &attrbits); + NFSSET_ATTRBIT(&refbits, &attrbits); NFSCLRNOTFILLABLE_ATTRBIT(&attrbits, nd); NFSZERO_ATTRBIT(&rderrbits); NFSSETBIT_ATTRBIT(&rderrbits, NFSATTRBIT_RDATTRERROR); + /* +* If these 4 bits are the only attributes requested by the +* client, they can be satisfied without acquiring the vnode +* for the file object unless it is a directory. +* This will be indicated by savbits being all 0s. +*/ + NFSCLRBIT_ATTRBIT(&savbits, NFSATTRBIT_TYPE); + NFSCLRBIT_ATTRBIT(&savbits, NFSATTRBIT_FILEID); + NFSCLRBIT_ATTRBIT(&savbits, NFSATTRBIT_MOUNTEDONFILEID); + NFSCLRBIT_ATTRBIT(&savbits, NFSATTRBIT_RDATTRERROR); } else { NFSZERO_ATTRBIT(&attrbits); } @@ -2616,7 +2632,10 @@ again: new_mp = mp; mounted_on_fileno = (uint64_t)dp->d_fileno; if ((nd->nd_flag & ND_NFSV3) || - NFSNONZERO_ATTRBIT(&savbits)) { + NFSNONZERO_ATTRBIT(&savbits) || + dp->d_type == DT_UNKNOWN || + (dp->d_type == DT_DIR && +nfsrv_enable_crossmntpt != 0)) { if (nd->nd_flag & ND_NFSV4) refp = nfsv4root_getreferral(NULL, vp, dp->d_fileno); @@ -2754,6 +2773,11 @@ again: break; } } + } else if (NFSNONZERO_ATTRBIT(&attrbits)) { + /* Only need Type and/or Fileid. */ + VATTR_NULL(&nvap->na_vattr); + nvap->na_fileid = dp->d_fileno; + nvap->na_type = NFS_DTYPETOVTYPE(dp->d_type); } /* @@ -2785,7 +2809,7 @@ again: supports_nfsv4acls = 0; if (refp != NULL) {
git: 4e583d78b77c - stable/14 - nfscl: Use Claim_Null_FH and Claim_Deleg_Cur_FH
The branch stable/14 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=4e583d78b77ce6a3c05b79d82e4ccf2a3a390d8d commit 4e583d78b77ce6a3c05b79d82e4ccf2a3a390d8d Author: Rick Macklem AuthorDate: 2023-10-20 23:10:25 + Commit: Rick Macklem CommitDate: 2023-11-21 23:55:19 + nfscl: Use Claim_Null_FH and Claim_Deleg_Cur_FH For NFSv4.1/4.2, there are two new options for the Open operation. These two options use the file handle for the file instead of the file handle for the directory plus a file name. By doing so, the client code is simplified (it no longer needs the "nfsv4node" structure attached to the NFS vnode). It also avoids problems caused by another NFS client (or process running locally in the NFS server) doing a rename or remove of the file name between the Lookup and Open. Unfortunately, there was a bug (fixed recently by commit X) in the NFS server which mis-parsed the Claim_Deleg_Cur_FH arguments. To allow this patch to work with the broken FreeBSD NFSv4.1/4.2 server, NFSMNTP_BUGGYFBSDSRV is defined and is set when a correctly formatted Claim_Deleg_Cur_FH fails with NFSERR_EXPIRED. (This is what the old, broken NFS server does, since it erroneously uses the Getattr arguments as a stateID.) Once this flag is set, the client fills in a stateID, to make the broken NFS server happy. Tested at a recent IETF NFSv4 Bakeathon. (cherry picked from commit 196787f79e67374527a1d528a42efa8b31acd9af) --- sys/fs/nfsclient/nfs_clport.c | 4 +- sys/fs/nfsclient/nfs_clrpcops.c | 92 +++-- sys/fs/nfsclient/nfs_clstate.c | 47 + sys/fs/nfsclient/nfs_clvnops.c | 16 --- sys/fs/nfsclient/nfsmount.h | 1 + 5 files changed, 114 insertions(+), 46 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c index 8ea50d80ae19..c0318b692d86 100644 --- a/sys/fs/nfsclient/nfs_clport.c +++ b/sys/fs/nfsclient/nfs_clport.c @@ -264,10 +264,10 @@ nfscl_nget(struct mount *mntp, struct vnode *dvp, struct nfsfh *nfhp, np->n_fhp = nfhp; /* -* For NFSv4, we have to attach the directory file handle and +* For NFSv4.0, we have to attach the directory file handle and * file name, so that Open Ops can be done later. */ - if (nmp->nm_flag & NFSMNT_NFSV4) { + if (NFSHASNFSV4(nmp) && !NFSHASNFSV4N(nmp)) { np->n_v4 = malloc(sizeof (struct nfsv4node) + dnp->n_fhp->nfh_len + cnp->cn_namelen - 1, M_NFSV4NODE, M_WAITOK); diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 8fe9158384a0..5a16a28bd83e 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -392,16 +392,6 @@ nfsrpc_open(vnode_t vp, int amode, struct ucred *cred, NFSPROC_T *p) nfhp = np->n_fhp; retrycnt = 0; -#ifdef notdef -{ char name[100]; int namel; -namel = (np->n_v4->n4_namelen < 100) ? np->n_v4->n4_namelen : 99; -bcopy(NFS4NODENAME(np->n_v4), name, namel); -name[namel] = '\0'; -printf("rpcopen p=0x%x name=%s",p->p_pid,name); -if (nfhp->nfh_len > 0) printf(" fh=0x%x\n",nfhp->nfh_fh[12]); -else printf(" fhl=0\n"); -} -#endif do { dp = NULL; error = nfscl_open(vp, nfhp->nfh_fh, nfhp->nfh_len, mode, 1, @@ -452,6 +442,39 @@ else printf(" fhl=0\n"); op->nfso_own->nfsow_clp, nfhp->nfh_fh, nfhp->nfh_len, cred, p, &dp); } + } else if (NFSHASNFSV4N(nmp)) { + /* +* For the first attempt, try and get a layout, if +* pNFS is enabled for the mount. +*/ + if (!NFSHASPNFS(nmp) || nfscl_enablecallb == 0 || + nfs_numnfscbd == 0 || + (np->n_flag & NNOLAYOUT) != 0 || retrycnt > 0) + error = nfsrpc_openrpc(nmp, vp, nfhp->nfh_fh, + nfhp->nfh_len, nfhp->nfh_fh, nfhp->nfh_len, + mode, op, NULL, 0, &dp, 0, 0x0, cred, p, 0, + 0); + else + error = nfsrpc_getopenlayout(nmp, vp, + nfhp->nfh_fh, nfhp->nfh_len, nfhp->nfh_fh, + nfhp->nfh_len, mode, op, NULL, 0, &dp, + cred, p); + if (dp != NULL) { + NFSLOCKNODE(np); + np->n
git: 55671098064f - stable/14 - nfscl: Handle a Getattr failure with NFSERR_DELAY following Open
The branch stable/14 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=55671098064f715ae106225513a7241bd6aa46b0 commit 55671098064f715ae106225513a7241bd6aa46b0 Author: Rick Macklem AuthorDate: 2023-10-22 01:33:33 + Commit: Rick Macklem CommitDate: 2023-11-21 23:57:43 + nfscl: Handle a Getattr failure with NFSERR_DELAY following Open During testing at a recent IETF NFSv4 Bakeathon, a non-FreeBSD server was rebooted. After the reboot, the FreeBSD client sent an Open/Claim_previous with a Getattr after the Open in the same compound. The Open/Claim_previous was done to recover the Open and a Delegation for for a file. The Open succeeded, but the Getattr after the Open failed with NFSERR_DELAY. This resulted in the FreeBSD client retrying the entire RPC over and over again, until the server's recovery grace period ended. Since the Open succeeded, there was no need to retry the entire RPC. This patch modifies the NFSv4 client side recovery Open/Claim_previous RPC reply handling to deal with this case. With this patch, the Getattr reply of NFSERR_DELAY is ignored and the successful Open reply is processed. This bug will not normally affect users, since this non-FreeBSD server is not widely used (it may not even have shipped to any customers). (cherry picked from commit 14bbf4fe5abb20f1126168e66b03127ae920f78e) --- sys/fs/nfsclient/nfs_clrpcops.c | 32 +++- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 5a16a28bd83e..207a51c4aece 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -609,7 +609,8 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen, if (error) return (error); NFSCL_INCRSEQID(op->nfso_own->nfsow_seqid, nd); - if (!nd->nd_repstat) { + if (nd->nd_repstat == 0 || (nd->nd_repstat == NFSERR_DELAY && + reclaim != 0 && (nd->nd_flag & ND_NOMOREDATA) == 0)) { NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID + 6 * NFSX_UNSIGNED); op->nfso_stateid.seqid = *tl++; @@ -681,16 +682,29 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen, goto nfsmout; } NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - error = nfsv4_loadattr(nd, NULL, &nfsva, NULL, - NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, - NULL, NULL, NULL, p, cred); - if (error) - goto nfsmout; + /* If the 2nd element == NFS_OK, the Getattr succeeded. */ + if (*++tl == 0) { + KASSERT(nd->nd_repstat == 0, + ("nfsrpc_openrpc: Getattr repstat")); + error = nfsv4_loadattr(nd, NULL, &nfsva, NULL, + NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, + NULL, NULL, NULL, p, cred); + if (error) + goto nfsmout; + } if (ndp != NULL) { - ndp->nfsdl_change = nfsva.na_filerev; - ndp->nfsdl_modtime = nfsva.na_mtime; - ndp->nfsdl_flags |= NFSCLDL_MODTIMESET; + if (reclaim != 0 && dp != NULL) { + ndp->nfsdl_change = dp->nfsdl_change; + ndp->nfsdl_modtime = dp->nfsdl_modtime; + ndp->nfsdl_flags |= NFSCLDL_MODTIMESET; + } else if (nd->nd_repstat == 0) { + ndp->nfsdl_change = nfsva.na_filerev; + ndp->nfsdl_modtime = nfsva.na_mtime; + ndp->nfsdl_flags |= NFSCLDL_MODTIMESET; + } else + ndp->nfsdl_flags |= NFSCLDL_RECALL; } + nd->nd_repstat = 0; if (!reclaim && (rflags & NFSV4OPEN_RESULTCONFIRM)) { do { ret = nfsrpc_openconfirm(vp, newfhp, newfhlen, op,
git: 3ab7f15d9116 - stable/13 - nfscl: Handle a Getattr failure with NFSERR_DELAY following Open
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=3ab7f15d91160b4ac3369f6c3bc696ba9bf88afc commit 3ab7f15d91160b4ac3369f6c3bc696ba9bf88afc Author: Rick Macklem AuthorDate: 2023-10-22 01:33:33 + Commit: Rick Macklem CommitDate: 2023-11-22 00:03:11 + nfscl: Handle a Getattr failure with NFSERR_DELAY following Open During testing at a recent IETF NFSv4 Bakeathon, a non-FreeBSD server was rebooted. After the reboot, the FreeBSD client sent an Open/Claim_previous with a Getattr after the Open in the same compound. The Open/Claim_previous was done to recover the Open and a Delegation for for a file. The Open succeeded, but the Getattr after the Open failed with NFSERR_DELAY. This resulted in the FreeBSD client retrying the entire RPC over and over again, until the server's recovery grace period ended. Since the Open succeeded, there was no need to retry the entire RPC. This patch modifies the NFSv4 client side recovery Open/Claim_previous RPC reply handling to deal with this case. With this patch, the Getattr reply of NFSERR_DELAY is ignored and the successful Open reply is processed. This bug will not normally affect users, since this non-FreeBSD server is not widely used (it may not even have shipped to any customers). (cherry picked from commit 14bbf4fe5abb20f1126168e66b03127ae920f78e) --- sys/fs/nfsclient/nfs_clrpcops.c | 32 +++- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index be702e703c91..569132aee43c 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -569,7 +569,8 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen, if (error) return (error); NFSCL_INCRSEQID(op->nfso_own->nfsow_seqid, nd); - if (!nd->nd_repstat) { + if (nd->nd_repstat == 0 || (nd->nd_repstat == NFSERR_DELAY && + reclaim != 0 && (nd->nd_flag & ND_NOMOREDATA) == 0)) { NFSM_DISSECT(tl, u_int32_t *, NFSX_STATEID + 6 * NFSX_UNSIGNED); op->nfso_stateid.seqid = *tl++; @@ -641,16 +642,29 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen, goto nfsmout; } NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - error = nfsv4_loadattr(nd, NULL, &nfsva, NULL, - NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, - NULL, NULL, NULL, p, cred); - if (error) - goto nfsmout; + /* If the 2nd element == NFS_OK, the Getattr succeeded. */ + if (*++tl == 0) { + KASSERT(nd->nd_repstat == 0, + ("nfsrpc_openrpc: Getattr repstat")); + error = nfsv4_loadattr(nd, NULL, &nfsva, NULL, + NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, + NULL, NULL, NULL, p, cred); + if (error) + goto nfsmout; + } if (ndp != NULL) { - ndp->nfsdl_change = nfsva.na_filerev; - ndp->nfsdl_modtime = nfsva.na_mtime; - ndp->nfsdl_flags |= NFSCLDL_MODTIMESET; + if (reclaim != 0 && dp != NULL) { + ndp->nfsdl_change = dp->nfsdl_change; + ndp->nfsdl_modtime = dp->nfsdl_modtime; + ndp->nfsdl_flags |= NFSCLDL_MODTIMESET; + } else if (nd->nd_repstat == 0) { + ndp->nfsdl_change = nfsva.na_filerev; + ndp->nfsdl_modtime = nfsva.na_mtime; + ndp->nfsdl_flags |= NFSCLDL_MODTIMESET; + } else + ndp->nfsdl_flags |= NFSCLDL_RECALL; } + nd->nd_repstat = 0; if (!reclaim && (rflags & NFSV4OPEN_RESULTCONFIRM)) { do { ret = nfsrpc_openconfirm(vp, newfhp, newfhlen, op,
git: 64d119ab5a36 - stable/14 - nfscl: newnfs_copycred() cannot be called when a mutex is held
The branch stable/14 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=64d119ab5a3600c45daf68a0eade19a5432e7563 commit 64d119ab5a3600c45daf68a0eade19a5432e7563 Author: Rick Macklem AuthorDate: 2023-11-06 22:25:30 + Commit: Rick Macklem CommitDate: 2023-11-22 00:09:13 + nfscl: newnfs_copycred() cannot be called when a mutex is held Since newnfs_copycred() calls crsetgroups() which in turn calls crextend() which might do a malloc(M_WAITOK), newnfs_copycred() cannot be called with a mutex held. Fortunately, the malloc() call is rarely done, since XU_GROUPS is 16 and the NFS client uses a maximum of 17 (only 17 groups will cause the malloc() to be called). Further, it is only a problem if the malloc() tries to sleep(). As such, this bug does not seem to have caused problems in practice. This patch fixes the one place in the NFS client where newnfs_copycred() is called while a mutex is held by moving the call to after where the mutex is released. Found by inspection while working on an experimental patch. (cherry picked from commit 501bdf3001190686bf55d9d333cb533858c2cf2f) --- sys/fs/nfsclient/nfs_clstate.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index 579210941802..ebc11efea637 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -526,6 +526,7 @@ nfscl_getstateid(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t mode, struct nfscldeleg *dp; struct nfsnode *np; struct nfsmount *nmp; + struct nfscred ncr; u_int8_t own[NFSV4CL_LOCKNAMELEN], lockown[NFSV4CL_LOCKNAMELEN]; int error; bool done; @@ -683,7 +684,7 @@ nfscl_getstateid(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t mode, * A read ahead or write behind is indicated by p == NULL. */ if (p == NULL) - newnfs_copycred(&op->nfso_cred, cred); + memcpy(&ncr, &op->nfso_cred, sizeof(ncr)); } /* @@ -697,6 +698,8 @@ nfscl_getstateid(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t mode, stateidp->other[1] = op->nfso_stateid.other[1]; stateidp->other[2] = op->nfso_stateid.other[2]; NFSUNLOCKCLSTATE(); + if (p == NULL) + newnfs_copycred(&ncr, cred); return (0); }
git: 2d8d914450da - stable/13 - nfscl: newnfs_copycred() cannot be called when a mutex is held
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=2d8d914450da1f9b79a7b51c0970445fcd9f648f commit 2d8d914450da1f9b79a7b51c0970445fcd9f648f Author: Rick Macklem AuthorDate: 2023-11-06 22:25:30 + Commit: Rick Macklem CommitDate: 2023-11-22 00:13:25 + nfscl: newnfs_copycred() cannot be called when a mutex is held Since newnfs_copycred() calls crsetgroups() which in turn calls crextend() which might do a malloc(M_WAITOK), newnfs_copycred() cannot be called with a mutex held. Fortunately, the malloc() call is rarely done, since XU_GROUPS is 16 and the NFS client uses a maximum of 17 (only 17 groups will cause the malloc() to be called). Further, it is only a problem if the malloc() tries to sleep(). As such, this bug does not seem to have caused problems in practice. This patch fixes the one place in the NFS client where newnfs_copycred() is called while a mutex is held by moving the call to after where the mutex is released. Found by inspection while working on an experimental patch. (cherry picked from commit 501bdf3001190686bf55d9d333cb533858c2cf2f) --- sys/fs/nfsclient/nfs_clstate.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index 3d516a33934f..9ab0a29e9c5d 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -528,6 +528,7 @@ nfscl_getstateid(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t mode, struct nfscldeleg *dp; struct nfsnode *np; struct nfsmount *nmp; + struct nfscred ncr; u_int8_t own[NFSV4CL_LOCKNAMELEN], lockown[NFSV4CL_LOCKNAMELEN]; int error; bool done; @@ -685,7 +686,7 @@ nfscl_getstateid(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t mode, * A read ahead or write behind is indicated by p == NULL. */ if (p == NULL) - newnfs_copycred(&op->nfso_cred, cred); + memcpy(&ncr, &op->nfso_cred, sizeof(ncr)); } /* @@ -699,6 +700,8 @@ nfscl_getstateid(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t mode, stateidp->other[1] = op->nfso_stateid.other[1]; stateidp->other[2] = op->nfso_stateid.other[2]; NFSUNLOCKCLSTATE(); + if (p == NULL) + newnfs_copycred(&ncr, cred); return (0); }
git: 148a227bf80e - main - nfsd: add KASSERTs to nfsm_trimtrailing() for M_EXTPG mbufs
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=148a227bf80e9716ee26a8a6747961b5a639918b commit 148a227bf80e9716ee26a8a6747961b5a639918b Author: Rick Macklem AuthorDate: 2021-01-10 21:50:15 + Commit: Rick Macklem CommitDate: 2021-01-10 21:50:15 + nfsd: add KASSERTs to nfsm_trimtrailing() for M_EXTPG mbufs Add KASSERTS to nfsm_trimtrailing() to confirm the sanity of the arguments for the M_EXTPG case. Suggested by: kib Reviewed by:kib Differential Revision: https://reviews.freebsd.org/D28053 --- sys/fs/nfsserver/nfs_nfsdport.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 727a83005fa0..8336a0b8fab2 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -6581,6 +6581,12 @@ nfsm_trimtrailing(struct nfsrv_descript *nd, struct mbuf *mb, char *bpos, mb->m_next = NULL; } if ((mb->m_flags & M_EXTPG) != 0) { + KASSERT(bextpg >= 0 && bextpg < mb->m_epg_npgs, + ("nfsm_trimtrailing: bextpg out of range")); + KASSERT(bpos == (char *)(void *) + PHYS_TO_DMAP(mb->m_epg_pa[bextpg]) + PAGE_SIZE - bextpgsiz, + ("nfsm_trimtrailing: bextpgsiz bad!")); + /* First, get rid of any pages after this position. */ for (i = mb->m_epg_npgs - 1; i > bextpg; i--) { pg = PHYS_TO_VM_PAGE(mb->m_epg_pa[i]); ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: f6dc363f6dd2 - main - nfs-over-tls: handle res.gid.gid_val correctly for memory allocation
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=f6dc363f6dd2f6daa8cb59ecff6964fb86064f9f commit f6dc363f6dd2f6daa8cb59ecff6964fb86064f9f Author: Rick Macklem AuthorDate: 2021-01-12 21:59:52 + Commit: Rick Macklem CommitDate: 2021-01-12 21:59:52 + nfs-over-tls: handle res.gid.gid_val correctly for memory allocation When the server side nfs-over-tls does an upcall to rpc.tlsservd(8) for the handshake and the rpc.tlsservd "-u" command line option has been specified, a list of gids may be returned. The list will be returned in malloc'd memory pointed to by res.gid.gid_val. To ensure the malloc occurs, res.gid.gid_val must be NULL before the call. Then, the malloc'd memory needs to be free'd. mem_free() just calls free(9), so a NULL pointer argument is fine and a length argument == 0 is ok, since the "len" argument is not used. This bug would have only affected nfs-over-tls and only when rpc.tlsservd(8) is running with the "-u" command line option. --- sys/rpc/rpcsec_tls/rpctls_impl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/rpc/rpcsec_tls/rpctls_impl.c b/sys/rpc/rpcsec_tls/rpctls_impl.c index 638f27eaf350..110ba107540a 100644 --- a/sys/rpc/rpcsec_tls/rpctls_impl.c +++ b/sys/rpc/rpcsec_tls/rpctls_impl.c @@ -573,6 +573,7 @@ rpctls_server(SVCXPRT *xprt, struct socket *so, uint32_t *flags, uint64_t *sslp, mtx_unlock(&rpctls_server_lock); /* Do the server upcall. */ + res.gid.gid_val = NULL; stat = rpctlssd_connect_1(NULL, &res, cl); if (stat == RPC_SUCCESS) { *flags = res.flags; @@ -598,6 +599,7 @@ rpctls_server(SVCXPRT *xprt, struct socket *so, uint32_t *flags, uint64_t *sslp, soshutdown(so, SHUT_RD); } CLNT_RELEASE(cl); + mem_free(res.gid.gid_val, 0); /* Once the upcall is done, the daemon is done with the fp and so. */ mtx_lock(&rpctls_server_lock); ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 448de00de556 - main - mount_nfs: update man page description for oneopenown
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=448de00de556753575ec0a2e705712e7c606e680 commit 448de00de556753575ec0a2e705712e7c606e680 Author: Rick Macklem AuthorDate: 2021-01-18 03:00:41 + Commit: Rick Macklem CommitDate: 2021-01-18 03:00:41 + mount_nfs: update man page description for oneopenown A recent email discussion indicated that a large accumulation of NFSv4 Opens was occurring on a mount. This appears to have been caused by a shared library within the mount being used by several processes, such that there is always at least one of these processes running. A new Open was created by each process and were not closed, since all the Opens were never closed. This is alleviated by using the "oneopenown" mount option. This man page update attempts to indicate the use of "oneopenown" for this case. This is a content change. Reported by:j.david.li...@gmail.com Reviewed by:0mp MFC:1 month Differential Revision: https://reviews.freebsd.org/D28215 --- sbin/mount_nfs/mount_nfs.8 | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/sbin/mount_nfs/mount_nfs.8 b/sbin/mount_nfs/mount_nfs.8 index b2c561bc5cc8..76e009817d8b 100644 --- a/sbin/mount_nfs/mount_nfs.8 +++ b/sbin/mount_nfs/mount_nfs.8 @@ -28,7 +28,7 @@ .\"@(#)mount_nfs.8 8.3 (Berkeley) 3/29/95 .\" $FreeBSD$ .\" -.Dd December 21, 2020 +.Dd January 17, 2021 .Dt MOUNT_NFS 8 .Os .Sh NAME @@ -217,6 +217,19 @@ Make a minor version 1 or 2 of the NFS Version 4 protocol mount use a single OpenOwner for all Opens. This may be useful for a server with a very low limit on OpenOwners, such as AmazonEFS. +It may be required when an accumulation of NFS version 4 Opens occurs, +as indicated by the +.Dq Opens +count displayed by +.Xr nfsstat 8 +with the +.Fl c +and +.Fl E +command-line options. +A common case for an accumulation of Opens is a shared library within +the NFS mount that is used by several +processes, where at least one of these processes is always running. This option cannot be used for an NFS Version 4, minor version 0 mount. As such, this option requires the .Cm minorversion ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
Re: git: aa8c1f8d84d2 - main - nfs client: block vnode_pager_setsize() calls from nfscl_loadattrcache in nfs_write
Yasuhiro Kimura wrote: >> The branch main has been updated by kib: >> >> URL: >> https://cgit.FreeBSD.org/src/commit/?id=aa8c1f8d84d2638a354e71f9593e978d00878243 >> >> commit aa8c1f8d84d2638a354e71f9593e978d00878243 >> Author: Konstantin Belousov >> AuthorDate: 2021-01-22 21:47:06 + >> Commit: Konstantin Belousov >> CommitDate: 2021-01-23 15:24:32 + >> >> nfs client: block vnode_pager_setsize() calls from nfscl_loadattrcache >> in nfs_write >> >> Otherwise writing thread might wait on sbusy state of the pages which >> were >> busied by itself, similarly to nfs_read(). But also we need to clear >> NVNSETSZKSIP flag possibly set by ncl_pager_setsize(), to not undo >> extension done by write. >> >> Reported by:bdrewery >> Reviewed by:rmacklem >> Tested by: pho >> MFC after: 1 week >> Sponsored by: The FreeBSD Foundation >> Differential Revision: https://reviews.freebsd.org/D28306 > >On my 14-CURRENT amd64 environment this commit causes the problem that >garbage date are written to file mounted with NFS. > >I use NFSv4 and autofs to mount home directory on my 12.2-RELEASE >amd64 server. And I use zsh as login shell and configure it so command >history is written to history file each time any command is executed. > >After update to 519b64e27fddf10c0b7f6a615edbad730b8c6c45, I see >following error message if I try to execute any command. > >-- >yasu@rolling-vm-freebsd1[1009]% ls >zsh: corrupt history file /home/yasu/.zhistory >yasu@rolling-vm-freebsd1[1010]% >-- > >I logged in the server and check the content of history file. Then >some garbase data are written to history file. > >I confirmed the problem disappears by reverting this commit. I was also able to reproduce a problem (a truncated file) during testing. For my case, setting the size to n_size instead of va_size fixed the problem I reproduced, but I do not know if this achieves what Kostik intended. My variant of the patch is in D28318. Maybe you could test this, although you might want to wait until Kostik comments on this variant of the patch. rick --- Yasuhiro Kimura ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 5a45802b3c8c - stable/13 - nfsv4 client: do the BindConnectionToSession as required
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=5a45802b3c8c3962649f47b01453c819dd137da1 commit 5a45802b3c8c3962649f47b01453c819dd137da1 Author: Rick Macklem AuthorDate: 2021-04-11 21:34:57 + Commit: Rick Macklem CommitDate: 2021-04-30 00:43:50 + nfsv4 client: do the BindConnectionToSession as required During a recent testing event, it was reported that the NFSv4.1/4.2 server erroneously bound the back channel to a new TCP connection. RFC5661 specifies that the fore channel is implicitly bound to a new TCP connection when an RPC with Sequence (almost any of them) is done on it. For the back channel to be bound to the new TCP connection, an explicit BindConnectionToSession must be done as the first RPC on the new connection. Since new TCP connections are created by the "reconnect" layer (sys/rpc/clnt_rc.c) of the krpc, this patch adds an optional upcall done by the krpc whenever a new connection is created. The patch also adds the specific upcall function that does a BindConnectionToSession and configures the krpc to call it when required. This is necessary for correct interoperability with NFSv4.1/NFSv4.2 servers when the nfscbd daemon is running. If doing NFSv4.1/NFSv4.2 mounts without this patch, it is recommended that the nfscbd daemon not be running and that the "pnfs" mount option not be specified. PR: 254840 (cherry picked from commit 7763814fc9c27a98fefcbf582d7a936ea43af23a) --- sys/fs/nfs/nfs_commonsubs.c | 5 ++- sys/fs/nfs/nfs_var.h| 1 + sys/fs/nfs/nfscl.h | 5 +++ sys/fs/nfs/nfsport.h| 9 +++-- sys/fs/nfs/nfsproto.h | 5 ++- sys/fs/nfsclient/nfs_clrpcops.c | 90 + sys/rpc/clnt.h | 6 +++ sys/rpc/clnt_rc.c | 15 +++ sys/rpc/krpc.h | 3 ++ 9 files changed, 133 insertions(+), 6 deletions(-) diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 43bb396d9cfd..4afa4c2d9ab4 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -218,7 +218,7 @@ static struct nfsrv_lughash *nfsgroupnamehash; static int nfs_bigreply[NFSV42_NPROCS] = { 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1 }; +1, 0, 0, 1, 0 }; /* local functions */ static int nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep); @@ -301,6 +301,7 @@ static struct { { NFSV4OP_SETXATTR, 2, "Setxattr", 8, }, { NFSV4OP_REMOVEXATTR, 2, "Rmxattr", 7, }, { NFSV4OP_LISTXATTRS, 2, "Listxattr", 9, }, + { NFSV4OP_BINDCONNTOSESS, 1, "BindConSess", 11, }, }; /* @@ -309,7 +310,7 @@ static struct { static int nfs_bigrequest[NFSV42_NPROCS] = { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }; /* diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index aba5c5124e72..0297b52015f8 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -561,6 +561,7 @@ int nfsrpc_listextattr(vnode_t, uint64_t *, struct uio *, size_t *, bool *, struct nfsvattr *, int *, struct ucred *, NFSPROC_T *); int nfsrpc_rmextattr(vnode_t, const char *, struct nfsvattr *, int *, struct ucred *, NFSPROC_T *); +void nfsrpc_bindconnsess(CLIENT *, void *, struct ucred *); /* nfs_clstate.c */ int nfscl_open(vnode_t, u_int8_t *, int, u_int32_t, int, diff --git a/sys/fs/nfs/nfscl.h b/sys/fs/nfs/nfscl.h index 52da0af6fa51..3d7afaf68432 100644 --- a/sys/fs/nfs/nfscl.h +++ b/sys/fs/nfs/nfscl.h @@ -81,4 +81,9 @@ struct nfsv4node { printf(__VA_ARGS__);\ } while (0) +struct nfscl_reconarg { + int minorvers; + uint8_t sessionid[NFSX_V4SESSIONID]; +}; + #endif /* _NFS_NFSCL_H */ diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h index 255c9a47ebdf..6777dc72f6a3 100644 --- a/sys/fs/nfs/nfsport.h +++ b/sys/fs/nfs/nfsport.h @@ -412,10 +412,13 @@ #defineNFSPROC_RMEXTATTR 63 #defineNFSPROC_LISTEXTATTR 64 +/* BindConnectionToSession, done by the krpc for a new connection. */ +#defineNFSPROC_BINDCONNTOSESS 65 + /* * Must be defined as one higher than the last NFSv4.2 Proc# above. */ -#defineNFSV42_NPROCS 65 +#defineNFSV42_NPROCS 66 #endif /* NFS_V3NPROCS */ @@ -444,7 +447,7 @@ struct nfsstatsv1 { uint64_treadlink_bios;
git: d60c6dc8f69b - stable/13 - param.h: bump __FreeBSD_version for commit 5a45802b3c8c
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=d60c6dc8f69b1264c7af5e2479ea94f000fd2c6d commit d60c6dc8f69b1264c7af5e2479ea94f000fd2c6d Author: Rick Macklem AuthorDate: 2021-04-30 01:29:25 + Commit: Rick Macklem CommitDate: 2021-04-30 01:29:25 + param.h: bump __FreeBSD_version for commit 5a45802b3c8c Commit 5a45802b3c8c changed the internal KAPI between the krpc and NFS. As such, the krpc, nfscommon and nfscl modules must all be rebuilt from sources. --- sys/sys/param.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/sys/param.h b/sys/sys/param.h index e547452e5af1..c93eccc143dd 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -60,7 +60,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1300502 /* Master, propagated to newvers */ +#define __FreeBSD_version 1300503 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 00a7499bcba1 - stable/13 - Add an UPDATING entry for commit 5a45802b3c8c
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=00a7499bcba17c974275e8208b4227b73cbcbebe commit 00a7499bcba17c974275e8208b4227b73cbcbebe Author: Rick Macklem AuthorDate: 2021-04-30 01:40:04 + Commit: Rick Macklem CommitDate: 2021-04-30 01:40:04 + Add an UPDATING entry for commit 5a45802b3c8c --- UPDATING | 8 1 file changed, 8 insertions(+) diff --git a/UPDATING b/UPDATING index c42fe6639b12..b966ed678efd 100644 --- a/UPDATING +++ b/UPDATING @@ -11,6 +11,14 @@ handbook: Items affecting the ports and packages system can be found in /usr/ports/UPDATING. Please read that file before running portupgrade. +20210429: + Commit 5a45802b3c8c changed the internal KAPI between + the krpc and NFS. As such, the krpc, nfscommon and + nfscl modules must all be rebuilt from sources. + Without this patch, NFSv4.1/4.2 mounts should not + be done with the nfscbd(8) daemon running, to avoid + needing a working back channel for server->client RPCs. + 20210202: Various LinuxKPI functionality was added which conflicts with DRM. Please update your drm-kmod port to after the __FreeBSD_verison 1300139 ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 0a1fdb867c72 - stable/12 - nfsv4 client: do the BindConnectionToSession as required
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=0a1fdb867c72a1009b4a194deb9978289cf5a3cd commit 0a1fdb867c72a1009b4a194deb9978289cf5a3cd Author: Rick Macklem AuthorDate: 2021-04-11 21:34:57 + Commit: Rick Macklem CommitDate: 2021-04-30 23:16:11 + nfsv4 client: do the BindConnectionToSession as required During a recent testing event, it was reported that the NFSv4.1 server erroneously bound the back channel to a new TCP connection. RFC5661 specifies that the fore channel is implicitly bound to a new TCP connection when an RPC with Sequence (almost any of them) is done on it. For the back channel to be bound to the new TCP connection, an explicit BindConnectionToSession must be done as the first RPC on the new connection. Since new TCP connections are created by the "reconnect" layer (sys/rpc/clnt_rc.c) of the krpc, this patch adds an optional upcall done by the krpc whenever a new connection is created. The patch also adds the specific upcall function that does a BindConnectionToSession and configures the krpc to call it when required. This is necessary for correct interoperability with NFSv4.1 servers when the nfscbd daemon is running. If doing NFSv4.1 mounts without this patch, it is recommended that the nfscbd daemon not be running and that the "pnfs" mount option not be specified. PR: 254840 (cherry picked from commit 7763814fc9c27a98fefcbf582d7a936ea43af23a) --- sys/fs/nfs/nfs_commonsubs.c | 5 ++- sys/fs/nfs/nfs_var.h| 1 + sys/fs/nfs/nfscl.h | 5 +++ sys/fs/nfs/nfsport.h| 7 +++- sys/fs/nfs/nfsproto.h | 5 ++- sys/fs/nfsclient/nfs_clrpcops.c | 89 + sys/rpc/clnt.h | 6 +++ sys/rpc/clnt_rc.c | 15 +++ sys/rpc/krpc.h | 3 ++ 9 files changed, 131 insertions(+), 5 deletions(-) diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index d004fbb1bc51..07652fbdb911 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -192,7 +192,7 @@ static struct nfsrv_lughash *nfsgroupnamehash; */ static int nfs_bigreply[NFSV41_NPROCS] = { 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }; +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }; /* local functions */ static int nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep); @@ -267,6 +267,7 @@ static struct { { NFSV4OP_COMMIT, 1, "CommitDS", 8, }, { NFSV4OP_OPEN, 3, "OpenLayoutGet", 13, }, { NFSV4OP_OPEN, 8, "CreateLayGet", 12, }, + { NFSV4OP_BINDCONNTOSESS, 1, "BindConSess", 11, }, }; /* @@ -275,7 +276,7 @@ static struct { static int nfs_bigrequest[NFSV41_NPROCS] = { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }; /* diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 4bc1101e3b8d..9c8942e27132 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -535,6 +535,7 @@ int nfscl_doiods(vnode_t, struct uio *, int *, int *, uint32_t, int, int nfscl_findlayoutforio(struct nfscllayout *, uint64_t, uint32_t, struct nfsclflayout **); void nfscl_freenfsclds(struct nfsclds *); +void nfsrpc_bindconnsess(CLIENT *, void *, struct ucred *); /* nfs_clstate.c */ int nfscl_open(vnode_t, u_int8_t *, int, u_int32_t, int, diff --git a/sys/fs/nfs/nfscl.h b/sys/fs/nfs/nfscl.h index 52da0af6fa51..3d7afaf68432 100644 --- a/sys/fs/nfs/nfscl.h +++ b/sys/fs/nfs/nfscl.h @@ -81,4 +81,9 @@ struct nfsv4node { printf(__VA_ARGS__);\ } while (0) +struct nfscl_reconarg { + int minorvers; + uint8_t sessionid[NFSX_V4SESSIONID]; +}; + #endif /* _NFS_NFSCL_H */ diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h index 177fcad5443d..a0181df0bde7 100644 --- a/sys/fs/nfs/nfsport.h +++ b/sys/fs/nfs/nfsport.h @@ -357,10 +357,13 @@ #defineNFSPROC_OPENLAYGET 54 #defineNFSPROC_CREATELAYGET55 +/* BindConnectionToSession, done by the krpc for a new connection. */ +#defineNFSPROC_BINDCONNTOSESS 56 + /* * Must be defined as one higher than the last NFSv4.1 Proc# above. */ -#defineNFSV41_NPROCS 56 +#defineNFSV41_NPROCS 57 #endif /* NFS_V3NPROCS */ @@ -389,7 +392,7 @@ struct nfsstatsv1 { uint64_treadlink_bios; uint64_tbiocache_readdirs; uint64_treaddir_bios; -
git: d36cc12ddfe3 - stable/12 - param.h: bump __FreeBSD_version to 1202506 for commit 0a1fdb867c72
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=d36cc12ddfe3335ec8306bd4b393f11069551fa0 commit d36cc12ddfe3335ec8306bd4b393f11069551fa0 Author: Rick Macklem AuthorDate: 2021-04-30 23:28:46 + Commit: Rick Macklem CommitDate: 2021-04-30 23:28:46 + param.h: bump __FreeBSD_version to 1202506 for commit 0a1fdb867c72 Commit 0a1fdb867c72 changed the internal KAPI between the krpc and NFS. As such, the krpc, nfscommon and nfscl modules must all be rebuilt from sources. --- sys/sys/param.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/sys/param.h b/sys/sys/param.h index 1473009481e0..89ab74bc07a6 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -60,7 +60,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1202505 /* Master, propagated to newvers */ +#define __FreeBSD_version 1202506 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 2e26b41fe54c - stable/12 - UPDATING: add an entry for commit 0a1fdb867c72
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=2e26b41fe54c81230ad802d00b95bbbd3b2eeea9 commit 2e26b41fe54c81230ad802d00b95bbbd3b2eeea9 Author: Rick Macklem AuthorDate: 2021-04-30 23:35:39 + Commit: Rick Macklem CommitDate: 2021-04-30 23:35:39 + UPDATING: add an entry for commit 0a1fdb867c72 --- UPDATING | 8 1 file changed, 8 insertions(+) diff --git a/UPDATING b/UPDATING index cc5ac276432d..225f0ca05baa 100644 --- a/UPDATING +++ b/UPDATING @@ -17,6 +17,14 @@ from older versions of FreeBSD, try WITHOUT_CLANG and WITH_GCC to bootstrap to the tip of head, and then rebuild without this option. The bootstrap process from older version of current across the gcc/clang cutover is a bit fragile. +20210430: + Commit 0a1fdb867c72 changed the internal KAPI between + the krpc and NFS. As such, the krpc, nfscommon and + nfscl modules must all be rebuilt from sources. + Without this patch, NFSv4.1 mounts should not + be done with the nfscbd(8) daemon running, to avoid + needing a working back channel for server->client RPCs. + 20200912: The make.conf(5) MALLOC_PRODUCTION variable, used for disabling and enabling assertions and statistics gathering in malloc(3), has been ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 4f592683c356 - main - copy_file_range(2): improve copying of a large hole to EOF
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=4f592683c356379c5bac56b52807ed4ad54ee647 commit 4f592683c356379c5bac56b52807ed4ad54ee647 Author: Rick Macklem AuthorDate: 2021-05-02 23:04:27 + Commit: Rick Macklem CommitDate: 2021-05-02 23:04:27 + copy_file_range(2): improve copying of a large hole to EOF PR#255523 reported that a file copy for a file with a large hole to EOF on ZFS ran slowly over NFSv4.2. The problem was that vn_generic_copy_file_range() would loop around reading the hole's data and then see it is all 0s. It was coded this way since UFS always allocates a data block near the end of the file, such that a hole to EOF never exists. This patch modifies vn_generic_copy_file_range() to check for a ENXIO returned from VOP_IOCTL(..FIOSEEKDATA..) and handle that case as a hole to EOF. asomers@ confirms that it works for his ZFS test case. PR: 255523 Tested by: asomers Reviewed by:asomers MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D30076 --- sys/kern/vfs_vnops.c | 28 +++- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 832c717a33b7..d4396f67a67b 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -3099,13 +3099,13 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, struct vnode *outvp, off_t *outoffp, size_t *lenp, unsigned int flags, struct ucred *incred, struct ucred *outcred, struct thread *fsize_td) { - struct vattr va; + struct vattr va, inva; struct mount *mp; struct uio io; off_t startoff, endoff, xfer, xfer2; u_long blksize; int error, interrupted; - bool cantseek, readzeros, eof, lastblock; + bool cantseek, readzeros, eof, lastblock, holetoeof; ssize_t aresid; size_t copylen, len, rem, savlen; char *dat; @@ -3122,7 +3122,11 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, goto out; if (VOP_PATHCONF(invp, _PC_MIN_HOLE_SIZE, &holein) != 0) holein = 0; + if (holein > 0) + error = VOP_GETATTR(invp, &inva, incred); VOP_UNLOCK(invp); + if (error != 0) + goto out; mp = NULL; error = vn_start_write(outvp, &mp, V_WAIT); @@ -3203,7 +3207,7 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, * Note that some file systems such as NFSv3, NFSv4.0 and NFSv4.1 may * support holes on the server, but do not support FIOSEEKHOLE. */ - eof = false; + holetoeof = eof = false; while (len > 0 && error == 0 && !eof && interrupted == 0) { endoff = 0; /* To shut up compilers. */ cantseek = true; @@ -3212,8 +3216,7 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, /* * Find the next data area. If there is just a hole to EOF, -* FIOSEEKDATA should fail and then we drop down into the -* inner loop and create the hole on the outvp file. +* FIOSEEKDATA should fail with ENXIO. * (I do not know if any file system will report a hole to * EOF via FIOSEEKHOLE, but I am pretty sure FIOSEEKDATA * will fail for those file systems.) @@ -3222,10 +3225,16 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, * the code just falls through to the inner copy loop. */ error = EINVAL; - if (holein > 0) + if (holein > 0) { error = VOP_IOCTL(invp, FIOSEEKDATA, &startoff, 0, incred, curthread); - if (error == 0) { + if (error == ENXIO) { + startoff = endoff = inva.va_size; + eof = holetoeof = true; + error = 0; + } + } + if (error == 0 && !holetoeof) { endoff = startoff; error = VOP_IOCTL(invp, FIOSEEKHOLE, &endoff, 0, incred, curthread); @@ -3256,11 +3265,12 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, } if (error == 0 && *outoffp + xfer > - va.va_size && xfer == len) - /* Grow last block. */ + va.va_size && (xfer == len || holetoeof)) { + /* Grow ou
git: bbd5039e9197 - stable/13 - nfsd: fix stripe size reply for the File Layout pNFS server
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=bbd5039e919728c739d717344f2183c29d142f89 commit bbd5039e919728c739d717344f2183c29d142f89 Author: Rick Macklem AuthorDate: 2021-04-20 00:51:07 + Commit: Rick Macklem CommitDate: 2021-05-04 00:40:01 + nfsd: fix stripe size reply for the File Layout pNFS server At a recent testing event I found out that I had misinterpreted RFC5661 where it describes the stripe size in the File Layout's nfl_util field. This patch fixes the pNFS File Layout server so that it returns the correct value to the NFSv4.1/4.2 pNFS enabled client. This affects almost no one, since pNFS server configurations are rare and the extant pNFS aware NFS clients seemed to function correctly despite the erroneous stripe size. It *might* be needed for correct behaviour if a recent Linux client mounts a FreeBSD pNFS server configuration that is using File Layout (non-mirrored configuration). (cherry picked from commit 5a89498d19863d0c4cb074f9b93862a70040bf1b) --- sys/fs/nfsserver/nfs_nfsdstate.c | 10 ++ 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index fa7bb3ba9f56..60647ab288d8 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -6873,14 +6873,8 @@ nfsrv_filelayout(struct nfsrv_descript *nd, int iomode, fhandle_t *fhp, NFSBCOPY(devid, tl, NFSX_V4DEVICEID); /* Device ID. */ tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED); - /* -* Make the stripe size as many 64K blocks as will fit in the stripe -* mask. Since there is only one stripe, the stripe size doesn't really -* matter, except that the Linux client will only handle an exact -* multiple of their PAGE_SIZE (usually 4K). I chose 64K as a value -* that should cover most/all arches w.r.t. PAGE_SIZE. -*/ - *tl++ = txdr_unsigned(NFSFLAYUTIL_STRIPE_MASK & ~0x); + /* Set the stripe size to the maximum I/O size. */ + *tl++ = txdr_unsigned(NFS_SRVMAXIO & NFSFLAYUTIL_STRIPE_MASK); *tl++ = 0; /* 1st stripe index. */ pattern_offset = 0; txdr_hyper(pattern_offset, tl); tl += 2;/* Pattern offset. */ ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: d0fbb03a4dc5 - stable/13 - nfscommon: fix function name in comment
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=d0fbb03a4dc51d78f92c1ef37fd4b6beecb0d724 commit d0fbb03a4dc51d78f92c1ef37fd4b6beecb0d724 Author: Rick Macklem AuthorDate: 2021-04-20 03:09:46 + Commit: Rick Macklem CommitDate: 2021-05-04 00:41:48 + nfscommon: fix function name in comment (cherry picked from commit 78ffcb86d98fc9c27ac7a723c65621667036c42d) --- sys/fs/nfs/nfs_commonsubs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 4afa4c2d9ab4..a30ee458e06c 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -4614,7 +4614,7 @@ nfsmout: * Handle an NFSv4.1 Sequence request for the session. * If reply != NULL, use it to return the cached reply, as required. * The client gets a cached reply via this call for callbacks, however the - * server gets a cached reply via the nfsv4_seqsess_cachereply() call. + * server gets a cached reply via the nfsv4_seqsess_cacherep() call. */ int nfsv4_seqsession(uint32_t seqid, uint32_t slotid, uint32_t highslot, ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 51c1b8c6e2b9 - stable/12 - nfsd: fix stripe size reply for the File Layout pNFS server
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=51c1b8c6e2b90dddbd7515416ab7fd3362c44df9 commit 51c1b8c6e2b90dddbd7515416ab7fd3362c44df9 Author: Rick Macklem AuthorDate: 2021-04-20 00:51:07 + Commit: Rick Macklem CommitDate: 2021-05-04 00:45:30 + nfsd: fix stripe size reply for the File Layout pNFS server At a recent testing event I found out that I had misinterpreted RFC5661 where it describes the stripe size in the File Layout's nfl_util field. This patch fixes the pNFS File Layout server so that it returns the correct value to the NFSv4.1/4.2 pNFS enabled client. This affects almost no one, since pNFS server configurations are rare and the extant pNFS aware NFS clients seemed to function correctly despite the erroneous stripe size. It *might* be needed for correct behaviour if a recent Linux client mounts a FreeBSD pNFS server configuration that is using File Layout (non-mirrored configuration). (cherry picked from commit 5a89498d19863d0c4cb074f9b93862a70040bf1b) --- sys/fs/nfsserver/nfs_nfsdstate.c | 10 ++ 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index 5aafebf0dd77..f0c72487121c 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -6849,14 +6849,8 @@ nfsrv_filelayout(struct nfsrv_descript *nd, int iomode, fhandle_t *fhp, NFSBCOPY(devid, tl, NFSX_V4DEVICEID); /* Device ID. */ tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED); - /* -* Make the stripe size as many 64K blocks as will fit in the stripe -* mask. Since there is only one stripe, the stripe size doesn't really -* matter, except that the Linux client will only handle an exact -* multiple of their PAGE_SIZE (usually 4K). I chose 64K as a value -* that should cover most/all arches w.r.t. PAGE_SIZE. -*/ - *tl++ = txdr_unsigned(NFSFLAYUTIL_STRIPE_MASK & ~0x); + /* Set the stripe size to the maximum I/O size. */ + *tl++ = txdr_unsigned(NFS_SRVMAXIO & NFSFLAYUTIL_STRIPE_MASK); *tl++ = 0; /* 1st stripe index. */ pattern_offset = 0; txdr_hyper(pattern_offset, tl); tl += 2;/* Pattern offset. */ ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 832f2982a1cc - stable/12 - nfscommon: fix function name in comment
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=832f2982a1cc5c81521cb93712662e23c8eb380b commit 832f2982a1cc5c81521cb93712662e23c8eb380b Author: Rick Macklem AuthorDate: 2021-04-20 03:09:46 + Commit: Rick Macklem CommitDate: 2021-05-04 00:47:34 + nfscommon: fix function name in comment (cherry picked from commit 78ffcb86d98fc9c27ac7a723c65621667036c42d) --- sys/fs/nfs/nfs_commonsubs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 07652fbdb911..39cf9e9fc819 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -4556,7 +4556,7 @@ nfsmout: * Handle an NFSv4.1 Sequence request for the session. * If reply != NULL, use it to return the cached reply, as required. * The client gets a cached reply via this call for callbacks, however the - * server gets a cached reply via the nfsv4_seqsess_cachereply() call. + * server gets a cached reply via the nfsv4_seqsess_cacherep() call. */ int nfsv4_seqsession(uint32_t seqid, uint32_t slotid, uint32_t highslot, ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 0755df1eeee8 - main - nfscl: fix typo in a comment
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=0755df1838e5b114c61886d6462507290977 commit 0755df1838e5b114c61886d6462507290977 Author: Rick Macklem AuthorDate: 2021-05-04 01:29:27 + Commit: Rick Macklem CommitDate: 2021-05-04 01:29:27 + nfscl: fix typo in a comment MFC after: 2 weeks --- sys/fs/nfsclient/nfs_clrpcops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index ed95173b732b..4ce871e810fe 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -1229,7 +1229,7 @@ nfsrpc_getattr(vnode_t vp, struct ucred *cred, NFSPROC_T *p, } /* - * nfs getattr call with non-vnode arguemnts. + * nfs getattr call with non-vnode arguments. */ int nfsrpc_getattrnovp(struct nfsmount *nmp, u_int8_t *fhp, int fhlen, int syscred, ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: dd02d9d605b6 - main - nfscl: Add support for va_birthtime to NFSv4
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=dd02d9d605b6d8849e858d7644bb84b45c606b46 commit dd02d9d605b6d8849e858d7644bb84b45c606b46 Author: Rick Macklem AuthorDate: 2021-05-08 00:30:56 + Commit: Rick Macklem CommitDate: 2021-05-08 00:30:56 + nfscl: Add support for va_birthtime to NFSv4 There is a NFSv4 file attribute called TimeCreate that can be used for va_birthtime. r362175 added some support for use of TimeCreate. This patch completes support of va_birthtime by adding support for setting this attribute to the server. It also eanbles the client to acquire and set the attribute for a NFSv4 server that supports the attribute. Reviewed by:markj MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D30156 --- sys/fs/nfs/nfs_commonsubs.c | 2 ++ sys/fs/nfs/nfsproto.h| 2 ++ sys/fs/nfsclient/nfs_clcomsubs.c | 4 sys/fs/nfsclient/nfs_clport.c| 2 ++ sys/fs/nfsclient/nfs_clrpcops.c | 3 +++ sys/fs/nfsclient/nfs_clvnops.c | 5 - sys/fs/nfsserver/nfs_nfsdserv.c | 9 + 7 files changed, 26 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 539cbbbde7d2..7ddef0f19ddc 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -1248,6 +1248,8 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, nap->na_rdev = (NFSDEV_T)0; nap->na_mtime.tv_sec = 0; nap->na_mtime.tv_nsec = 0; + nap->na_btime.tv_sec = -1; + nap->na_btime.tv_nsec = 0; nap->na_gen = 0; nap->na_flags = 0; nap->na_blocksize = NFS_FABLKSIZE; diff --git a/sys/fs/nfs/nfsproto.h b/sys/fs/nfs/nfsproto.h index 236d8c14ff24..a1a992d14cdb 100644 --- a/sys/fs/nfs/nfsproto.h +++ b/sys/fs/nfs/nfsproto.h @@ -1227,6 +1227,7 @@ struct nfsv3_sattr { NFSATTRBM_RAWDEV | \ NFSATTRBM_SPACEUSED | \ NFSATTRBM_TIMEACCESS | \ + NFSATTRBM_TIMECREATE | \ NFSATTRBM_TIMEMETADATA |\ NFSATTRBM_TIMEMODIFY) @@ -1258,6 +1259,7 @@ struct nfsv3_sattr { NFSATTRBM_RAWDEV | \ NFSATTRBM_SPACEUSED | \ NFSATTRBM_TIMEACCESS | \ + NFSATTRBM_TIMECREATE | \ NFSATTRBM_TIMEMETADATA |\ NFSATTRBM_TIMEMODIFY) diff --git a/sys/fs/nfsclient/nfs_clcomsubs.c b/sys/fs/nfsclient/nfs_clcomsubs.c index 8a51d51f093f..554f5e820f54 100644 --- a/sys/fs/nfsclient/nfs_clcomsubs.c +++ b/sys/fs/nfsclient/nfs_clcomsubs.c @@ -284,6 +284,8 @@ nfsm_loadattr(struct nfsrv_descript *nd, struct nfsvattr *nap) fxdr_nfsv3time(&fp->fa3_atime, &nap->na_atime); fxdr_nfsv3time(&fp->fa3_ctime, &nap->na_ctime); fxdr_nfsv3time(&fp->fa3_mtime, &nap->na_mtime); + nap->na_btime.tv_sec = -1; + nap->na_btime.tv_nsec = 0; nap->na_flags = 0; nap->na_gen = 0; nap->na_filerev = 0; @@ -315,6 +317,8 @@ nfsm_loadattr(struct nfsrv_descript *nd, struct nfsvattr *nap) nap->na_ctime.tv_sec = fxdr_unsigned(u_int32_t, fp->fa2_ctime.nfsv2_sec); nap->na_ctime.tv_nsec = 0; + nap->na_btime.tv_sec = -1; + nap->na_btime.tv_nsec = 0; nap->na_gen = fxdr_unsigned(u_int32_t,fp->fa2_ctime.nfsv2_usec); nap->na_filerev = 0; } diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c index 64820cd11f1c..492b93340e4e 100644 --- a/sys/fs/nfsclient/nfs_clport.c +++ b/sys/fs/nfsclient/nfs_clport.c @@ -415,6 +415,7 @@ ncl_copy_vattr(struct vattr *dst, struct vattr *src) dst->va_atime = src->va_atime; dst->va_mtime = src->va_mtime; dst->va_ctime = src->va_ctime; + dst->va_birthtime = src->va_birthtime; dst->va_gen = src->va_gen; dst->va_flags = src->va_flags; dst->va_rdev = src->va_rdev; @@ -466,6 +467,7 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper, np->n_vattr.na_size = nap->na_size; np->n_vattr.na_mtime = nap->na_mtime; np->n_vattr.na_ctime = nap->n
git: 69aed9987e27 - stable/13 - nfscl: fix delegation recall when the file is not open
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=69aed9987e2790b24cfff6284e75fbad46172729 commit 69aed9987e2790b24cfff6284e75fbad46172729 Author: Rick Macklem AuthorDate: 2021-04-25 19:52:48 + Commit: Rick Macklem CommitDate: 2021-05-09 02:55:16 + nfscl: fix delegation recall when the file is not open Without this patch, if a NFSv4 server recalled a delegation when the file is not open, the renew thread would block in the NFS VOP_INACTIVE() trying to acquire the client state lock that it already holds. This patch fixes the problem by delaying the vrele() call until after the client state lock is released. This bug has been in the NFSv4 client for a long time, but since it only affects delegation when recalled due to another client opening the file, it got missed during previous testing. Until you have this patch in your client, you should avoid the use of delegations. (cherry picked from commit 02695ea8909d818ceaa726f90f889889dfd39fac) --- sys/fs/nfsclient/nfs_clstate.c | 53 -- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index e310deff6cf9..6cff58331c97 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -156,7 +156,8 @@ static void nfscl_freedeleg(struct nfscldeleghead *, struct nfscldeleg *); static int nfscl_errmap(struct nfsrv_descript *, u_int32_t); static void nfscl_cleanup_common(struct nfsclclient *, u_int8_t *); static int nfscl_recalldeleg(struct nfsclclient *, struct nfsmount *, -struct nfscldeleg *, vnode_t, struct ucred *, NFSPROC_T *, int); +struct nfscldeleg *, vnode_t, struct ucred *, NFSPROC_T *, int, +vnode_t *); static void nfscl_freeopenowner(struct nfsclowner *, int); static void nfscl_cleandeleg(struct nfscldeleg *); static int nfscl_trydelegreturn(struct nfscldeleg *, struct ucred *, @@ -2562,6 +2563,7 @@ nfscl_renewthread(struct nfsclclient *clp, NFSPROC_T *p) struct nfsclds *dsp; bool retok; struct mount *mp; + vnode_t vp; cred = newnfs_getcred(); NFSLOCKCLSTATE(); @@ -2683,7 +2685,7 @@ tryagain: NFSUNLOCKCLSTATE(); newnfs_copycred(&dp->nfsdl_cred, cred); ret = nfscl_recalldeleg(clp, clp->nfsc_nmp, dp, - NULL, cred, p, 1); + NULL, cred, p, 1, &vp); if (!ret) { nfscl_cleandeleg(dp); TAILQ_REMOVE(&clp->nfsc_deleg, dp, @@ -2694,6 +2696,22 @@ tryagain: nfsstatsv1.cldelegates--; } NFSLOCKCLSTATE(); + /* +* The nfsc_lock must be released before doing +* vrele(), since it might call nfs_inactive(). +* For the unlikely case where the vnode failed +* to be acquired by nfscl_recalldeleg(), a +* VOP_RECLAIM() should be in progress and it +* will return the delegation. +*/ + nfsv4_unlock(&clp->nfsc_lock, 0); + igotlock = 0; + if (vp != NULL) { + NFSUNLOCKCLSTATE(); + vrele(vp); + NFSLOCKCLSTATE(); + } + goto tryagain; } dp = ndp; } @@ -3943,16 +3961,18 @@ nfscl_lockt(vnode_t vp, struct nfsclclient *clp, u_int64_t off, static int nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *nmp, struct nfscldeleg *dp, vnode_t vp, struct ucred *cred, NFSPROC_T *p, -int called_from_renewthread) +int called_from_renewthread, vnode_t *vpp) { struct nfsclowner *owp, *lowp, *nowp; struct nfsclopen *op, *lop; struct nfscllockowner *lp; struct nfscllock *lckp; struct nfsnode *np; - int error = 0, ret, gotvp = 0; + int error = 0, ret; if (vp == NULL) { + KASSERT(vpp != NULL, ("nfscl_recalldeleg: vpp NULL")); + *vpp = NULL; /* * First, get a vnode for the file. This is needed to do RPCs. */ @@ -3966,7 +3986,7 @@ nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *
git: 9223cea0795f - stable/12 - nfscl: fix delegation recall when the file is not open
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=9223cea0795f1ef2a5bb856908acc78416bbc966 commit 9223cea0795f1ef2a5bb856908acc78416bbc966 Author: Rick Macklem AuthorDate: 2021-04-25 19:52:48 + Commit: Rick Macklem CommitDate: 2021-05-09 03:00:38 + nfscl: fix delegation recall when the file is not open Without this patch, if a NFSv4 server recalled a delegation when the file is not open, the renew thread would block in the NFS VOP_INACTIVE() trying to acquire the client state lock that it already holds. This patch fixes the problem by delaying the vrele() call until after the client state lock is released. This bug has been in the NFSv4 client for a long time, but since it only affects delegation when recalled due to another client opening the file, it got missed during previous testing. Until you have this patch in your client, you should avoid the use of delegations. (cherry picked from commit 02695ea8909d818ceaa726f90f889889dfd39fac) --- sys/fs/nfsclient/nfs_clstate.c | 53 -- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index 0cade3e4178a..03c046c36ccc 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -152,7 +152,8 @@ static void nfscl_freedeleg(struct nfscldeleghead *, struct nfscldeleg *); static int nfscl_errmap(struct nfsrv_descript *, u_int32_t); static void nfscl_cleanup_common(struct nfsclclient *, u_int8_t *); static int nfscl_recalldeleg(struct nfsclclient *, struct nfsmount *, -struct nfscldeleg *, vnode_t, struct ucred *, NFSPROC_T *, int); +struct nfscldeleg *, vnode_t, struct ucred *, NFSPROC_T *, int, +vnode_t *); static void nfscl_freeopenowner(struct nfsclowner *, int); static void nfscl_cleandeleg(struct nfscldeleg *); static int nfscl_trydelegreturn(struct nfscldeleg *, struct ucred *, @@ -2532,6 +2533,7 @@ nfscl_renewthread(struct nfsclclient *clp, NFSPROC_T *p) struct nfsclrecalllayout *recallp; struct nfsclds *dsp; struct mount *mp; + vnode_t vp; cred = newnfs_getcred(); NFSLOCKCLSTATE(); @@ -2651,7 +2653,7 @@ tryagain: NFSUNLOCKCLSTATE(); newnfs_copycred(&dp->nfsdl_cred, cred); ret = nfscl_recalldeleg(clp, clp->nfsc_nmp, dp, - NULL, cred, p, 1); + NULL, cred, p, 1, &vp); if (!ret) { nfscl_cleandeleg(dp); TAILQ_REMOVE(&clp->nfsc_deleg, dp, @@ -2662,6 +2664,22 @@ tryagain: nfsstatsv1.cldelegates--; } NFSLOCKCLSTATE(); + /* +* The nfsc_lock must be released before doing +* vrele(), since it might call nfs_inactive(). +* For the unlikely case where the vnode failed +* to be acquired by nfscl_recalldeleg(), a +* VOP_RECLAIM() should be in progress and it +* will return the delegation. +*/ + nfsv4_unlock(&clp->nfsc_lock, 0); + igotlock = 0; + if (vp != NULL) { + NFSUNLOCKCLSTATE(); + vrele(vp); + NFSLOCKCLSTATE(); + } + goto tryagain; } dp = ndp; } @@ -3906,16 +3924,18 @@ nfscl_lockt(vnode_t vp, struct nfsclclient *clp, u_int64_t off, static int nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *nmp, struct nfscldeleg *dp, vnode_t vp, struct ucred *cred, NFSPROC_T *p, -int called_from_renewthread) +int called_from_renewthread, vnode_t *vpp) { struct nfsclowner *owp, *lowp, *nowp; struct nfsclopen *op, *lop; struct nfscllockowner *lp; struct nfscllock *lckp; struct nfsnode *np; - int error = 0, ret, gotvp = 0; + int error = 0, ret; if (vp == NULL) { + KASSERT(vpp != NULL, ("nfscl_recalldeleg: vpp NULL")); + *vpp = NULL; /* * First, get a vnode for the file. This is needed to do RPCs. */ @@ -3929,7 +3949,7 @@ nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *
git: 5e1753891a09 - stable/13 - nfsd: fix session slot handling for failed callbacks
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=5e1753891a09df5411627e87bad7dc66226607d7 commit 5e1753891a09df5411627e87bad7dc66226607d7 Author: Rick Macklem AuthorDate: 2021-04-23 22:24:47 + Commit: Rick Macklem CommitDate: 2021-05-10 14:57:51 + nfsd: fix session slot handling for failed callbacks When the NFSv4.1/4.2 server does a callback to a client on the back channel, it will use a session slot in the back channel session. If the back channel has failed, the callback will fail and, without this patch, the session slot will not be released. As more callbacks are attempted, all session slots can become busy and then the nfsd thread gets stuck waiting for a back channel session slot. This patch frees the session slot upon callback failure to avoid this problem. Without this patch, the problem can be avoided by leaving delegations disabled in the NFS server. (cherry picked from commit 4281bfec36285e2212f41568459c077bf4dbd91c) --- sys/fs/nfsserver/nfs_nfsdstate.c | 30 ++ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index 60647ab288d8..430f09844b83 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -166,7 +166,8 @@ static int nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp, int trunc, fhandle_t *fhp, struct nfsvattr *nap, nfsattrbit_t *attrbitp, int laytype, NFSPROC_T *p); static int nfsrv_cbcallargs(struct nfsrv_descript *nd, struct nfsclient *clp, -uint32_t callback, int op, const char *optag, struct nfsdsession **sepp); +uint32_t callback, int op, const char *optag, struct nfsdsession **sepp, +int *slotposp); static u_int32_t nfsrv_nextclientindex(void); static u_int32_t nfsrv_nextstateindex(struct nfsclient *clp); static void nfsrv_markstable(struct nfsclient *clp); @@ -201,7 +202,7 @@ static void nfsrv_unlocklf(struct nfslockfile *lfp); static struct nfsdsession *nfsrv_findsession(uint8_t *sessionid); static int nfsrv_freesession(struct nfsdsession *sep, uint8_t *sessionid); static int nfsv4_setcbsequence(struct nfsrv_descript *nd, struct nfsclient *clp, -int dont_replycache, struct nfsdsession **sepp); +int dont_replycache, struct nfsdsession **sepp, int *slotposp); static int nfsv4_getcbsession(struct nfsclient *clp, struct nfsdsession **sepp); static int nfsrv_addlayout(struct nfsrv_descript *nd, struct nfslayout **lypp, nfsv4stateid_t *stateidp, char *layp, int *layoutlenp, NFSPROC_T *p); @@ -4434,7 +4435,7 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp, u_int32_t *tl; struct nfsrv_descript *nd; struct ucred *cred; - int error = 0; + int error = 0, slotpos; u_int32_t callback; struct nfsdsession *sep = NULL; uint64_t tval; @@ -4492,7 +4493,7 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp, if (procnum == NFSV4OP_CBGETATTR) { nd->nd_procnum = NFSV4PROC_CBCOMPOUND; error = nfsrv_cbcallargs(nd, clp, callback, NFSV4OP_CBGETATTR, - "CB Getattr", &sep); + "CB Getattr", &sep, &slotpos); if (error != 0) { m_freem(nd->nd_mreq); goto errout; @@ -4502,7 +4503,7 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp, } else if (procnum == NFSV4OP_CBRECALL) { nd->nd_procnum = NFSV4PROC_CBCOMPOUND; error = nfsrv_cbcallargs(nd, clp, callback, NFSV4OP_CBRECALL, - "CB Recall", &sep); + "CB Recall", &sep, &slotpos); if (error != 0) { m_freem(nd->nd_mreq); goto errout; @@ -4521,7 +4522,7 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp, NFSD_DEBUG(4, "docallback layout recall\n"); nd->nd_procnum = NFSV4PROC_CBCOMPOUND; error = nfsrv_cbcallargs(nd, clp, callback, - NFSV4OP_CBLAYOUTRECALL, "CB Reclayout", &sep); + NFSV4OP_CBLAYOUTRECALL, "CB Reclayout", &sep, &slotpos); NFSD_DEBUG(4, "aft cbcallargs=%d\n", error); if (error != 0) { m_freem(nd->nd_mreq); @@ -4570,6 +4571,8 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp, if (clp->lc_req.nr_client == NULL) { if ((clp->lc_flags & LCL_NFSV41) != 0) { error =
git: 272f39942254 - stable/13 - nfsd: fix the slot sequence# when a callback fails
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=272f39942254ea721a06413241ae2632cdd45077 commit 272f39942254ea721a06413241ae2632cdd45077 Author: Rick Macklem AuthorDate: 2021-04-26 23:24:10 + Commit: Rick Macklem CommitDate: 2021-05-10 15:01:42 + nfsd: fix the slot sequence# when a callback fails Commit 4281bfec3628 patched the server so that the callback session slot would be free'd for reuse when a callback attempt fails. However, this can often result in the sequence# for the session slot to be advanced such that the client end will reply NFSERR_SEQMISORDERED. To avoid the NFSERR_SEQMISORDERED client reply, this patch negates the sequence# advance for the case where the callback has failed. The common case is a failed back channel, where the callback cannot be sent to the client, and not advancing the sequence# is correct for this case. For the uncommon case where the client's reply to the callback is lost, not advancing the sequence# will indicate to the client that the next callback is a retry and not a new callback. But, since the FreeBSD server always sets "csa_cachethis" false in the callback sequence operation, a retry and a new callback should be handled the same way by the client, so this should not matter. Until you have this patch in your NFSv4.1/4.2 server, you should consider avoiding the use of delegations. Even with this patch, interoperation with the Linux NFSv4.1/4.2 client in kernel versions prior to 5.3 can result in frequent 15second delays if delegations are enabled. This occurs because, for kernels prior to 5.3, the Linux client does a TCP reconnect every time it sees multiple concurrent callbacks and then it takes 15seconds to recover the back channel after doing so. (cherry picked from commit 87597731488105dd1ab921a95e39bb62e1abe668) --- sys/fs/nfs/nfs_commonkrpc.c | 4 ++-- sys/fs/nfs/nfs_commonsubs.c | 4 +++- sys/fs/nfs/nfs_var.h | 2 +- sys/fs/nfsserver/nfs_nfsdstate.c | 23 --- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index daf8082fa1c3..6e766abcf4b1 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -871,7 +871,7 @@ tryagain: sep->nfsess_slotseq[nd->nd_slotid] += 10; mtx_unlock(&sep->nfsess_mtx); /* And free the slot. */ - nfsv4_freeslot(sep, nd->nd_slotid); + nfsv4_freeslot(sep, nd->nd_slotid, false); } NFSINCRGLOBAL(nfsstatsv1.rpcinvalid); error = ENXIO; @@ -1108,7 +1108,7 @@ tryagain: if ((nd->nd_flag & ND_NFSV4) != 0) { /* Free the slot, as required. */ if (freeslot != -1) - nfsv4_freeslot(sep, freeslot); + nfsv4_freeslot(sep, freeslot, false); /* * If this op is Putfh, throw its results away. */ diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index a30ee458e06c..539cbbbde7d2 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -4811,7 +4811,7 @@ nfsv4_sequencelookup(struct nfsmount *nmp, struct nfsclsession *sep, * Free a session slot. */ void -nfsv4_freeslot(struct nfsclsession *sep, int slot) +nfsv4_freeslot(struct nfsclsession *sep, int slot, bool resetseq) { uint64_t bitval; @@ -4819,6 +4819,8 @@ nfsv4_freeslot(struct nfsclsession *sep, int slot) if (slot > 0) bitval <<= slot; mtx_lock(&sep->nfsess_mtx); + if (resetseq) + sep->nfsess_slotseq[slot]--; if ((bitval & sep->nfsess_slots) == 0) printf("freeing free slot!!\n"); sep->nfsess_slots &= ~bitval; diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 0297b52015f8..23ba0e3893db 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -355,7 +355,7 @@ void nfsv4_setsequence(struct nfsmount *, struct nfsrv_descript *, struct nfsclsession *, int); int nfsv4_sequencelookup(struct nfsmount *, struct nfsclsession *, int *, int *, uint32_t *, uint8_t *); -void nfsv4_freeslot(struct nfsclsession *, int); +void nfsv4_freeslot(struct nfsclsession *, int, bool); struct ucred *nfsrv_getgrpscred(struct ucred *); struct nfsdevice *nfsv4_findmirror(struct nfsmount *); void nfsm_set(struct nfsrv_descript *, u_int); diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index 430f09844b83..3aebddad0962 100644 --- a/s
git: 8f81f190a640 - stable/13 - param.h: Bump __FreeBSD_version to 1300505 for 272f39942254
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=8f81f190a640e211dd814bdde7811982b9491fb0 commit 8f81f190a640e211dd814bdde7811982b9491fb0 Author: Rick Macklem AuthorDate: 2021-05-10 15:14:57 + Commit: Rick Macklem CommitDate: 2021-05-10 15:14:57 + param.h: Bump __FreeBSD_version to 1300505 for 272f39942254 Commit 272f39942254 changed the internal KAPI between the nscl.ko and nfscommon.ko modules, so they both need to be rebuilt from sources. --- sys/sys/param.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/sys/param.h b/sys/sys/param.h index db5a31d60267..3d1ab448eae4 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -60,7 +60,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1300504 /* Master, propagated to newvers */ +#define __FreeBSD_version 1300505 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 4e1c728f1926 - stable/13 - UPDATING: Add an entry for commit 272f39942254
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=4e1c728f1926b8563358ffb2df2e6e9d79000db9 commit 4e1c728f1926b8563358ffb2df2e6e9d79000db9 Author: Rick Macklem AuthorDate: 2021-05-10 15:20:48 + Commit: Rick Macklem CommitDate: 2021-05-10 15:20:48 + UPDATING: Add an entry for commit 272f39942254 --- UPDATING | 5 + 1 file changed, 5 insertions(+) diff --git a/UPDATING b/UPDATING index 7a07f2d8fe35..f7e3996e8d48 100644 --- a/UPDATING +++ b/UPDATING @@ -12,6 +12,11 @@ Items affecting the ports and packages system can be found in /usr/ports/UPDATING. Please read that file before updating system packages and/or ports. +20210510: + Commit 272f39942254 changed the internal KAPI between the + nscl.ko and nfscommon.ko modules, so they both need to be + rebuilt from sources. + 20210429: Commit 5a45802b3c8c changed the internal KAPI between the krpc and NFS. As such, the krpc, nfscommon and ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: c86420ea7dcd - stable/12 - nfsd: fix session slot handling for failed callbacks
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=c86420ea7dcda16b4fd32c19cde54b128677f371 commit c86420ea7dcda16b4fd32c19cde54b128677f371 Author: Rick Macklem AuthorDate: 2021-04-23 22:24:47 + Commit: Rick Macklem CommitDate: 2021-05-10 15:51:18 + nfsd: fix session slot handling for failed callbacks When the NFSv4.1/4.2 server does a callback to a client on the back channel, it will use a session slot in the back channel session. If the back channel has failed, the callback will fail and, without this patch, the session slot will not be released. As more callbacks are attempted, all session slots can become busy and then the nfsd thread gets stuck waiting for a back channel session slot. This patch frees the session slot upon callback failure to avoid this problem. Without this patch, the problem can be avoided by leaving delegations disabled in the NFS server. (cherry picked from commit 4281bfec36285e2212f41568459c077bf4dbd91c) --- sys/fs/nfsserver/nfs_nfsdstate.c | 30 ++ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index f0c72487121c..a093d5db9a18 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -166,7 +166,8 @@ static int nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp, int trunc, fhandle_t *fhp, struct nfsvattr *nap, nfsattrbit_t *attrbitp, int laytype, NFSPROC_T *p); static int nfsrv_cbcallargs(struct nfsrv_descript *nd, struct nfsclient *clp, -uint32_t callback, int op, const char *optag, struct nfsdsession **sepp); +uint32_t callback, int op, const char *optag, struct nfsdsession **sepp, +int *slotposp); static u_int32_t nfsrv_nextclientindex(void); static u_int32_t nfsrv_nextstateindex(struct nfsclient *clp); static void nfsrv_markstable(struct nfsclient *clp); @@ -201,7 +202,7 @@ static void nfsrv_unlocklf(struct nfslockfile *lfp); static struct nfsdsession *nfsrv_findsession(uint8_t *sessionid); static int nfsrv_freesession(struct nfsdsession *sep, uint8_t *sessionid); static int nfsv4_setcbsequence(struct nfsrv_descript *nd, struct nfsclient *clp, -int dont_replycache, struct nfsdsession **sepp); +int dont_replycache, struct nfsdsession **sepp, int *slotposp); static int nfsv4_getcbsession(struct nfsclient *clp, struct nfsdsession **sepp); static int nfsrv_addlayout(struct nfsrv_descript *nd, struct nfslayout **lypp, nfsv4stateid_t *stateidp, char *layp, int *layoutlenp, NFSPROC_T *p); @@ -4430,7 +4431,7 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp, u_int32_t *tl; struct nfsrv_descript *nd; struct ucred *cred; - int error = 0; + int error = 0, slotpos; u_int32_t callback; struct nfsdsession *sep = NULL; uint64_t tval; @@ -4485,7 +4486,7 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp, if (procnum == NFSV4OP_CBGETATTR) { nd->nd_procnum = NFSV4PROC_CBCOMPOUND; error = nfsrv_cbcallargs(nd, clp, callback, NFSV4OP_CBGETATTR, - "CB Getattr", &sep); + "CB Getattr", &sep, &slotpos); if (error != 0) { mbuf_freem(nd->nd_mreq); goto errout; @@ -4495,7 +4496,7 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp, } else if (procnum == NFSV4OP_CBRECALL) { nd->nd_procnum = NFSV4PROC_CBCOMPOUND; error = nfsrv_cbcallargs(nd, clp, callback, NFSV4OP_CBRECALL, - "CB Recall", &sep); + "CB Recall", &sep, &slotpos); if (error != 0) { mbuf_freem(nd->nd_mreq); goto errout; @@ -4514,7 +4515,7 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp, NFSD_DEBUG(4, "docallback layout recall\n"); nd->nd_procnum = NFSV4PROC_CBCOMPOUND; error = nfsrv_cbcallargs(nd, clp, callback, - NFSV4OP_CBLAYOUTRECALL, "CB Reclayout", &sep); + NFSV4OP_CBLAYOUTRECALL, "CB Reclayout", &sep, &slotpos); NFSD_DEBUG(4, "aft cbcallargs=%d\n", error); if (error != 0) { mbuf_freem(nd->nd_mreq); @@ -4560,6 +4561,8 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp, if (clp->lc_req.nr_client == NULL) { if ((clp->lc_flags & LCL_NFSV41) != 0) { error =
git: e9959506d2cc - stable/12 - nfsd: fix the slot sequence# when a callback fails
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=e9959506d2cc2fd728be8cef5babbcd019c4fcd2 commit e9959506d2cc2fd728be8cef5babbcd019c4fcd2 Author: Rick Macklem AuthorDate: 2021-04-26 23:24:10 + Commit: Rick Macklem CommitDate: 2021-05-10 15:53:15 + nfsd: fix the slot sequence# when a callback fails Commit 4281bfec3628 patched the server so that the callback session slot would be free'd for reuse when a callback attempt fails. However, this can often result in the sequence# for the session slot to be advanced such that the client end will reply NFSERR_SEQMISORDERED. To avoid the NFSERR_SEQMISORDERED client reply, this patch negates the sequence# advance for the case where the callback has failed. The common case is a failed back channel, where the callback cannot be sent to the client, and not advancing the sequence# is correct for this case. For the uncommon case where the client's reply to the callback is lost, not advancing the sequence# will indicate to the client that the next callback is a retry and not a new callback. But, since the FreeBSD server always sets "csa_cachethis" false in the callback sequence operation, a retry and a new callback should be handled the same way by the client, so this should not matter. Until you have this patch in your NFSv4.1/4.2 server, you should consider avoiding the use of delegations. Even with this patch, interoperation with the Linux NFSv4.1/4.2 client in kernel versions prior to 5.3 can result in frequent 15second delays if delegations are enabled. This occurs because, for kernels prior to 5.3, the Linux client does a TCP reconnect every time it sees multiple concurrent callbacks and then it takes 15seconds to recover the back channel after doing so. (cherry picked from commit 87597731488105dd1ab921a95e39bb62e1abe668) --- sys/fs/nfs/nfs_commonkrpc.c | 4 ++-- sys/fs/nfs/nfs_commonsubs.c | 4 +++- sys/fs/nfs/nfs_var.h | 2 +- sys/fs/nfsserver/nfs_nfsdstate.c | 23 --- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 78b6d0ed6985..449b3ad5e4a7 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -866,7 +866,7 @@ tryagain: sep->nfsess_slotseq[nd->nd_slotid] += 10; mtx_unlock(&sep->nfsess_mtx); /* And free the slot. */ - nfsv4_freeslot(sep, nd->nd_slotid); + nfsv4_freeslot(sep, nd->nd_slotid, false); } NFSINCRGLOBAL(nfsstatsv1.rpcinvalid); error = ENXIO; @@ -1103,7 +1103,7 @@ tryagain: if ((nd->nd_flag & ND_NFSV4) != 0) { /* Free the slot, as required. */ if (freeslot != -1) - nfsv4_freeslot(sep, freeslot); + nfsv4_freeslot(sep, freeslot, false); /* * If this op is Putfh, throw its results away. */ diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 39cf9e9fc819..390d6e91535f 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -4751,7 +4751,7 @@ nfsv4_sequencelookup(struct nfsmount *nmp, struct nfsclsession *sep, * Free a session slot. */ void -nfsv4_freeslot(struct nfsclsession *sep, int slot) +nfsv4_freeslot(struct nfsclsession *sep, int slot, bool resetseq) { uint64_t bitval; @@ -4759,6 +4759,8 @@ nfsv4_freeslot(struct nfsclsession *sep, int slot) if (slot > 0) bitval <<= slot; mtx_lock(&sep->nfsess_mtx); + if (resetseq) + sep->nfsess_slotseq[slot]--; if ((bitval & sep->nfsess_slots) == 0) printf("freeing free slot!!\n"); sep->nfsess_slots &= ~bitval; diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 9c8942e27132..bee66d15b016 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -345,7 +345,7 @@ void nfsv4_setsequence(struct nfsmount *, struct nfsrv_descript *, struct nfsclsession *, int); int nfsv4_sequencelookup(struct nfsmount *, struct nfsclsession *, int *, int *, uint32_t *, uint8_t *); -void nfsv4_freeslot(struct nfsclsession *, int); +void nfsv4_freeslot(struct nfsclsession *, int, bool); struct ucred *nfsrv_getgrpscred(struct ucred *); struct nfsdevice *nfsv4_findmirror(struct nfsmount *); diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index a093d5db9a18..9171891478c1 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nf
git: 1e279fe9deae - stable/12 - param.h: Bump __FreeBSD_version to 1202507 for commit e9959506d2cc
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=1e279fe9deaea1c5e3503117dd3077dcffb1276d commit 1e279fe9deaea1c5e3503117dd3077dcffb1276d Author: Rick Macklem AuthorDate: 2021-05-10 16:00:50 + Commit: Rick Macklem CommitDate: 2021-05-10 16:00:50 + param.h: Bump __FreeBSD_version to 1202507 for commit e9959506d2cc Commit e9959506d2cc changed the internal KAPI between the nfscl.ko and nfscommon.ko modules, so they both need to be rebuilt from sources. --- sys/sys/param.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/sys/param.h b/sys/sys/param.h index 89ab74bc07a6..1e3fd909956a 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -60,7 +60,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1202506 /* Master, propagated to newvers */ +#define __FreeBSD_version 1202507 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 304e740b7ea8 - stable/12 - UPDATING: Add an entry for commit e9959506d2cc
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=304e740b7ea89c508efa5e47cbd9317d41e8e52f commit 304e740b7ea89c508efa5e47cbd9317d41e8e52f Author: Rick Macklem AuthorDate: 2021-05-10 16:05:10 + Commit: Rick Macklem CommitDate: 2021-05-10 16:05:10 + UPDATING: Add an entry for commit e9959506d2cc --- UPDATING | 5 + 1 file changed, 5 insertions(+) diff --git a/UPDATING b/UPDATING index 225f0ca05baa..f1dceda848e2 100644 --- a/UPDATING +++ b/UPDATING @@ -17,6 +17,11 @@ from older versions of FreeBSD, try WITHOUT_CLANG and WITH_GCC to bootstrap to the tip of head, and then rebuild without this option. The bootstrap process from older version of current across the gcc/clang cutover is a bit fragile. +20210510: + Commit e9959506d2cc changed the internal KAPI between the + nscl.ko and nfscommon.ko modules, so they both need to be + rebuilt from sources. + 20210430: Commit 0a1fdb867c72 changed the internal KAPI between the krpc and NFS. As such, the krpc, nfscommon and ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: cb07628d9e7c - main - nfscl: Delete unneeded redundant MODULE_DEPEND() calls
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=cb07628d9e7c84019f99e2dfeadbe0957e5c22e8 commit cb07628d9e7c84019f99e2dfeadbe0957e5c22e8 Author: Rick Macklem AuthorDate: 2021-05-11 00:34:29 + Commit: Rick Macklem CommitDate: 2021-05-11 00:34:29 + nfscl: Delete unneeded redundant MODULE_DEPEND() calls There are two module declarations in the nfscl.ko module for "nfscl" and "nfs". Both of these declarations had MODULE_DEPEND() calls. This patch deletes the MODULE_DEPEND() calls for "nfs" to avoid confusion with respect to what modules this module is dependent upon. The patch also adds comments explaining why there are two module declarations within the module. Reviewed by:kib Differential Revision: https://reviews.freebsd.org/D30102 --- sys/fs/nfsclient/nfs_clport.c | 9 + sys/fs/nfsclient/nfs_clvfsops.c | 14 -- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c index 492b93340e4e..4676f09f8e86 100644 --- a/sys/fs/nfsclient/nfs_clport.c +++ b/sys/fs/nfsclient/nfs_clport.c @@ -1438,6 +1438,14 @@ static moduledata_t nfscl_mod = { nfscl_modevent, NULL, }; +/* + * This is the main module declaration for the NFS client. The + * nfscl_modevent() function is needed to ensure that the module + * cannot be unloaded, among other things. + * There is also a module declaration in sys/fs/nfsclient/nfs_clvfsops.c + * for the name "nfs" within the VFS_SET() macro that defines the "nfs" + * file system type. + */ DECLARE_MODULE(nfscl, nfscl_mod, SI_SUB_VFS, SI_ORDER_FIRST); /* So that loader and kldload(2) can find us, wherever we are.. */ @@ -1445,3 +1453,4 @@ MODULE_VERSION(nfscl, 1); MODULE_DEPEND(nfscl, nfscommon, 1, 1, 1); MODULE_DEPEND(nfscl, krpc, 1, 1, 1); MODULE_DEPEND(nfscl, nfssvc, 1, 1, 1); +MODULE_DEPEND(nfscl, xdr, 1, 1, 1); diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 08a25c6fe632..847bf72acf0c 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -148,14 +147,17 @@ static struct vfsops nfs_vfsops = { .vfs_sysctl = nfs_sysctl, .vfs_purge =nfs_purge, }; +/* + * This macro declares that the file system type is named "nfs". + * It also declares a module name of "nfs" and uses vfs_modevent() + * as the event handling function. + * The main module declaration is found in sys/fs/nfsclient/nfs_clport.c + * for "nfscl" and is needed so that a custom event handling + * function gets called. MODULE_DEPEND() macros are found there. + */ VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK | VFCF_SBDRY); -/* So that loader and kldload(2) can find us, wherever we are.. */ MODULE_VERSION(nfs, 1); -MODULE_DEPEND(nfs, nfscommon, 1, 1, 1); -MODULE_DEPEND(nfs, krpc, 1, 1, 1); -MODULE_DEPEND(nfs, nfssvc, 1, 1, 1); -MODULE_DEPEND(nfs, xdr, 1, 1, 1); /* * This structure is now defined in sys/nfs/nfs_diskless.c so that it ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 3e67975a0c08 - stable/13 - nfsd: fix a NFSv4.1 Linux client mount stuck in CLOSE_WAIT
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=3e67975a0c0807073daff24a3b6fa8942d3305d2 commit 3e67975a0c0807073daff24a3b6fa8942d3305d2 Author: Rick Macklem AuthorDate: 2021-04-27 22:32:35 + Commit: Rick Macklem CommitDate: 2021-05-11 01:12:21 + nfsd: fix a NFSv4.1 Linux client mount stuck in CLOSE_WAIT It was reported that a NFSv4.1 Linux client mount against a FreeBSD12 server was hung, with the TCP connection in CLOSE_WAIT state on the server. When a NFSv4.1/4.2 mount is done and the back channel is bound to the TCP connection, the soclose() is delayed until a new TCP connection is bound to the back channel, due to a reference count being held on the SVCXPRT structure in the krpc for the socket. Without the soclose() call, the socket will remain in CLOSE_WAIT and this somehow caused the Linux client to hang. This patch adds calls to soshutdown(.., SHUT_WR) that are performed when the server side krpc sees that the socket is no longer usable. Since this can be done before the back channel is bound to a new TCP connection, it allows the TCP connection to proceed to CLOSED state. PR: 254590 (cherry picked from commit db8c27f499105dcc9872dcc46e88bdd570c24fee) --- sys/rpc/svc.c | 5 + 1 file changed, 5 insertions(+) diff --git a/sys/rpc/svc.c b/sys/rpc/svc.c index a059096e7b77..be0f08ebca9d 100644 --- a/sys/rpc/svc.c +++ b/sys/rpc/svc.c @@ -203,6 +203,8 @@ svcpool_cleanup(SVCPOOL *pool) mtx_unlock(&grp->sg_lock); } TAILQ_FOREACH_SAFE(xprt, &cleanup, xp_link, nxprt) { + if (xprt->xp_socket != NULL) + soshutdown(xprt->xp_socket, SHUT_WR); SVC_RELEASE(xprt); } @@ -388,6 +390,8 @@ xprt_unregister(SVCXPRT *xprt) xprt_unregister_locked(xprt); mtx_unlock(&grp->sg_lock); + if (xprt->xp_socket != NULL) + soshutdown(xprt->xp_socket, SHUT_WR); SVC_RELEASE(xprt); } @@ -1078,6 +1082,7 @@ svc_checkidle(SVCGROUP *grp) mtx_unlock(&grp->sg_lock); TAILQ_FOREACH_SAFE(xprt, &cleanup, xp_link, nxprt) { + soshutdown(xprt->xp_socket, SHUT_WR); SVC_RELEASE(xprt); } mtx_lock(&grp->sg_lock); ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 3bcaad593004 - stable/13 - nfscl: fix the handling of NFSERR_DELAY for Open/LayoutGet RPCs
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=3bcaad5930046d64645923dd2286dff3dce09eed commit 3bcaad5930046d64645923dd2286dff3dce09eed Author: Rick Macklem AuthorDate: 2021-04-27 00:48:21 + Commit: Rick Macklem CommitDate: 2021-05-11 01:14:20 + nfscl: fix the handling of NFSERR_DELAY for Open/LayoutGet RPCs For a pNFS mount, the NFSv4.1/4.2 client uses compound RPCs that have both Open and LayoutGet operations in them. If the pNFS server were tp reply NFSERR_DELAY for one of these compounds, the retry after a delay cannot be handled by newnfs_request(), since there is a reference held on the open state for the Open operation in them. Fix this by adding these RPCs to the "don't do delay here" list in newnfs_request(). This patch is only needed if the mount is using pNFS (the "pnfs" mount option) and probably only matters if the MDS server is issuing delegations as well as pNFS layouts. Found by code inspection. (cherry picked from commit f5ff282bc025f0395afcef40f5b6e778202c4181) --- sys/fs/nfs/nfs_commonkrpc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 6e766abcf4b1..49c68da45a69 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -1067,7 +1067,9 @@ tryagain: nd->nd_procnum != NFSPROC_WRITE && nd->nd_procnum != NFSPROC_WRITEDS && nd->nd_procnum != NFSPROC_OPEN && +nd->nd_procnum != NFSPROC_OPENLAYGET && nd->nd_procnum != NFSPROC_CREATE && +nd->nd_procnum != NFSPROC_CREATELAYGET && nd->nd_procnum != NFSPROC_OPENCONFIRM && nd->nd_procnum != NFSPROC_OPENDOWNGRADE && nd->nd_procnum != NFSPROC_CLOSE && ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 16e172a410bf - stable/12 - nfsd: fix a NFSv4.1 Linux client mount stuck in CLOSE_WAIT
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=16e172a410bff6d2c67523fe949424ab055b46a6 commit 16e172a410bff6d2c67523fe949424ab055b46a6 Author: Rick Macklem AuthorDate: 2021-04-27 22:32:35 + Commit: Rick Macklem CommitDate: 2021-05-11 01:19:54 + nfsd: fix a NFSv4.1 Linux client mount stuck in CLOSE_WAIT It was reported that a NFSv4.1 Linux client mount against a FreeBSD12 server was hung, with the TCP connection in CLOSE_WAIT state on the server. When a NFSv4.1/4.2 mount is done and the back channel is bound to the TCP connection, the soclose() is delayed until a new TCP connection is bound to the back channel, due to a reference count being held on the SVCXPRT structure in the krpc for the socket. Without the soclose() call, the socket will remain in CLOSE_WAIT and this somehow caused the Linux client to hang. This patch adds calls to soshutdown(.., SHUT_WR) that are performed when the server side krpc sees that the socket is no longer usable. Since this can be done before the back channel is bound to a new TCP connection, it allows the TCP connection to proceed to CLOSED state. PR: 254590 (cherry picked from commit db8c27f499105dcc9872dcc46e88bdd570c24fee) --- sys/rpc/svc.c | 5 + 1 file changed, 5 insertions(+) diff --git a/sys/rpc/svc.c b/sys/rpc/svc.c index cd44b8fd53b7..8fe457c63cc3 100644 --- a/sys/rpc/svc.c +++ b/sys/rpc/svc.c @@ -203,6 +203,8 @@ svcpool_cleanup(SVCPOOL *pool) mtx_unlock(&grp->sg_lock); } TAILQ_FOREACH_SAFE(xprt, &cleanup, xp_link, nxprt) { + if (xprt->xp_socket != NULL) + soshutdown(xprt->xp_socket, SHUT_WR); SVC_RELEASE(xprt); } @@ -388,6 +390,8 @@ xprt_unregister(SVCXPRT *xprt) xprt_unregister_locked(xprt); mtx_unlock(&grp->sg_lock); + if (xprt->xp_socket != NULL) + soshutdown(xprt->xp_socket, SHUT_WR); SVC_RELEASE(xprt); } @@ -1076,6 +1080,7 @@ svc_checkidle(SVCGROUP *grp) mtx_unlock(&grp->sg_lock); TAILQ_FOREACH_SAFE(xprt, &cleanup, xp_link, nxprt) { + soshutdown(xprt->xp_socket, SHUT_WR); SVC_RELEASE(xprt); } mtx_lock(&grp->sg_lock); ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: d0c90712df75 - stable/12 - nfscl: fix the handling of NFSERR_DELAY for Open/LayoutGet RPCs
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=d0c90712df75e588cc1fa1f68a93f67ba9ff80c6 commit d0c90712df75e588cc1fa1f68a93f67ba9ff80c6 Author: Rick Macklem AuthorDate: 2021-04-27 00:48:21 + Commit: Rick Macklem CommitDate: 2021-05-11 01:23:12 + nfscl: fix the handling of NFSERR_DELAY for Open/LayoutGet RPCs For a pNFS mount, the NFSv4.1/4.2 client uses compound RPCs that have both Open and LayoutGet operations in them. If the pNFS server were tp reply NFSERR_DELAY for one of these compounds, the retry after a delay cannot be handled by newnfs_request(), since there is a reference held on the open state for the Open operation in them. Fix this by adding these RPCs to the "don't do delay here" list in newnfs_request(). This patch is only needed if the mount is using pNFS (the "pnfs" mount option) and probably only matters if the MDS server is issuing delegations as well as pNFS layouts. Found by code inspection. (cherry picked from commit f5ff282bc025f0395afcef40f5b6e778202c4181) --- sys/fs/nfs/nfs_commonkrpc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 449b3ad5e4a7..b6fe49b8e470 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -1062,7 +1062,9 @@ tryagain: nd->nd_procnum != NFSPROC_WRITE && nd->nd_procnum != NFSPROC_WRITEDS && nd->nd_procnum != NFSPROC_OPEN && +nd->nd_procnum != NFSPROC_OPENLAYGET && nd->nd_procnum != NFSPROC_CREATE && +nd->nd_procnum != NFSPROC_CREATELAYGET && nd->nd_procnum != NFSPROC_OPENCONFIRM && nd->nd_procnum != NFSPROC_OPENDOWNGRADE && nd->nd_procnum != NFSPROC_CLOSE && ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 7e35a8a28c6f - stable/13 - nfscl: return delegations in the NFS VOP_RECLAIM()
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=7e35a8a28c6f719ad4e8b8e33bbc0b7a5901e008 commit 7e35a8a28c6f719ad4e8b8e33bbc0b7a5901e008 Author: Rick Macklem AuthorDate: 2021-04-26 00:57:55 + Commit: Rick Macklem CommitDate: 2021-05-12 02:15:26 + nfscl: return delegations in the NFS VOP_RECLAIM() After a vnode is recycled it can no longer be acquired via vfs_hash_get() and, as such, a delegation for the vnode cannot be recalled. In the unlikely event that a delegation still exists when the vnode is being recycled, return the delegation since it will no longer be recallable. Until you have this patch in your NFSv4 client, you should consider avoiding the use of delegations. (cherry picked from commit aad780464fad1e32c97316515a4044d661413a6b) --- sys/fs/nfs/nfs_var.h | 1 + sys/fs/nfsclient/nfs_clnode.c | 10 - sys/fs/nfsclient/nfs_clstate.c | 49 ++ 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 23ba0e3893db..f23d56050449 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -604,6 +604,7 @@ void nfscl_lockinit(struct nfsv4lock *); void nfscl_lockexcl(struct nfsv4lock *, void *); void nfscl_lockunlock(struct nfsv4lock *); void nfscl_lockderef(struct nfsv4lock *); +void nfscl_delegreturnvp(vnode_t, NFSPROC_T *); void nfscl_docb(struct nfsrv_descript *, NFSPROC_T *); void nfscl_releasealllocks(struct nfsclclient *, vnode_t, NFSPROC_T *, void *, int); diff --git a/sys/fs/nfsclient/nfs_clnode.c b/sys/fs/nfsclient/nfs_clnode.c index a59b96bf3c8b..43c2286726f7 100644 --- a/sys/fs/nfsclient/nfs_clnode.c +++ b/sys/fs/nfsclient/nfs_clnode.c @@ -303,7 +303,7 @@ ncl_reclaim(struct vop_reclaim_args *ap) ncl_releasesillyrename(vp, td); NFSUNLOCKNODE(np); - if (NFS_ISV4(vp) && vp->v_type == VREG) + if (NFS_ISV4(vp) && vp->v_type == VREG) { /* * We can now safely close any remaining NFSv4 Opens for * this file. Most opens will have already been closed by @@ -311,6 +311,14 @@ ncl_reclaim(struct vop_reclaim_args *ap) * called, so we need to do it again here. */ (void) nfsrpc_close(vp, 1, td); + /* +* It it unlikely a delegation will still exist, but +* if one does, it must be returned before calling +* vfs_hash_remove(), since it cannot be recalled once the +* nfs node is no longer available. +*/ + nfscl_delegreturnvp(vp, td); + } vfs_hash_remove(vp); diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index 6cff58331c97..bbc1c6ccbc2f 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -152,7 +152,8 @@ static int nfscl_trylock(struct nfsmount *, vnode_t , u_int8_t *, struct ucred *, NFSPROC_T *); static int nfsrpc_reopen(struct nfsmount *, u_int8_t *, int, u_int32_t, struct nfsclopen *, struct nfscldeleg **, struct ucred *, NFSPROC_T *); -static void nfscl_freedeleg(struct nfscldeleghead *, struct nfscldeleg *); +static void nfscl_freedeleg(struct nfscldeleghead *, struct nfscldeleg *, +bool); static int nfscl_errmap(struct nfsrv_descript *, u_int32_t); static void nfscl_cleanup_common(struct nfsclclient *, u_int8_t *); static int nfscl_recalldeleg(struct nfsclclient *, struct nfsmount *, @@ -1622,12 +1623,13 @@ nfscl_cleandeleg(struct nfscldeleg *dp) * Free a delegation. */ static void -nfscl_freedeleg(struct nfscldeleghead *hdp, struct nfscldeleg *dp) +nfscl_freedeleg(struct nfscldeleghead *hdp, struct nfscldeleg *dp, bool freeit) { TAILQ_REMOVE(hdp, dp, nfsdl_list); LIST_REMOVE(dp, nfsdl_hash); - free(dp, M_NFSCLDELEG); + if (freeit) + free(dp, M_NFSCLDELEG); nfsstatsv1.cldelegates--; nfscl_delegcnt--; } @@ -1725,7 +1727,7 @@ nfscl_expireclient(struct nfsclclient *clp, struct nfsmount *nmp, printf("nfsv4 expired locks lost\n"); } nfscl_cleandeleg(dp); - nfscl_freedeleg(&clp->nfsc_deleg, dp); + nfscl_freedeleg(&clp->nfsc_deleg, dp, true); dp = ndp; } if (!TAILQ_EMPTY(&clp->nfsc_deleg)) @@ -2257,7 +2259,7 @@ nfscl_recover(struct nfsclclient *clp, bool *retokp, struct ucred *cred, * away. Ouch!! */ nfscl_cleandeleg(dp); - nfscl_freedeleg(&clp->nfsc_deleg, dp); + nfscl_freedeleg(&clp->nfsc_deleg, dp, true); } else { LIST_INSERT_HEAD(&extra_open, nop, nfso_list)
git: f6bc043b7a16 - stable/13 - nfscl: add check for NULL clp and forced dismounts to nfscl_delegreturnvp()
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=f6bc043b7a16529fa475b1759011a1bdf83f9652 commit f6bc043b7a16529fa475b1759011a1bdf83f9652 Author: Rick Macklem AuthorDate: 2021-04-28 00:30:16 + Commit: Rick Macklem CommitDate: 2021-05-12 02:18:17 + nfscl: add check for NULL clp and forced dismounts to nfscl_delegreturnvp() Commit aad780464fad added a function called nfscl_delegreturnvp() to return delegations during the NFS VOP_RECLAIM(). The function erroneously assumed that nm_clp would be non-NULL. It will be NULL for NFSV4.0 mounts until a regular file is opened. It will also be NULL during vflush() in nfs_unmount() for a forced dismount. This patch adds a check for clp == NULL to fix this. Also, since it makes no sense to call nfscl_delegreturnvp() during a forced dismount, the patch adds a check for that case and does not do the call during forced dismounts. PR: 255436 (cherry picked from commit f6fec55fe30088bbefd3efe70b62565399a7b9b8) --- sys/fs/nfsclient/nfs_clnode.c | 9 - sys/fs/nfsclient/nfs_clstate.c | 6 -- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clnode.c b/sys/fs/nfsclient/nfs_clnode.c index 43c2286726f7..1c0e855ff5a9 100644 --- a/sys/fs/nfsclient/nfs_clnode.c +++ b/sys/fs/nfsclient/nfs_clnode.c @@ -289,8 +289,10 @@ ncl_reclaim(struct vop_reclaim_args *ap) struct nfsnode *np = VTONFS(vp); struct nfsdmap *dp, *dp2; struct thread *td; + struct mount *mp; td = curthread; + mp = vp->v_mount; /* * If the NLM is running, give it a chance to abort pending @@ -317,7 +319,12 @@ ncl_reclaim(struct vop_reclaim_args *ap) * vfs_hash_remove(), since it cannot be recalled once the * nfs node is no longer available. */ - nfscl_delegreturnvp(vp, td); + MNT_ILOCK(mp); + if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) == 0) { + MNT_IUNLOCK(mp); + nfscl_delegreturnvp(vp, td); + } else + MNT_IUNLOCK(mp); } vfs_hash_remove(vp); diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index bbc1c6ccbc2f..8b5f07b5aa2a 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -3300,10 +3300,12 @@ nfscl_delegreturnvp(vnode_t vp, NFSPROC_T *p) np = VTONFS(vp); cred = newnfs_getcred(); + dp = NULL; NFSLOCKCLSTATE(); clp = VFSTONFS(vp->v_mount)->nm_clp; - dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, - np->n_fhp->nfh_len); + if (clp != NULL) + dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, + np->n_fhp->nfh_len); if (dp != NULL) { nfscl_cleandeleg(dp); nfscl_freedeleg(&clp->nfsc_deleg, dp, false); ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 44d99af3c545 - stable/12 - nfscl: return delegations in the NFS VOP_RECLAIM()
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=44d99af3c545398c5bbc01b20c611fe63ccdad76 commit 44d99af3c545398c5bbc01b20c611fe63ccdad76 Author: Rick Macklem AuthorDate: 2021-04-26 00:57:55 + Commit: Rick Macklem CommitDate: 2021-05-12 02:32:12 + nfscl: return delegations in the NFS VOP_RECLAIM() After a vnode is recycled it can no longer be acquired via vfs_hash_get() and, as such, a delegation for the vnode cannot be recalled. In the unlikely event that a delegation still exists when the vnode is being recycled, return the delegation since it will no longer be recallable. Until you have this patch in your NFSv4 client, you should consider avoiding the use of delegations. (cherry picked from commit aad780464fad1e32c97316515a4044d661413a6b) --- sys/fs/nfs/nfs_var.h | 1 + sys/fs/nfsclient/nfs_clnode.c | 10 - sys/fs/nfsclient/nfs_clstate.c | 49 ++ 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index bee66d15b016..0f656601e531 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -578,6 +578,7 @@ void nfscl_lockinit(struct nfsv4lock *); void nfscl_lockexcl(struct nfsv4lock *, void *); void nfscl_lockunlock(struct nfsv4lock *); void nfscl_lockderef(struct nfsv4lock *); +void nfscl_delegreturnvp(vnode_t, NFSPROC_T *); void nfscl_docb(struct nfsrv_descript *, NFSPROC_T *); void nfscl_releasealllocks(struct nfsclclient *, vnode_t, NFSPROC_T *, void *, int); diff --git a/sys/fs/nfsclient/nfs_clnode.c b/sys/fs/nfsclient/nfs_clnode.c index f41cb8749020..cdebf9c56631 100644 --- a/sys/fs/nfsclient/nfs_clnode.c +++ b/sys/fs/nfsclient/nfs_clnode.c @@ -303,7 +303,7 @@ ncl_reclaim(struct vop_reclaim_args *ap) */ vnode_destroy_vobject(vp); - if (NFS_ISV4(vp) && vp->v_type == VREG) + if (NFS_ISV4(vp) && vp->v_type == VREG) { /* * We can now safely close any remaining NFSv4 Opens for * this file. Most opens will have already been closed by @@ -311,6 +311,14 @@ ncl_reclaim(struct vop_reclaim_args *ap) * called, so we need to do it again here. */ (void) nfsrpc_close(vp, 1, ap->a_td); + /* +* It it unlikely a delegation will still exist, but +* if one does, it must be returned before calling +* vfs_hash_remove(), since it cannot be recalled once the +* nfs node is no longer available. +*/ + nfscl_delegreturnvp(vp, td); + } vfs_hash_remove(vp); diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index 03c046c36ccc..5d2641e1f4b0 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -148,7 +148,8 @@ static int nfscl_trylock(struct nfsmount *, vnode_t , u_int8_t *, struct ucred *, NFSPROC_T *); static int nfsrpc_reopen(struct nfsmount *, u_int8_t *, int, u_int32_t, struct nfsclopen *, struct nfscldeleg **, struct ucred *, NFSPROC_T *); -static void nfscl_freedeleg(struct nfscldeleghead *, struct nfscldeleg *); +static void nfscl_freedeleg(struct nfscldeleghead *, struct nfscldeleg *, +bool); static int nfscl_errmap(struct nfsrv_descript *, u_int32_t); static void nfscl_cleanup_common(struct nfsclclient *, u_int8_t *); static int nfscl_recalldeleg(struct nfsclclient *, struct nfsmount *, @@ -1610,12 +1611,13 @@ nfscl_cleandeleg(struct nfscldeleg *dp) * Free a delegation. */ static void -nfscl_freedeleg(struct nfscldeleghead *hdp, struct nfscldeleg *dp) +nfscl_freedeleg(struct nfscldeleghead *hdp, struct nfscldeleg *dp, bool freeit) { TAILQ_REMOVE(hdp, dp, nfsdl_list); LIST_REMOVE(dp, nfsdl_hash); - free(dp, M_NFSCLDELEG); + if (freeit) + free(dp, M_NFSCLDELEG); nfsstatsv1.cldelegates--; nfscl_delegcnt--; } @@ -1713,7 +1715,7 @@ nfscl_expireclient(struct nfsclclient *clp, struct nfsmount *nmp, printf("nfsv4 expired locks lost\n"); } nfscl_cleandeleg(dp); - nfscl_freedeleg(&clp->nfsc_deleg, dp); + nfscl_freedeleg(&clp->nfsc_deleg, dp, true); dp = ndp; } if (!TAILQ_EMPTY(&clp->nfsc_deleg)) @@ -2230,7 +2232,7 @@ nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p) * away. Ouch!! */ nfscl_cleandeleg(dp); - nfscl_freedeleg(&clp->nfsc_deleg, dp); + nfscl_freedeleg(&clp->nfsc_deleg, dp, true); } else { LIST_INSERT_HEAD(&extra_open, nop, nfso_list);
git: 8686e00fdfac - stable/12 - nfscl: add check for NULL clp and forced dismounts to nfscl_delegreturnvp()
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=8686e00fdfac505cded6d8f4a4bcf8e51fc10349 commit 8686e00fdfac505cded6d8f4a4bcf8e51fc10349 Author: Rick Macklem AuthorDate: 2021-04-28 00:30:16 + Commit: Rick Macklem CommitDate: 2021-05-12 02:38:42 + nfscl: add check for NULL clp and forced dismounts to nfscl_delegreturnvp() Commit aad780464fad added a function called nfscl_delegreturnvp() to return delegations during the NFS VOP_RECLAIM(). The function erroneously assumed that nm_clp would be non-NULL. It will be NULL for NFSV4.0 mounts until a regular file is opened. It will also be NULL during vflush() in nfs_unmount() for a forced dismount. This patch adds a check for clp == NULL to fix this. Also, since it makes no sense to call nfscl_delegreturnvp() during a forced dismount, the patch adds a check for that case and does not do the call during forced dismounts. PR: 255436 (cherry picked from commit f6fec55fe30088bbefd3efe70b62565399a7b9b8) --- sys/fs/nfsclient/nfs_clnode.c | 10 +- sys/fs/nfsclient/nfs_clstate.c | 6 -- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clnode.c b/sys/fs/nfsclient/nfs_clnode.c index cdebf9c56631..278d4f4900fe 100644 --- a/sys/fs/nfsclient/nfs_clnode.c +++ b/sys/fs/nfsclient/nfs_clnode.c @@ -286,6 +286,9 @@ ncl_reclaim(struct vop_reclaim_args *ap) struct vnode *vp = ap->a_vp; struct nfsnode *np = VTONFS(vp); struct nfsdmap *dp, *dp2; + struct mount *mp; + + mp = vp->v_mount; /* * If the NLM is running, give it a chance to abort pending @@ -317,7 +320,12 @@ ncl_reclaim(struct vop_reclaim_args *ap) * vfs_hash_remove(), since it cannot be recalled once the * nfs node is no longer available. */ - nfscl_delegreturnvp(vp, td); + MNT_ILOCK(mp); + if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) == 0) { + MNT_IUNLOCK(mp); + nfscl_delegreturnvp(vp, td); + } else + MNT_IUNLOCK(mp); } vfs_hash_remove(vp); diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index 5d2641e1f4b0..e705af31185b 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -3267,10 +3267,12 @@ nfscl_delegreturnvp(vnode_t vp, NFSPROC_T *p) np = VTONFS(vp); cred = newnfs_getcred(); + dp = NULL; NFSLOCKCLSTATE(); clp = VFSTONFS(vp->v_mount)->nm_clp; - dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, - np->n_fhp->nfh_len); + if (clp != NULL) + dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, + np->n_fhp->nfh_len); if (dp != NULL) { nfscl_cleandeleg(dp); nfscl_freedeleg(&clp->nfsc_deleg, dp, false); ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 83e7630f3246 - stable/12 - nfscl: Fix mis-merge in cherry-pick commit 44d99af3c545
The branch stable/12 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=83e7630f324649ed95a07d0be440553e672ba725 commit 83e7630f324649ed95a07d0be440553e672ba725 Author: Rick Macklem AuthorDate: 2021-05-12 02:46:46 + Commit: Rick Macklem CommitDate: 2021-05-12 02:46:46 + nfscl: Fix mis-merge in cherry-pick commit 44d99af3c545 This is a direct commit. --- sys/fs/nfsclient/nfs_clnode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/nfsclient/nfs_clnode.c b/sys/fs/nfsclient/nfs_clnode.c index 278d4f4900fe..096770e5da59 100644 --- a/sys/fs/nfsclient/nfs_clnode.c +++ b/sys/fs/nfsclient/nfs_clnode.c @@ -323,7 +323,7 @@ ncl_reclaim(struct vop_reclaim_args *ap) MNT_ILOCK(mp); if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) == 0) { MNT_IUNLOCK(mp); - nfscl_delegreturnvp(vp, td); + nfscl_delegreturnvp(vp, ap->a_td); } else MNT_IUNLOCK(mp); } ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"
git: 46269d66ed02 - main - NFSv4 server: Re-establish the delegation recall timeout
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=46269d66ed02598c86756d81a7d7b27ec0f0c5cd commit 46269d66ed02598c86756d81a7d7b27ec0f0c5cd Author: Rick Macklem AuthorDate: 2021-05-16 23:40:01 + Commit: Rick Macklem CommitDate: 2021-05-16 23:40:01 + NFSv4 server: Re-establish the delegation recall timeout Commit 7a606f280a3e allowed the server to do retries of CB_RECALL callbacks every couple of seconds. This was needed to allow the Linux client to re-establish the back channel. However this patch broke the delegation timeout check, such that it would just keep retrying CB_RECALLS. If the client has crashed or been network patitioned from the server, this continues until the client TCP reconnects to the server and re-establishes the back channel. This patch modifies the code such that it still times out the delegation recall after some minutes, so that the server will allow the conflicting client request once the delegation times out. This patch only affects the NFSv4 server when delegations are enabled and a NFSv4 client that holds a delegation has crashed or been network partitioned from the server for at least several minutes when a delegation needs to be recalled. MFC after: 2 weeks --- sys/fs/nfsserver/nfs_nfsdstate.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index 3aebddad0962..c16d5b8afdc8 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -5292,8 +5292,9 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p, * - check to see if the delegation has expired * - if so, get the v4root lock and then expire it */ - if ((stp->ls_flags & NFSLCK_DELEGRECALL) == 0 || stp->ls_lastrecall < - time_uptime) { + if ((stp->ls_flags & NFSLCK_DELEGRECALL) == 0 || (stp->ls_lastrecall < + NFSD_MONOSEC && clp->lc_expiry >= NFSD_MONOSEC && + stp->ls_delegtime >= NFSD_MONOSEC)) { /* * - do a recall callback, since not yet done * For now, never allow truncate to be set. To use ___ dev-commits-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"