aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/skbuff.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/skbuff.c')
-rw-r--r--net/core/skbuff.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 5c459f2b7985..366621610e76 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1292,12 +1292,14 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
1292{ 1292{
1293 unsigned int nr_pages = spd->nr_pages; 1293 unsigned int nr_pages = spd->nr_pages;
1294 unsigned int poff, plen, len, toff, tlen; 1294 unsigned int poff, plen, len, toff, tlen;
1295 int headlen, seg; 1295 int headlen, seg, error = 0;
1296 1296
1297 toff = *offset; 1297 toff = *offset;
1298 tlen = *total_len; 1298 tlen = *total_len;
1299 if (!tlen) 1299 if (!tlen) {
1300 error = 1;
1300 goto err; 1301 goto err;
1302 }
1301 1303
1302 /* 1304 /*
1303 * if the offset is greater than the linear part, go directly to 1305 * if the offset is greater than the linear part, go directly to
@@ -1339,7 +1341,8 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
1339 * just jump directly to update and return, no point 1341 * just jump directly to update and return, no point
1340 * in going over fragments when the output is full. 1342 * in going over fragments when the output is full.
1341 */ 1343 */
1342 if (spd_fill_page(spd, virt_to_page(p), plen, poff, skb)) 1344 error = spd_fill_page(spd, virt_to_page(p), plen, poff, skb);
1345 if (error)
1343 goto done; 1346 goto done;
1344 1347
1345 tlen -= plen; 1348 tlen -= plen;
@@ -1369,7 +1372,8 @@ map_frag:
1369 if (!plen) 1372 if (!plen)
1370 break; 1373 break;
1371 1374
1372 if (spd_fill_page(spd, f->page, plen, poff, skb)) 1375 error = spd_fill_page(spd, f->page, plen, poff, skb);
1376 if (error)
1373 break; 1377 break;
1374 1378
1375 tlen -= plen; 1379 tlen -= plen;
@@ -1382,7 +1386,10 @@ done:
1382 return 0; 1386 return 0;
1383 } 1387 }
1384err: 1388err:
1385 return 1; 1389 /* update the offset to reflect the linear part skip, if any */
1390 if (!error)
1391 *offset = toff;
1392 return error;
1386} 1393}
1387 1394
1388/* 1395/*
@@ -1445,6 +1452,7 @@ done:
1445 1452
1446 if (spd.nr_pages) { 1453 if (spd.nr_pages) {
1447 int ret; 1454 int ret;
1455 struct sock *sk = __skb->sk;
1448 1456
1449 /* 1457 /*
1450 * Drop the socket lock, otherwise we have reverse 1458 * Drop the socket lock, otherwise we have reverse
@@ -1455,9 +1463,9 @@ done:
1455 * we call into ->sendpage() with the i_mutex lock held 1463 * we call into ->sendpage() with the i_mutex lock held
1456 * and networking will grab the socket lock. 1464 * and networking will grab the socket lock.
1457 */ 1465 */
1458 release_sock(__skb->sk); 1466 release_sock(sk);
1459 ret = splice_to_pipe(pipe, &spd); 1467 ret = splice_to_pipe(pipe, &spd);
1460 lock_sock(__skb->sk); 1468 lock_sock(sk);
1461 return ret; 1469 return ret;
1462 } 1470 }
1463 1471