diff options
Diffstat (limited to 'net/socket.c')
| -rw-r--r-- | net/socket.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/net/socket.c b/net/socket.c index 5c5c5a85b21d..ef037a5b8456 100644 --- a/net/socket.c +++ b/net/socket.c @@ -71,6 +71,7 @@ #include <linux/poll.h> #include <linux/cache.h> #include <linux/module.h> +#include <linux/highmem.h> #if defined(CONFIG_KMOD) && defined(CONFIG_NET) #include <linux/kmod.h> @@ -104,6 +105,8 @@ static ssize_t sock_readv(struct file *file, const struct iovec *vector, unsigned long count, loff_t *ppos); static ssize_t sock_writev(struct file *file, const struct iovec *vector, unsigned long count, loff_t *ppos); +static ssize_t sock_writepage(struct file *file, struct page *page, + int offset, size_t size, loff_t *ppos, int more); /* @@ -122,7 +125,8 @@ static struct file_operations socket_file_ops = { release: sock_close, fasync: sock_fasync, readv: sock_readv, - writev: sock_writev + writev: sock_writev, + writepage: sock_writepage }; /* @@ -602,6 +606,24 @@ static ssize_t sock_write(struct file *file, const char *ubuf, return sock_sendmsg(sock, &msg, size); } +ssize_t sock_writepage(struct file *file, struct page *page, + int offset, size_t size, loff_t *ppos, int more) +{ + struct socket *sock; + int flags; + + if (ppos != &file->f_pos) + return -ESPIPE; + + sock = socki_lookup(file->f_dentry->d_inode); + + flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT; + if (more) + flags |= MSG_MORE; + + return sock->ops->sendpage(sock, page, offset, size, flags); +} + int sock_readv_writev(int type, struct inode * inode, struct file * file, const struct iovec * iov, long count, long size) { @@ -1269,7 +1291,10 @@ asmlinkage long sys_setsockopt(int fd, int level, int optname, char *optval, int { int err; struct socket *sock; - + + if (optlen < 0) + return -EINVAL; + if ((sock = sockfd_lookup(fd, &err))!=NULL) { if (level == SOL_SOCKET) |
