@@ -560,6 +560,38 @@ static size_t copy_pipe_to_iter(const void *addr, size_t bytes,
560
560
return bytes ;
561
561
}
562
562
563
+ static size_t csum_and_copy_to_pipe_iter (const void * addr , size_t bytes ,
564
+ __wsum * csum , struct iov_iter * i )
565
+ {
566
+ struct pipe_inode_info * pipe = i -> pipe ;
567
+ size_t n , r ;
568
+ size_t off = 0 ;
569
+ __wsum sum = * csum , next ;
570
+ int idx ;
571
+
572
+ if (!sanity (i ))
573
+ return 0 ;
574
+
575
+ bytes = n = push_pipe (i , bytes , & idx , & r );
576
+ if (unlikely (!n ))
577
+ return 0 ;
578
+ for ( ; n ; idx = next_idx (idx , pipe ), r = 0 ) {
579
+ size_t chunk = min_t (size_t , n , PAGE_SIZE - r );
580
+ char * p = kmap_atomic (pipe -> bufs [idx ].page );
581
+ next = csum_partial_copy_nocheck (addr , p + r , chunk , 0 );
582
+ sum = csum_block_add (sum , next , off );
583
+ kunmap_atomic (p );
584
+ i -> idx = idx ;
585
+ i -> iov_offset = r + chunk ;
586
+ n -= chunk ;
587
+ off += chunk ;
588
+ addr += chunk ;
589
+ }
590
+ i -> count -= bytes ;
591
+ * csum = sum ;
592
+ return bytes ;
593
+ }
594
+
563
595
size_t _copy_to_iter (const void * addr , size_t bytes , struct iov_iter * i )
564
596
{
565
597
const char * from = addr ;
@@ -1438,8 +1470,12 @@ size_t csum_and_copy_to_iter(const void *addr, size_t bytes, __wsum *csum,
1438
1470
const char * from = addr ;
1439
1471
__wsum sum , next ;
1440
1472
size_t off = 0 ;
1473
+
1474
+ if (unlikely (iov_iter_is_pipe (i )))
1475
+ return csum_and_copy_to_pipe_iter (addr , bytes , csum , i );
1476
+
1441
1477
sum = * csum ;
1442
- if (unlikely (iov_iter_is_pipe ( i ) || iov_iter_is_discard (i ))) {
1478
+ if (unlikely (iov_iter_is_discard (i ))) {
1443
1479
WARN_ON (1 ); /* for now */
1444
1480
return 0 ;
1445
1481
}
0 commit comments