@@ -91,7 +91,10 @@ static ssize_t configfs_read_iter(struct kiocb *iocb, struct iov_iter *to)
91
91
}
92
92
pr_debug ("%s: count = %zd, pos = %lld, buf = %s\n" ,
93
93
__func__ , iov_iter_count (to ), iocb -> ki_pos , buffer -> page );
94
- retval = copy_to_iter (buffer -> page , buffer -> count , to );
94
+ if (iocb -> ki_pos >= buffer -> count )
95
+ goto out ;
96
+ retval = copy_to_iter (buffer -> page + iocb -> ki_pos ,
97
+ buffer -> count - iocb -> ki_pos , to );
95
98
iocb -> ki_pos += retval ;
96
99
if (retval == 0 )
97
100
retval = - EFAULT ;
@@ -162,7 +165,10 @@ static ssize_t configfs_bin_read_iter(struct kiocb *iocb, struct iov_iter *to)
162
165
buffer -> needs_read_fill = 0 ;
163
166
}
164
167
165
- retval = copy_to_iter (buffer -> bin_buffer , buffer -> bin_buffer_size , to );
168
+ if (iocb -> ki_pos >= buffer -> bin_buffer_size )
169
+ goto out ;
170
+ retval = copy_to_iter (buffer -> bin_buffer + iocb -> ki_pos ,
171
+ buffer -> bin_buffer_size - iocb -> ki_pos , to );
166
172
iocb -> ki_pos += retval ;
167
173
if (retval == 0 )
168
174
retval = - EFAULT ;
@@ -171,21 +177,28 @@ static ssize_t configfs_bin_read_iter(struct kiocb *iocb, struct iov_iter *to)
171
177
return retval ;
172
178
}
173
179
174
- static int fill_write_buffer (struct configfs_buffer * buffer ,
180
+ /* Fill [buffer, buffer + pos) with data coming from @from. */
181
+ static int fill_write_buffer (struct configfs_buffer * buffer , loff_t pos ,
175
182
struct iov_iter * from )
176
183
{
184
+ loff_t to_copy ;
177
185
int copied ;
186
+ u8 * to ;
178
187
179
188
if (!buffer -> page )
180
189
buffer -> page = (char * )__get_free_pages (GFP_KERNEL , 0 );
181
190
if (!buffer -> page )
182
191
return - ENOMEM ;
183
192
184
- copied = copy_from_iter (buffer -> page , SIMPLE_ATTR_SIZE - 1 , from );
193
+ to_copy = SIMPLE_ATTR_SIZE - 1 - pos ;
194
+ if (to_copy <= 0 )
195
+ return 0 ;
196
+ to = buffer -> page + pos ;
197
+ copied = copy_from_iter (to , to_copy , from );
185
198
buffer -> needs_read_fill = 1 ;
186
199
/* if buf is assumed to contain a string, terminate it by \0,
187
200
* so e.g. sscanf() can scan the string easily */
188
- buffer -> page [copied ] = 0 ;
201
+ to [copied ] = 0 ;
189
202
return copied ? : - EFAULT ;
190
203
}
191
204
@@ -217,7 +230,7 @@ static ssize_t configfs_write_iter(struct kiocb *iocb, struct iov_iter *from)
217
230
ssize_t len ;
218
231
219
232
mutex_lock (& buffer -> mutex );
220
- len = fill_write_buffer (buffer , from );
233
+ len = fill_write_buffer (buffer , iocb -> ki_pos , from );
221
234
if (len > 0 )
222
235
len = flush_write_buffer (file , buffer , len );
223
236
if (len > 0 )
@@ -272,7 +285,9 @@ static ssize_t configfs_bin_write_iter(struct kiocb *iocb,
272
285
buffer -> bin_buffer_size = end_offset ;
273
286
}
274
287
275
- len = copy_from_iter (buffer -> bin_buffer , buffer -> bin_buffer_size , from );
288
+ len = copy_from_iter (buffer -> bin_buffer + iocb -> ki_pos ,
289
+ buffer -> bin_buffer_size - iocb -> ki_pos , from );
290
+ iocb -> ki_pos += len ;
276
291
out :
277
292
mutex_unlock (& buffer -> mutex );
278
293
return len ? : - EFAULT ;
0 commit comments