diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/fs/sockfs/socksyscalls.c | 53 | ||||
-rw-r--r-- | usr/src/uts/common/syscall/sendfile.c | 16 |
2 files changed, 36 insertions, 33 deletions
diff --git a/usr/src/uts/common/fs/sockfs/socksyscalls.c b/usr/src/uts/common/fs/sockfs/socksyscalls.c index 21f3744895..4cbd079539 100644 --- a/usr/src/uts/common/fs/sockfs/socksyscalls.c +++ b/usr/src/uts/common/fs/sockfs/socksyscalls.c @@ -80,7 +80,7 @@ int do_useracc = 1; /* Controlled by setting SO_DEBUG to 4 */ #define do_useracc 1 #endif /* SOCK_TEST */ -extern int xnet_truncate_print; +extern int xnet_truncate_print; extern void nl7c_init(void); extern int sockfs_defer_nl7c_init; @@ -221,7 +221,7 @@ getsonode(int sock, int *errorp, file_t **fpp) */ static struct sockaddr * copyin_name(struct sonode *so, struct sockaddr *name, socklen_t *namelenp, - int *errorp) + int *errorp) { char *faddr; size_t namelen = (size_t)*namelenp; @@ -279,8 +279,8 @@ copyin_name(struct sonode *so, struct sockaddr *name, socklen_t *namelenp, * Copy from kaddr/klen to uaddr/ulen. Updates ulenp if non-NULL. */ static int -copyout_arg(void *uaddr, socklen_t ulen, void *ulenp, - void *kaddr, socklen_t klen) +copyout_arg(void *uaddr, socklen_t ulen, void *ulenp, void *kaddr, + socklen_t klen) { if (uaddr != NULL) { if (ulen > klen) @@ -306,8 +306,8 @@ copyout_arg(void *uaddr, socklen_t ulen, void *ulenp, * klen to update ulenp. */ static int -copyout_name(void *uaddr, socklen_t ulen, void *ulenp, - void *kaddr, socklen_t klen) +copyout_name(void *uaddr, socklen_t ulen, void *ulenp, void *kaddr, + socklen_t klen) { if (uaddr != NULL) { if (ulen >= klen) @@ -830,13 +830,8 @@ shutdown(int sock, int how, int version) * Common receive routine. */ static ssize_t -recvit(int sock, - struct nmsghdr *msg, - struct uio *uiop, - int flags, - socklen_t *namelenp, - socklen_t *controllenp, - int *flagsp) +recvit(int sock, struct nmsghdr *msg, struct uio *uiop, int flags, + socklen_t *namelenp, socklen_t *controllenp, int *flagsp) { struct sonode *so; file_t *fp; @@ -978,8 +973,8 @@ recv(int sock, void *buffer, size_t len, int flags) } ssize_t -recvfrom(int sock, void *buffer, size_t len, int flags, - struct sockaddr *name, socklen_t *namelenp) +recvfrom(int sock, void *buffer, size_t len, int flags, struct sockaddr *name, + socklen_t *namelenp) { struct nmsghdr lmsg; struct uio auio; @@ -1448,8 +1443,7 @@ bad: return (error != 0 ? set_errno(error) : 0); /*ARGSUSED3*/ int -getsockname(int sock, struct sockaddr *name, - socklen_t *namelenp, int version) +getsockname(int sock, struct sockaddr *name, socklen_t *namelenp, int version) { struct sonode *so; int error; @@ -1486,12 +1480,8 @@ bad: return (error != 0 ? set_errno(error) : 0); /*ARGSUSED5*/ int -getsockopt(int sock, - int level, - int option_name, - void *option_value, - socklen_t *option_lenp, - int version) +getsockopt(int sock, int level, int option_name, void *option_value, + socklen_t *option_lenp, int version) { struct sonode *so; socklen_t optlen, optlen_res; @@ -1538,12 +1528,8 @@ getsockopt(int sock, /*ARGSUSED5*/ int -setsockopt(int sock, - int level, - int option_name, - void *option_value, - socklen_t option_len, - int version) +setsockopt(int sock, int level, int option_name, void *option_value, + socklen_t option_len, int version) { struct sonode *so; intptr_t buffer[2]; @@ -1943,7 +1929,7 @@ sockconfig(int cmd, void *arg1, void *arg2, void *arg3, void *arg4) * the application as that's what would have happened if the operations * were done sequentially. With this in mind, following should work : * - * - Check for errors before read or write. + * - Check for errors before read or write. * - If the reader encounters error, set the error in sr_read_error. * Check sr_write_error, if it is set, send cv_signal as it is * waiting for reader to complete. If it is not set, the writer @@ -2457,6 +2443,9 @@ snf_smap_desbfree(snf_smap_desbinfo *snfi) * At the end of the whole sendfile() operation, we wait till the data from * the last mblk is ack'ed by the transport before returning so that the * caller of sendfile() can safely modify the file content. + * + * The caller of this function should make sure that total_size does not exceed + * the actual file size of fvp. */ int snf_segmap(file_t *fp, vnode_t *fvp, u_offset_t fileoff, u_offset_t total_size, @@ -2973,7 +2962,7 @@ recv32(int32_t sock, caddr32_t buffer, size32_t len, int32_t flags) ssize_t recvfrom32(int32_t sock, caddr32_t buffer, size32_t len, int32_t flags, - caddr32_t name, caddr32_t namelenp) + caddr32_t name, caddr32_t namelenp) { return (recvfrom(sock, (void *)(uintptr_t)buffer, (ssize32_t)len, flags, (void *)(uintptr_t)name, (void *)(uintptr_t)namelenp)); @@ -2987,7 +2976,7 @@ send32(int32_t sock, caddr32_t buffer, size32_t len, int32_t flags) ssize_t sendto32(int32_t sock, caddr32_t buffer, size32_t len, int32_t flags, - caddr32_t name, socklen_t namelen) + caddr32_t name, socklen_t namelen) { return (sendto(sock, (void *)(uintptr_t)buffer, (ssize32_t)len, flags, (void *)(uintptr_t)name, namelen)); diff --git a/usr/src/uts/common/syscall/sendfile.c b/usr/src/uts/common/syscall/sendfile.c index 822f14416c..0cfafbf13f 100644 --- a/usr/src/uts/common/syscall/sendfile.c +++ b/usr/src/uts/common/syscall/sendfile.c @@ -953,13 +953,27 @@ sendvec_chunk(file_t *fp, u_offset_t *fileoff, struct sendfilevec *sfv, if (socket_setsockopt(VTOSO(vp), SOL_SOCKET, SO_SND_COPYAVOID, &on, sizeof (on), CRED()) == 0) - segmapit = 1; + segmapit = 1; } } if (segmapit) { + struct vattr va; boolean_t nowait; + va.va_mask = AT_SIZE; + error = VOP_GETATTR(readvp, &va, 0, kcred, + NULL); + if (error != 0 || sfv_off >= va.va_size) { + VOP_RWUNLOCK(readvp, V_WRITELOCK_FALSE, + NULL); + releasef(sfv->sfv_fd); + return (error); + } + /* Read as much as possible. */ + if (sfv_off + sfv_len > va.va_size) + sfv_len = va.va_size - sfv_off; + nowait = (sfv->sfv_flag & SFV_NOWAIT) != 0; error = snf_segmap(fp, readvp, sfv_off, (u_offset_t)sfv_len, (ssize_t *)&cnt, |