@@ -73,6 +73,7 @@ static int dump_pages(struct parasite_dump_pages_args *args)
73
73
int p , ret , tsock ;
74
74
struct iovec * iovs ;
75
75
int off , nr_segs ;
76
+ long buf_off ;
76
77
unsigned long spliced_bytes = 0 ;
77
78
78
79
tsock = parasite_get_rpc_sock ();
@@ -82,22 +83,37 @@ static int dump_pages(struct parasite_dump_pages_args *args)
82
83
83
84
iovs = pargs_iovs (args );
84
85
off = 0 ;
85
- nr_segs = args -> nr_segs ;
86
- if (nr_segs > UIO_MAXIOV )
87
- nr_segs = UIO_MAXIOV ;
86
+ buf_off = 0 ;
88
87
while (1 ) {
88
+ nr_segs = args -> nr_segs - off ;
89
+ if (nr_segs > UIO_MAXIOV )
90
+ nr_segs = UIO_MAXIOV ;
91
+
92
+ iovs [args -> off + off ].iov_base += buf_off ;
93
+ iovs [args -> off + off ].iov_len -= buf_off ;
89
94
ret = sys_vmsplice (p , & iovs [args -> off + off ], nr_segs , SPLICE_F_GIFT | SPLICE_F_NONBLOCK );
95
+ iovs [args -> off + off ].iov_base -= buf_off ;
96
+ iovs [args -> off + off ].iov_len += buf_off ;
90
97
if (ret < 0 ) {
91
98
sys_close (p );
99
+ pr_err ("iov_base %p iov_len %lx\n" , iovs [args -> off + off ].iov_base , iovs [args -> off + off ].iov_len );
92
100
pr_err ("Can't splice pages to pipe (%d/%d/%d)\n" , ret , nr_segs , args -> off + off );
93
101
return -1 ;
94
102
}
95
103
spliced_bytes += ret ;
96
- off += nr_segs ;
104
+ while (ret ) {
105
+ long l = iovs [args -> off + off ].iov_len - buf_off ;
106
+ if (ret < l ) {
107
+ buf_off += ret ;
108
+ break ;
109
+ }
110
+ ret -= l ;
111
+ buf_off = 0 ;
112
+ off ++ ;
113
+ }
97
114
if (off == args -> nr_segs )
98
115
break ;
99
- if (off + nr_segs > args -> nr_segs )
100
- nr_segs = args -> nr_segs - off ;
116
+ BUG_ON (off > args -> nr_segs );
101
117
}
102
118
if (spliced_bytes != args -> nr_pages * PAGE_SIZE ) {
103
119
sys_close (p );
0 commit comments