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 ---