Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Nov 2018 00:42:34 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r340357 - projects/nfsv42/sys/fs/nfsclient
Message-ID:  <201811120042.wAC0gY0B037632@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Mon Nov 12 00:42:34 2018
New Revision: 340357
URL: https://svnweb.freebsd.org/changeset/base/340357

Log:
  Add support for the NFSv4.2 IOAdvise RPC to sys/fs/nfsclient.

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

Modified: projects/nfsv42/sys/fs/nfsclient/nfs_clrpcops.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsclient/nfs_clrpcops.c	Mon Nov 12 00:23:58 2018	(r340356)
+++ projects/nfsv42/sys/fs/nfsclient/nfs_clrpcops.c	Mon Nov 12 00:42:34 2018	(r340357)
@@ -110,6 +110,9 @@ struct nfsclwritedsdorpc {
 	struct nfsclds		*dsp;
 	uint64_t		off;
 	int			len;
+#ifdef notyet
+	int			advise;
+#endif
 	struct nfsfh		*fhp;
 	struct mbuf		*m;
 	int			vers;
@@ -172,12 +175,19 @@ static int nfsio_commitds(vnode_t, uint64_t, int, stru
     NFSPROC_T *);
 static int nfsrpc_commitds(vnode_t, uint64_t, int, struct nfsclds *,
     struct nfsfh *, int, int, struct ucred *, NFSPROC_T *);
+#ifdef notyet
+static int nfsio_adviseds(vnode_t, uint64_t, int, int, struct nfsclds *,
+    struct nfsfh *, int, int, struct nfsclwritedsdorpc *, struct ucred *,
+    NFSPROC_T *);
+static int nfsrpc_adviseds(vnode_t, uint64_t, int, int, struct nfsclds *,
+    struct nfsfh *, int, int, struct ucred *, NFSPROC_T *);
+#endif
 static void nfsrv_setuplayoutget(struct nfsrv_descript *, int, uint64_t,
     uint64_t, uint64_t, nfsv4stateid_t *, int, int, int);
 static int nfsrv_parseug(struct nfsrv_descript *, int, uid_t *, gid_t *,
     NFSPROC_T *);
-static int nfsrv_parselayoutget(struct nfsrv_descript *, nfsv4stateid_t *,
-    int *, struct nfsclflayouthead *);
+static int nfsrv_parselayoutget(struct nfsmount *, struct nfsrv_descript *,
+    nfsv4stateid_t *, int *, struct nfsclflayouthead *);
 static int nfsrpc_getopenlayout(struct nfsmount *, vnode_t, u_int8_t *,
     int, uint8_t *, int, uint32_t, struct nfsclopen *, uint8_t *, int,
     struct nfscldeleg **, struct ucred *, NFSPROC_T *);
@@ -4922,7 +4932,8 @@ nfsrpc_layoutget(struct nfsmount *nmp, uint8_t *fhp, i
 	if (error != 0)
 		return (error);
 	if (nd->nd_repstat == 0)
-		error = nfsrv_parselayoutget(nd, stateidp, retonclosep, flhp);
+		error = nfsrv_parselayoutget(nmp, nd, stateidp, retonclosep,
+		    flhp);
 	if (error == 0 && nd->nd_repstat != 0)
 		error = nd->nd_repstat;
 	mbuf_freem(nd->nd_mrep);
@@ -6682,6 +6693,147 @@ nfsio_commitds(vnode_t vp, uint64_t offset, int cnt, s
 }
 
 /*
+ * NFS Advise rpc
+ */
+APPLESTATIC int
+nfsrpc_advise(vnode_t vp, off_t offset, uint64_t cnt, int advise,
+    struct ucred *cred, NFSPROC_T *p)
+{
+	u_int32_t *tl;
+	struct nfsrv_descript nfsd, *nd = &nfsd;
+	nfsattrbit_t hints;
+	int error;
+	
+	NFSZERO_ATTRBIT(&hints);
+	if (advise == POSIX_FADV_WILLNEED)
+		NFSSETBIT_ATTRBIT(&hints, NFSV4IOHINT_WILLNEED);
+	else if (advise == POSIX_FADV_DONTNEED)
+		NFSSETBIT_ATTRBIT(&hints, NFSV4IOHINT_DONTNEED);
+	else
+		return (0);
+	NFSCL_REQSTART(nd, NFSPROC_IOADVISE, vp);
+	nfsm_stateidtom(nd, NULL, NFSSTATEID_PUTALLZERO);
+	NFSM_BUILD(tl, uint32_t *, 2 * NFSX_HYPER);
+	txdr_hyper(offset, tl);
+	tl += 2;
+	txdr_hyper(cnt, tl);
+	nfsrv_putattrbit(nd, &hints);
+	error = nfscl_request(nd, vp, p, cred, NULL);
+	if (error != 0)
+		return (error);
+	if (nd->nd_repstat != 0)
+		error = nd->nd_repstat;
+	mbuf_freem(nd->nd_mrep);
+	return (error);
+}
+
+#ifdef notyet
+/*
+ * NFS advise rpc to a NFSv4.2 DS.
+ */
+static int
+nfsrpc_adviseds(vnode_t vp, uint64_t offset, int cnt, int advise,
+    struct nfsclds *dsp, struct nfsfh *fhp, int vers, int minorvers,
+    struct ucred *cred, NFSPROC_T *p)
+{
+	uint32_t *tl;
+	struct nfsrv_descript nfsd, *nd = &nfsd;
+	struct nfsmount *nmp = VFSTONFS(vnode_mount(vp));
+	struct nfssockreq *nrp;
+	nfsattrbit_t hints;
+	int error;
+	
+	/* For NFS DSs prior to NFSv4.2, just return OK. */
+	if (vers == NFS_VER3 || minorversion < NFSV42_MINORVERSION)
+		return (0);
+	NFSZERO_ATTRBIT(&hints);
+	if (advise == POSIX_FADV_WILLNEED)
+		NFSSETBIT_ATTRBIT(&hints, NFSV4IOHINT_WILLNEED);
+	else if (advise == POSIX_FADV_DONTNEED)
+		NFSSETBIT_ATTRBIT(&hints, NFSV4IOHINT_DONTNEED);
+	else
+		return (0);
+	nd->nd_mrep = NULL;
+	nfscl_reqstart(nd, NFSPROC_IOADVISEDS, nmp, fhp->nfh_fh,
+	    fhp->nfh_len, NULL, &dsp->nfsclds_sess, vers, minorvers);
+	vers = NFS_VER4;
+	NFSCL_DEBUG(4, "nfsrpc_adviseds: vers=%d minvers=%d\n", vers,
+	    minorvers);
+	nfsm_stateidtom(nd, NULL, NFSSTATEID_PUTALLZERO);
+	NFSM_BUILD(tl, uint32_t *, NFSX_HYPER + NFSX_UNSIGNED);
+	txdr_hyper(offset, tl);
+	tl += 2;
+	*tl = txdr_unsigned(cnt);
+	nfsrv_putattrbit(nd, &hints);
+	nrp = dsp->nfsclds_sockp;
+	if (nrp == NULL)
+		/* If NULL, use the MDS socket. */
+		nrp = &nmp->nm_sockreq;
+	error = newnfs_request(nd, nmp, NULL, nrp, vp, p, cred,
+	    NFS_PROG, vers, NULL, 1, NULL, &dsp->nfsclds_sess);
+	NFSCL_DEBUG(4, "nfsrpc_adviseds: err=%d stat=%d\n", error,
+	    nd->nd_repstat);
+	if (error != 0)
+		return (error);
+	if (nd->nd_repstat != 0)
+		error = nd->nd_repstat;
+	mbuf_freem(nd->nd_mrep);
+	return (error);
+}
+
+/*
+ * Start up the thread that will execute nfsrpc_commitds().
+ */
+static void
+start_adviseds(void *arg, int pending)
+{
+	struct nfsclwritedsdorpc *drpc;
+
+	drpc = (struct nfsclwritedsdorpc *)arg;
+	drpc->err = nfsrpc_adviseds(drpc->vp, drpc->off, drpc->len,
+	    drpc->advise, drpc->dsp, drpc->fhp, drpc->vers, drpc->minorvers,
+	    drpc->cred, drpc->p);
+	drpc->done = 1;
+	NFSCL_DEBUG(4, "start_adviseds: err=%d\n", drpc->err);
+}
+
+/*
+ * Set up the commit DS mirror call for the pNFS I/O thread.
+ */
+static int
+nfsio_adviseds(vnode_t vp, uint64_t offset, int cnt, int advise,
+    struct nfsclds *dsp, struct nfsfh *fhp, int vers, int minorvers,
+    struct nfsclwritedsdorpc *drpc, struct ucred *cred, NFSPROC_T *p)
+{
+	int error, ret;
+
+	error = 0;
+	drpc->done = 0;
+	drpc->vp = vp;
+	drpc->off = offset;
+	drpc->len = cnt;
+	drpc->advise = advise;
+	drpc->dsp = dsp;
+	drpc->fhp = fhp;
+	drpc->vers = vers;
+	drpc->minorvers = minorvers;
+	drpc->cred = cred;
+	drpc->p = p;
+	drpc->inprog = 0;
+	ret = EIO;
+	if (nfs_pnfsiothreads != 0) {
+		ret = nfs_pnfsio(start_adviseds, drpc);
+		NFSCL_DEBUG(4, "nfsio_adviseds: nfs_pnfsio=%d\n", ret);
+	}
+	if (ret != 0)
+		error = nfsrpc_adviseds(vp, offset, cnt, advise, dsp, fhp, vers,
+		    minorvers, cred, p);
+	NFSCL_DEBUG(4, "nfsio_adviseds: error=%d\n", error);
+	return (error);
+}
+#endif	/* notyet */
+
+/*
  * Set up the XDR arguments for the LayoutGet operation.
  */
 static void
@@ -6722,8 +6874,8 @@ nfsrv_setuplayoutget(struct nfsrv_descript *nd, int io
  * Parse the reply for a successful LayoutGet operation.
  */
 static int
-nfsrv_parselayoutget(struct nfsrv_descript *nd, nfsv4stateid_t *stateidp,
-    int *retonclosep, struct nfsclflayouthead *flhp)
+nfsrv_parselayoutget(struct nfsmount *nmp, struct nfsrv_descript *nd,
+    nfsv4stateid_t *stateidp, int *retonclosep, struct nfsclflayouthead *flhp)
 {
 	uint32_t *tl;
 	struct nfsclflayout *flp, *prevflp, *tflp;
@@ -6803,6 +6955,11 @@ nfsrv_parselayoutget(struct nfsrv_descript *nd, nfsv4s
 			tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED);
 			flp->nfsfl_util = fxdr_unsigned(uint32_t, *tl++);
 			NFSCL_DEBUG(4, "flutil=0x%x\n", flp->nfsfl_util);
+			mtx_lock(&nmp->nm_mtx);
+			if (nmp->nm_minorvers > 1 && (flp->nfsfl_util &
+			    NFSFLAYUTIL_IOADVISE_THRU_MDS) != 0)
+				nmp->nm_privflag |= NFSMNTP_IOADVISETHRUMDS;
+			mtx_unlock(&nmp->nm_mtx);
 			flp->nfsfl_stripe1 = fxdr_unsigned(uint32_t, *tl++);
 			flp->nfsfl_patoff = fxdr_hyper(tl); tl += 2;
 			NFSCL_DEBUG(4, "stripe1=%u poff=%ju\n",
@@ -6951,6 +7108,18 @@ nfsrv_parselayoutget(struct nfsrv_descript *nd, nfsv4s
 			}
 			NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
 			flp->nfsfl_fflags = fxdr_unsigned(uint32_t, *tl++);
+#ifdef notnow
+			/*
+			 * At this time, there is no flag.
+			 * NFSFLEXFLAG_IOADVISE_THRU_MDS might need to be
+			 * added, or it may never exist?
+			 */
+			mtx_lock(&nmp->nm_mtx);
+			if (nmp->nm_minorvers > 1 && (flp->nfsfl_fflags &
+			    NFSFLEXFLAG_IOADVISE_THRU_MDS) != 0)
+				nmp->nm_privflag |= NFSMNTP_IOADVISETHRUMDS;
+			mtx_unlock(&nmp->nm_mtx);
+#endif
 			flp->nfsfl_statshint = fxdr_unsigned(uint32_t, *tl);
 			NFSCL_DEBUG(4, "fflags=0x%x statshint=%d\n",
 			    flp->nfsfl_fflags, flp->nfsfl_statshint);
@@ -7262,7 +7431,7 @@ nfsrpc_openlayoutrpc(struct nfsmount *nmp, vnode_t vp,
 				NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
 				*laystatp = fxdr_unsigned(int, *++tl);
 				if (*laystatp == 0) {
-					error = nfsrv_parselayoutget(nd,
+					error = nfsrv_parselayoutget(nmp, nd,
 					    stateidp, retonclosep, flhp);
 					if (error != 0)
 						*laystatp = error;
@@ -7511,7 +7680,7 @@ nfsrpc_createlayout(vnode_t dvp, char *name, int namel
 				NFSM_DISSECT(tl, uint32_t *, 4 * NFSX_UNSIGNED);
 				*laystatp = fxdr_unsigned(int, *(tl + 3));
 				if (*laystatp == 0) {
-					error = nfsrv_parselayoutget(nd,
+					error = nfsrv_parselayoutget(nmp, nd,
 					    stateidp, retonclosep, flhp);
 					if (error != 0)
 						*laystatp = error;

Modified: projects/nfsv42/sys/fs/nfsclient/nfs_clvnops.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsclient/nfs_clvnops.c	Mon Nov 12 00:23:58 2018	(r340356)
+++ projects/nfsv42/sys/fs/nfsclient/nfs_clvnops.c	Mon Nov 12 00:42:34 2018	(r340357)
@@ -143,6 +143,7 @@ static vop_advlockasync_t nfs_advlockasync;
 static vop_getacl_t nfs_getacl;
 static vop_setacl_t nfs_setacl;
 static vop_set_text_t nfs_set_text;
+static vop_advise_t nfs_advise;
 
 /*
  * Global vfs data structures for nfs
@@ -181,6 +182,7 @@ static struct vop_vector newnfs_vnodeops_nosig = {
 	.vop_getacl =		nfs_getacl,
 	.vop_setacl =		nfs_setacl,
 	.vop_set_text =		nfs_set_text,
+	.vop_advise =		nfs_advise,
 };
 
 static int
@@ -3443,6 +3445,34 @@ nfs_set_text(struct vop_set_text_args *ap)
 	mtx_unlock(&np->n_mtx);
 
 	vp->v_vflag |= VV_TEXT;
+	return (0);
+}
+
+/*
+ * VOP_ADVISE for NFS.
+ * Just return 0 for any errors, since it is just a hint.
+ */
+static int
+nfs_advise(struct vop_advise_args *ap)
+{
+	struct thread *td = curthread;
+	struct nfsmount *nmp;
+	uint64_t len;
+
+	if (ap->a_start < 0 || ap->a_end < 0)
+		return (0);
+	if (ap->a_end == OFF_MAX)
+		len = 0;
+	else if (ap->a_end < ap->a_start)
+		return (0);
+	else
+		len = ap->a_end - ap->a_start + 1;
+	nmp = VFSTONFS(ap->a_vp->v_mount);
+	if (NFSHASPNFS(nmp) && (nmp->nm_privflag & NFSMNTP_IOADVISETHRUMDS) ==
+	    0)
+		return (0);
+	nfsrpc_advise(ap->a_vp, ap->a_start, len, ap->a_advice,
+	    td->td_ucred, td);
 	return (0);
 }
 

Modified: projects/nfsv42/sys/fs/nfsclient/nfsmount.h
==============================================================================
--- projects/nfsv42/sys/fs/nfsclient/nfsmount.h	Mon Nov 12 00:23:58 2018	(r340356)
+++ projects/nfsv42/sys/fs/nfsclient/nfsmount.h	Mon Nov 12 00:42:34 2018	(r340357)
@@ -105,6 +105,7 @@ struct	nfsmount {
 /* Private flags. */
 #define	NFSMNTP_FORCEDISM	0x00000001
 #define	NFSMNTP_CANCELRPCS	0x00000002
+#define	NFSMNTP_IOADVISETHRUMDS	0x00000004
 
 #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?201811120042.wAC0gY0B037632>