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.c38
1 files changed, 21 insertions, 17 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index f2913ae2b52..4e7ac09c281 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1406,12 +1406,13 @@ new_page:
1406/* 1406/*
1407 * Fill page/offset/length into spd, if it can hold more pages. 1407 * Fill page/offset/length into spd, if it can hold more pages.
1408 */ 1408 */
1409static inline int spd_fill_page(struct splice_pipe_desc *spd, struct page *page, 1409static inline int spd_fill_page(struct splice_pipe_desc *spd,
1410 struct pipe_inode_info *pipe, struct page *page,
1410 unsigned int *len, unsigned int offset, 1411 unsigned int *len, unsigned int offset,
1411 struct sk_buff *skb, int linear, 1412 struct sk_buff *skb, int linear,
1412 struct sock *sk) 1413 struct sock *sk)
1413{ 1414{
1414 if (unlikely(spd->nr_pages == PIPE_BUFFERS)) 1415 if (unlikely(spd->nr_pages == pipe->buffers))
1415 return 1; 1416 return 1;
1416 1417
1417 if (linear) { 1418 if (linear) {
@@ -1447,7 +1448,8 @@ static inline int __splice_segment(struct page *page, unsigned int poff,
1447 unsigned int plen, unsigned int *off, 1448 unsigned int plen, unsigned int *off,
1448 unsigned int *len, struct sk_buff *skb, 1449 unsigned int *len, struct sk_buff *skb,
1449 struct splice_pipe_desc *spd, int linear, 1450 struct splice_pipe_desc *spd, int linear,
1450 struct sock *sk) 1451 struct sock *sk,
1452 struct pipe_inode_info *pipe)
1451{ 1453{
1452 if (!*len) 1454 if (!*len)
1453 return 1; 1455 return 1;
@@ -1470,7 +1472,7 @@ static inline int __splice_segment(struct page *page, unsigned int poff,
1470 /* the linear region may spread across several pages */ 1472 /* the linear region may spread across several pages */
1471 flen = min_t(unsigned int, flen, PAGE_SIZE - poff); 1473 flen = min_t(unsigned int, flen, PAGE_SIZE - poff);
1472 1474
1473 if (spd_fill_page(spd, page, &flen, poff, skb, linear, sk)) 1475 if (spd_fill_page(spd, pipe, page, &flen, poff, skb, linear, sk))
1474 return 1; 1476 return 1;
1475 1477
1476 __segment_seek(&page, &poff, &plen, flen); 1478 __segment_seek(&page, &poff, &plen, flen);
@@ -1485,9 +1487,9 @@ static inline int __splice_segment(struct page *page, unsigned int poff,
1485 * Map linear and fragment data from the skb to spd. It reports failure if the 1487 * Map linear and fragment data from the skb to spd. It reports failure if the
1486 * pipe is full or if we already spliced the requested length. 1488 * pipe is full or if we already spliced the requested length.
1487 */ 1489 */
1488static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset, 1490static int __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe,
1489 unsigned int *len, struct splice_pipe_desc *spd, 1491 unsigned int *offset, unsigned int *len,
1490 struct sock *sk) 1492 struct splice_pipe_desc *spd, struct sock *sk)
1491{ 1493{
1492 int seg; 1494 int seg;
1493 1495
@@ -1497,7 +1499,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
1497 if (__splice_segment(virt_to_page(skb->data), 1499 if (__splice_segment(virt_to_page(skb->data),
1498 (unsigned long) skb->data & (PAGE_SIZE - 1), 1500 (unsigned long) skb->data & (PAGE_SIZE - 1),
1499 skb_headlen(skb), 1501 skb_headlen(skb),
1500 offset, len, skb, spd, 1, sk)) 1502 offset, len, skb, spd, 1, sk, pipe))
1501 return 1; 1503 return 1;
1502 1504
1503 /* 1505 /*
@@ -1507,7 +1509,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
1507 const skb_frag_t *f = &skb_shinfo(skb)->frags[seg]; 1509 const skb_frag_t *f = &skb_shinfo(skb)->frags[seg];
1508 1510
1509 if (__splice_segment(f->page, f->page_offset, f->size, 1511 if (__splice_segment(f->page, f->page_offset, f->size,
1510 offset, len, skb, spd, 0, sk)) 1512 offset, len, skb, spd, 0, sk, pipe))
1511 return 1; 1513 return 1;
1512 } 1514 }
1513 1515
@@ -1524,8 +1526,8 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
1524 struct pipe_inode_info *pipe, unsigned int tlen, 1526 struct pipe_inode_info *pipe, unsigned int tlen,
1525 unsigned int flags) 1527 unsigned int flags)
1526{ 1528{
1527 struct partial_page partial[PIPE_BUFFERS]; 1529 struct partial_page partial[PIPE_DEF_BUFFERS];
1528 struct page *pages[PIPE_BUFFERS]; 1530 struct page *pages[PIPE_DEF_BUFFERS];
1529 struct splice_pipe_desc spd = { 1531 struct splice_pipe_desc spd = {
1530 .pages = pages, 1532 .pages = pages,
1531 .partial = partial, 1533 .partial = partial,
@@ -1535,12 +1537,16 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
1535 }; 1537 };
1536 struct sk_buff *frag_iter; 1538 struct sk_buff *frag_iter;
1537 struct sock *sk = skb->sk; 1539 struct sock *sk = skb->sk;
1540 int ret = 0;
1541
1542 if (splice_grow_spd(pipe, &spd))
1543 return -ENOMEM;
1538 1544
1539 /* 1545 /*
1540 * __skb_splice_bits() only fails if the output has no room left, 1546 * __skb_splice_bits() only fails if the output has no room left,
1541 * so no point in going over the frag_list for the error case. 1547 * so no point in going over the frag_list for the error case.
1542 */ 1548 */
1543 if (__skb_splice_bits(skb, &offset, &tlen, &spd, sk)) 1549 if (__skb_splice_bits(skb, pipe, &offset, &tlen, &spd, sk))
1544 goto done; 1550 goto done;
1545 else if (!tlen) 1551 else if (!tlen)
1546 goto done; 1552 goto done;
@@ -1551,14 +1557,12 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
1551 skb_walk_frags(skb, frag_iter) { 1557 skb_walk_frags(skb, frag_iter) {
1552 if (!tlen) 1558 if (!tlen)
1553 break; 1559 break;
1554 if (__skb_splice_bits(frag_iter, &offset, &tlen, &spd, sk)) 1560 if (__skb_splice_bits(frag_iter, pipe, &offset, &tlen, &spd, sk))
1555 break; 1561 break;
1556 } 1562 }
1557 1563
1558done: 1564done:
1559 if (spd.nr_pages) { 1565 if (spd.nr_pages) {
1560 int ret;
1561
1562 /* 1566 /*
1563 * Drop the socket lock, otherwise we have reverse 1567 * Drop the socket lock, otherwise we have reverse
1564 * locking dependencies between sk_lock and i_mutex 1568 * locking dependencies between sk_lock and i_mutex
@@ -1571,10 +1575,10 @@ done:
1571 release_sock(sk); 1575 release_sock(sk);
1572 ret = splice_to_pipe(pipe, &spd); 1576 ret = splice_to_pipe(pipe, &spd);
1573 lock_sock(sk); 1577 lock_sock(sk);
1574 return ret;
1575 } 1578 }
1576 1579
1577 return 0; 1580 splice_shrink_spd(pipe, &spd);
1581 return ret;
1578} 1582}
1579 1583
1580/** 1584/**