changeset 4173:dd63c52d1998

6532645 implement ZCP sendfile for 64-bit apps
author pr14459
date Fri, 04 May 2007 15:54:05 -0700
parents a08c5d71a686
children e72663e55221
files usr/src/uts/common/fs/sockfs/socksyscalls.c usr/src/uts/common/syscall/sendfile.c usr/src/uts/intel/ia32/ml/modstubs.s usr/src/uts/sparc/ml/modstubs.s
diffstat 4 files changed, 55 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/fs/sockfs/socksyscalls.c	Fri May 04 14:25:21 2007 -0700
+++ b/usr/src/uts/common/fs/sockfs/socksyscalls.c	Fri May 04 15:54:05 2007 -0700
@@ -45,6 +45,7 @@
 #include <sys/stream.h>
 #include <sys/strsubr.h>
 #include <sys/strsun.h>
+#include <sys/sunddi.h>
 #include <sys/esunddi.h>
 #include <sys/flock.h>
 #include <sys/modctl.h>
@@ -2486,7 +2487,7 @@
 	vp = fp->f_vnode;
 	stp = vp->v_stream;
 	if (stp->sd_qn_maxpsz == INFPSZ)
-		maxpsz = MAXOFF32_T;
+		maxpsz = maxphys;
 	else
 		maxpsz = roundup(stp->sd_qn_maxpsz, MAXBSIZE);
 	/*
@@ -2496,7 +2497,7 @@
 	 */
 	if (sfv_len >= MAXBSIZE && (sfv_len >= (va_size >> 1) ||
 	    (sfv->sfv_flag & SFV_NOWAIT) || sfv_len >= 0x1000000) &&
-	    !vn_has_flocks(fvp)) {
+	    !vn_has_flocks(fvp) && !(fvp->v_flag & VNOMAP)) {
 		if ((stp->sd_copyflag & (STZCVMSAFE|STZCVMUNSAFE)) == 0) {
 			int on = 1;
 
--- a/usr/src/uts/common/syscall/sendfile.c	Fri May 04 14:25:21 2007 -0700
+++ b/usr/src/uts/common/syscall/sendfile.c	Fri May 04 15:54:05 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -46,6 +46,7 @@
 #include <sys/termios.h>
 #include <sys/stream.h>
 #include <sys/strsubr.h>
+#include <sys/sunddi.h>
 #include <sys/esunddi.h>
 #include <sys/flock.h>
 #include <sys/modctl.h>
@@ -74,6 +75,11 @@
 		ssize32_t *);
 extern int nl7c_sendfilev(struct sonode *, u_offset_t *, struct sendfilevec *,
 		int, ssize_t *);
+extern int snf_segmap(file_t *, vnode_t *, u_offset_t, u_offset_t, uint_t,
+		ssize_t *, boolean_t);
+
+#define	readflg	(V_WRITELOCK_FALSE)
+#define	rwflag	(V_WRITELOCK_TRUE)
 
 /*
  * kstrwritemp() has very similar semantics as that of strwrite().
@@ -260,7 +266,6 @@
 		} else {
 			file_t	*ffp;
 			vnode_t	*readvp;
-			int	readflg = 0;
 			size_t	size;
 			caddr_t	ptr;
 
@@ -408,7 +413,6 @@
 sendvec64(file_t *fp, const struct ksendfilevec64 *vec, int sfvcnt,
 	size32_t *xferred, int fildes)
 {
-	int			rwflag;
 	u_offset_t		fileoff;
 	int			copy_cnt;
 	const struct ksendfilevec64 *copy_vec;
@@ -416,15 +420,12 @@
 	struct vnode *vp;
 	int error;
 	ssize32_t count = 0;
-	int osfvcnt;
 
-	rwflag = 1;
 	vp = fp->f_vnode;
 	(void) VOP_RWLOCK(vp, rwflag, NULL);
 
 	copy_vec = vec;
 	fileoff = fp->f_offset;
-	osfvcnt = sfvcnt;
 
 	do {
 		copy_cnt = MIN(sfvcnt, SEND_MAX_CHUNK);
@@ -435,11 +436,10 @@
 		}
 
 		/*
-		 * Optimize the single regular file over
+		 * Optimize the regular file over
 		 * the socket case.
 		 */
-		if (vp->v_type == VSOCK && osfvcnt == 1 &&
-		    sfv->sfv_fd != SFV_FD_SELF) {
+		if (vp->v_type == VSOCK && sfv->sfv_fd != SFV_FD_SELF) {
 			file_t *rfp;
 			vnode_t *rvp;
 
@@ -455,7 +455,11 @@
 			rvp = rfp->f_vnode;
 			if (rvp->v_type == VREG) {
 				error = sosendfile64(fp, rfp, sfv, &count);
-				break;
+				if (error)
+					break;
+				copy_vec++;
+				sfvcnt--;
+				continue;
 			}
 			releasef(sfv->sfv_fd);
 		}
@@ -607,7 +611,6 @@
 		} else {
 			file_t	*ffp;
 			vnode_t	*readvp;
-			int	readflg = 0;
 
 			if ((ffp = getf(sfv->sfv_fd)) == NULL) {
 				freemsg(head);
@@ -897,9 +900,9 @@
 				}
 			}
 		} else {
+			int segmapit;
 			file_t	*ffp;
 			vnode_t	*readvp;
-			int	readflg = 0;
 			size_t	size;
 			caddr_t	ptr;
 
@@ -950,6 +953,7 @@
 			size = sfv_len < size ? sfv_len : size;
 
 			if (vp->v_type != VSOCK) {
+				segmapit = 0;
 				buf = kmem_alloc(size, KM_NOSLEEP);
 				if (buf == NULL) {
 					VOP_RWUNLOCK(readvp, readflg, NULL);
@@ -964,6 +968,40 @@
 				 */
 				if (so->so_kssl_ctx != NULL)
 					size = MIN(size, maxblk);
+
+				if (vn_has_flocks(readvp) ||
+				    readvp->v_flag & VNOMAP ||
+				    stp->sd_copyflag & STZCVMUNSAFE) {
+					segmapit = 0;
+				} else if (stp->sd_copyflag & STZCVMSAFE) {
+					segmapit = 1;
+				} else {
+					int on = 1;
+					if (SOP_SETSOCKOPT(VTOSO(vp),
+					    SOL_SOCKET, SO_SND_COPYAVOID,
+					    &on, sizeof (on)) == 0)
+					segmapit = 1;
+				}
+			}
+
+			if (segmapit) {
+				boolean_t nowait;
+				uint_t maxpsz;
+
+				nowait = (sfv->sfv_flag & SFV_NOWAIT) != 0;
+				maxpsz = stp->sd_qn_maxpsz;
+				if (maxpsz == INFPSZ)
+					maxpsz = maxphys;
+				maxpsz = roundup(maxpsz, MAXBSIZE);
+				error = snf_segmap(fp, readvp, sfv_off,
+					    (u_offset_t)sfv_len, maxpsz,
+					    (ssize_t *)&cnt, nowait);
+				releasef(sfv->sfv_fd);
+				*count += cnt;
+				if (error)
+					return (error);
+				sfv++;
+				continue;
 			}
 
 			while (sfv_len > 0) {
--- a/usr/src/uts/intel/ia32/ml/modstubs.s	Fri May 04 14:25:21 2007 -0700
+++ b/usr/src/uts/intel/ia32/ml/modstubs.s	Fri May 04 15:54:05 2007 -0700
@@ -493,6 +493,7 @@
 	NO_UNLOAD_STUB(sockfs, sock_getmsg,  	nomod_zero);
 	NO_UNLOAD_STUB(sockfs, sock_putmsg,  	nomod_zero);
 	NO_UNLOAD_STUB(sockfs, sosendfile64,  	nomod_zero);
+	NO_UNLOAD_STUB(sockfs, snf_segmap,  	nomod_einval);
 	NO_UNLOAD_STUB(sockfs, sock_getfasync,  nomod_zero);
 	NO_UNLOAD_STUB(sockfs, nl7c_sendfilev,  nomod_zero);
 	NO_UNLOAD_STUB(sockfs, sostream_direct,	nomod_zero);
--- a/usr/src/uts/sparc/ml/modstubs.s	Fri May 04 14:25:21 2007 -0700
+++ b/usr/src/uts/sparc/ml/modstubs.s	Fri May 04 15:54:05 2007 -0700
@@ -381,6 +381,7 @@
 	NO_UNLOAD_STUB(sockfs, sock_getmsg,  	nomod_zero);
 	NO_UNLOAD_STUB(sockfs, sock_putmsg,  	nomod_zero);
 	NO_UNLOAD_STUB(sockfs, sosendfile64,  	nomod_zero);
+	NO_UNLOAD_STUB(sockfs, snf_segmap,  	nomod_einval);
 	NO_UNLOAD_STUB(sockfs, sock_getfasync,  nomod_zero);
 	NO_UNLOAD_STUB(sockfs, nl7c_sendfilev,  nomod_zero);
 	NO_UNLOAD_STUB(sockfs, sostream_direct,	nomod_zero);