Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Aug 2019 01:40:39 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r351525 - projects/nfsv42/sys/fs/nfsclient
Message-ID:  <201908270140.x7R1edvC010782@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Tue Aug 27 01:40:38 2019
New Revision: 351525
URL: https://svnweb.freebsd.org/changeset/base/351525

Log:
  Add support for _PC_MIN_HOLE_SIZE to the NFSv4.2 client.
  
  Unfortunately there is no NFSv4.2 attribute for this, so all I could come
  up with was to try Seek to see if it supported and, if it is, return
  mnt_stat.f_iosize as a "best guess".
  At least this allows applications to use hole size non-zero to indicate
  support for holes.

Modified:
  projects/nfsv42/sys/fs/nfsclient/nfs_clvnops.c
  projects/nfsv42/sys/fs/nfsclient/nfsmount.h

Modified: projects/nfsv42/sys/fs/nfsclient/nfs_clvnops.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsclient/nfs_clvnops.c	Tue Aug 27 01:16:02 2019	(r351524)
+++ projects/nfsv42/sys/fs/nfsclient/nfs_clvnops.c	Tue Aug 27 01:40:38 2019	(r351525)
@@ -3754,7 +3754,10 @@ nfs_pathconf(struct vop_pathconf_args *ap)
 	struct nfsv3_pathconf pc;
 	struct nfsvattr nfsva;
 	struct vnode *vp = ap->a_vp;
+	struct nfsmount *nmp;
 	struct thread *td = curthread;
+	off_t off;
+	bool eof;
 	int attrflag, error;
 
 	if ((NFS_ISV34(vp) && (ap->a_name == _PC_LINK_MAX ||
@@ -3852,6 +3855,40 @@ nfs_pathconf(struct vop_pathconf_args *ap)
 		break;
 	case _PC_SYMLINK_MAX:
 		*ap->a_retval = NFS_MAXPATHLEN;
+		break;
+	case _PC_MIN_HOLE_SIZE:
+		/* Only some NFSv4.2 servers support Seek for Holes. */
+		*ap->a_retval = 0;
+		nmp = VFSTONFS(vp->v_mount);
+		if (NFS_ISV4(vp) && nmp->nm_minorvers == NFSV42_MINORVERSION) {
+			/*
+			 * NFSv4.2 doesn't have an attribute for hole size,
+			 * so all we can do is see if the Seek operation is
+			 * supported and then use f_iosize as a "best guess".
+			 */
+			mtx_lock(&nmp->nm_mtx);
+			if ((nmp->nm_privflag & NFSMNTP_SEEKTESTED) == 0) {
+				mtx_unlock(&nmp->nm_mtx);
+				off = 0;
+				attrflag = 0;
+				error = nfsrpc_seek(vp, &off, &eof,
+				    NFSV4CONTENT_HOLE, td->td_ucred, &nfsva,
+				    &attrflag);
+				if (attrflag != 0)
+					nfscl_loadattrcache(&vp, &nfsva,
+					    NULL, NULL, 0, 1);
+				mtx_lock(&nmp->nm_mtx);
+				if (error == NFSERR_NOTSUPP)
+					nmp->nm_privflag |= NFSMNTP_SEEKTESTED;
+				else
+					nmp->nm_privflag |= NFSMNTP_SEEKTESTED |
+					    NFSMNTP_SEEK;
+				error = 0;
+			}
+			if ((nmp->nm_privflag & NFSMNTP_SEEK) != 0)
+				*ap->a_retval = vp->v_mount->mnt_stat.f_iosize;
+			mtx_unlock(&nmp->nm_mtx);
+		}
 		break;
 
 	default:

Modified: projects/nfsv42/sys/fs/nfsclient/nfsmount.h
==============================================================================
--- projects/nfsv42/sys/fs/nfsclient/nfsmount.h	Tue Aug 27 01:16:02 2019	(r351524)
+++ projects/nfsv42/sys/fs/nfsclient/nfsmount.h	Tue Aug 27 01:40:38 2019	(r351525)
@@ -108,6 +108,8 @@ struct	nfsmount {
 #define	NFSMNTP_IOADVISETHRUMDS	0x00000004
 #define	NFSMNTP_NOCOPY		0x00000008
 #define	NFSMNTP_NOCONSECUTIVE	0x00000010
+#define	NFSMNTP_SEEK		0x00000020
+#define	NFSMNTP_SEEKTESTED	0x00000040
 
 #define	NFSMNT_DIRPATH(m)	(&((m)->nm_name[(m)->nm_krbnamelen + 1]))
 #define	NFSMNT_SRVKRBNAME(m)						\



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