xdr.c (094bb20b9fcab3a1652a77741caba6b78097d622) | xdr.c (a246b0105bbd9a70a698f69baae2042996f2a0e9) |
---|---|
1/* 2 * linux/net/sunrpc/xdr.c 3 * 4 * Generic XDR support. 5 * 6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> 7 */ 8 | 1/* 2 * linux/net/sunrpc/xdr.c 3 * 4 * Generic XDR support. 5 * 6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> 7 */ 8 |
9#include <linux/module.h> |
|
9#include <linux/types.h> | 10#include <linux/types.h> |
10#include <linux/socket.h> | |
11#include <linux/string.h> 12#include <linux/kernel.h> 13#include <linux/pagemap.h> 14#include <linux/errno.h> | 11#include <linux/string.h> 12#include <linux/kernel.h> 13#include <linux/pagemap.h> 14#include <linux/errno.h> |
15#include <linux/in.h> 16#include <linux/net.h> 17#include <net/sock.h> | |
18#include <linux/sunrpc/xdr.h> 19#include <linux/sunrpc/msg_prot.h> 20 21/* 22 * XDR functions for basic NFS types 23 */ 24u32 * 25xdr_encode_netobj(u32 *p, const struct xdr_netobj *obj) --- 146 unchanged lines hidden (view full) --- 172 173 tail->iov_base = buf + offset; 174 tail->iov_len = buflen - offset; 175 176 xdr->buflen += len; 177} 178 179 | 15#include <linux/sunrpc/xdr.h> 16#include <linux/sunrpc/msg_prot.h> 17 18/* 19 * XDR functions for basic NFS types 20 */ 21u32 * 22xdr_encode_netobj(u32 *p, const struct xdr_netobj *obj) --- 146 unchanged lines hidden (view full) --- 169 170 tail->iov_base = buf + offset; 171 tail->iov_len = buflen - offset; 172 173 xdr->buflen += len; 174} 175 176 |
180int 181xdr_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, 182 struct xdr_buf *xdr, unsigned int base, int msgflags) 183{ 184 struct page **ppage = xdr->pages; 185 unsigned int len, pglen = xdr->page_len; 186 int err, ret = 0; 187 ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int); 188 189 len = xdr->head[0].iov_len; 190 if (base < len || (addr != NULL && base == 0)) { 191 struct kvec iov = { 192 .iov_base = xdr->head[0].iov_base + base, 193 .iov_len = len - base, 194 }; 195 struct msghdr msg = { 196 .msg_name = addr, 197 .msg_namelen = addrlen, 198 .msg_flags = msgflags, 199 }; 200 if (xdr->len > len) 201 msg.msg_flags |= MSG_MORE; 202 203 if (iov.iov_len != 0) 204 err = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len); 205 else 206 err = kernel_sendmsg(sock, &msg, NULL, 0, 0); 207 if (ret == 0) 208 ret = err; 209 else if (err > 0) 210 ret += err; 211 if (err != iov.iov_len) 212 goto out; 213 base = 0; 214 } else 215 base -= len; 216 217 if (pglen == 0) 218 goto copy_tail; 219 if (base >= pglen) { 220 base -= pglen; 221 goto copy_tail; 222 } 223 if (base || xdr->page_base) { 224 pglen -= base; 225 base += xdr->page_base; 226 ppage += base >> PAGE_CACHE_SHIFT; 227 base &= ~PAGE_CACHE_MASK; 228 } 229 230 sendpage = sock->ops->sendpage ? : sock_no_sendpage; 231 do { 232 int flags = msgflags; 233 234 len = PAGE_CACHE_SIZE; 235 if (base) 236 len -= base; 237 if (pglen < len) 238 len = pglen; 239 240 if (pglen != len || xdr->tail[0].iov_len != 0) 241 flags |= MSG_MORE; 242 243 /* Hmm... We might be dealing with highmem pages */ 244 if (PageHighMem(*ppage)) 245 sendpage = sock_no_sendpage; 246 err = sendpage(sock, *ppage, base, len, flags); 247 if (ret == 0) 248 ret = err; 249 else if (err > 0) 250 ret += err; 251 if (err != len) 252 goto out; 253 base = 0; 254 ppage++; 255 } while ((pglen -= len) != 0); 256copy_tail: 257 len = xdr->tail[0].iov_len; 258 if (base < len) { 259 struct kvec iov = { 260 .iov_base = xdr->tail[0].iov_base + base, 261 .iov_len = len - base, 262 }; 263 struct msghdr msg = { 264 .msg_flags = msgflags, 265 }; 266 err = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len); 267 if (ret == 0) 268 ret = err; 269 else if (err > 0) 270 ret += err; 271 } 272out: 273 return ret; 274} 275 276 | |
277/* 278 * Helper routines for doing 'memmove' like operations on a struct xdr_buf 279 * 280 * _shift_data_right_pages 281 * @pages: vector of pages containing both the source and dest memory area. 282 * @pgto_base: page vector address of destination 283 * @pgfrom_base: page vector address of source 284 * @len: number of bytes to copy --- 837 unchanged lines hidden --- | 177/* 178 * Helper routines for doing 'memmove' like operations on a struct xdr_buf 179 * 180 * _shift_data_right_pages 181 * @pages: vector of pages containing both the source and dest memory area. 182 * @pgto_base: page vector address of destination 183 * @pgfrom_base: page vector address of source 184 * @len: number of bytes to copy --- 837 unchanged lines hidden --- |