aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-04-07 12:23:29 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2015-04-15 15:06:33 -0400
commitaa4d86163e4e91a1ac560954a554bab417e338f4 (patch)
tree25c4f29e616669c7f2f72309b2ca2668c7c90438
parent6683de3886a313ae3d4b8c0323313a987073481b (diff)
block: loop: switch to VFS ITER_BVEC
Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--drivers/block/loop.c294
1 files changed, 120 insertions, 174 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index c4fd1e45ce1e..ae3fcb4199e9 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -88,28 +88,6 @@ static int part_shift;
88 88
89static struct workqueue_struct *loop_wq; 89static struct workqueue_struct *loop_wq;
90 90
91/*
92 * Transfer functions
93 */
94static int transfer_none(struct loop_device *lo, int cmd,
95 struct page *raw_page, unsigned raw_off,
96 struct page *loop_page, unsigned loop_off,
97 int size, sector_t real_block)
98{
99 char *raw_buf = kmap_atomic(raw_page) + raw_off;
100 char *loop_buf = kmap_atomic(loop_page) + loop_off;
101
102 if (cmd == READ)
103 memcpy(loop_buf, raw_buf, size);
104 else
105 memcpy(raw_buf, loop_buf, size);
106
107 kunmap_atomic(loop_buf);
108 kunmap_atomic(raw_buf);
109 cond_resched();
110 return 0;
111}
112
113static int transfer_xor(struct loop_device *lo, int cmd, 91static int transfer_xor(struct loop_device *lo, int cmd,
114 struct page *raw_page, unsigned raw_off, 92 struct page *raw_page, unsigned raw_off,
115 struct page *loop_page, unsigned loop_off, 93 struct page *loop_page, unsigned loop_off,
@@ -148,14 +126,13 @@ static int xor_init(struct loop_device *lo, const struct loop_info64 *info)
148 126
149static struct loop_func_table none_funcs = { 127static struct loop_func_table none_funcs = {
150 .number = LO_CRYPT_NONE, 128 .number = LO_CRYPT_NONE,
151 .transfer = transfer_none, 129};
152};
153 130
154static struct loop_func_table xor_funcs = { 131static struct loop_func_table xor_funcs = {
155 .number = LO_CRYPT_XOR, 132 .number = LO_CRYPT_XOR,
156 .transfer = transfer_xor, 133 .transfer = transfer_xor,
157 .init = xor_init 134 .init = xor_init
158}; 135};
159 136
160/* xfer_funcs[0] is special - its release function is never called */ 137/* xfer_funcs[0] is special - its release function is never called */
161static struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = { 138static struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = {
@@ -215,207 +192,169 @@ lo_do_transfer(struct loop_device *lo, int cmd,
215 struct page *lpage, unsigned loffs, 192 struct page *lpage, unsigned loffs,
216 int size, sector_t rblock) 193 int size, sector_t rblock)
217{ 194{
218 if (unlikely(!lo->transfer)) 195 int ret;
196
197 ret = lo->transfer(lo, cmd, rpage, roffs, lpage, loffs, size, rblock);
198 if (likely(!ret))
219 return 0; 199 return 0;
220 200
221 return lo->transfer(lo, cmd, rpage, roffs, lpage, loffs, size, rblock); 201 printk_ratelimited(KERN_ERR
202 "loop: Transfer error at byte offset %llu, length %i.\n",
203 (unsigned long long)rblock << 9, size);
204 return ret;
222} 205}
223 206
224/** 207static int lo_write_bvec(struct file *file, struct bio_vec *bvec, loff_t *ppos)
225 * __do_lo_send_write - helper for writing data to a loop device
226 *
227 * This helper just factors out common code between do_lo_send_direct_write()
228 * and do_lo_send_write().
229 */
230static int __do_lo_send_write(struct file *file,
231 u8 *buf, const int len, loff_t pos)
232{ 208{
233 struct kvec kvec = {.iov_base = buf, .iov_len = len}; 209 struct iov_iter i;
234 struct iov_iter from;
235 ssize_t bw; 210 ssize_t bw;
236 211
237 iov_iter_kvec(&from, ITER_KVEC | WRITE, &kvec, 1, len); 212 iov_iter_bvec(&i, ITER_BVEC, bvec, 1, bvec->bv_len);
238 213
239 file_start_write(file); 214 file_start_write(file);
240 bw = vfs_iter_write(file, &from, &pos); 215 bw = vfs_iter_write(file, &i, ppos);
241 file_end_write(file); 216 file_end_write(file);
242 if (likely(bw == len)) 217
218 if (likely(bw == bvec->bv_len))
243 return 0; 219 return 0;
244 printk_ratelimited(KERN_ERR "loop: Write error at byte offset %llu, length %i.\n", 220
245 (unsigned long long)pos, len); 221 printk_ratelimited(KERN_ERR
222 "loop: Write error at byte offset %llu, length %i.\n",
223 (unsigned long long)*ppos, bvec->bv_len);
246 if (bw >= 0) 224 if (bw >= 0)
247 bw = -EIO; 225 bw = -EIO;
248 return bw; 226 return bw;
249} 227}
250 228
251/** 229static int lo_write_simple(struct loop_device *lo, struct request *rq,
252 * do_lo_send_direct_write - helper for writing data to a loop device 230 loff_t pos)
253 *
254 * This is the fast, non-transforming version that does not need double
255 * buffering.
256 */
257static int do_lo_send_direct_write(struct loop_device *lo,
258 struct bio_vec *bvec, loff_t pos, struct page *page)
259{ 231{
260 ssize_t bw = __do_lo_send_write(lo->lo_backing_file, 232 struct bio_vec bvec;
261 kmap(bvec->bv_page) + bvec->bv_offset, 233 struct req_iterator iter;
262 bvec->bv_len, pos); 234 int ret = 0;
263 kunmap(bvec->bv_page); 235
264 cond_resched(); 236 rq_for_each_segment(bvec, rq, iter) {
265 return bw; 237 ret = lo_write_bvec(lo->lo_backing_file, &bvec, &pos);
238 if (ret < 0)
239 break;
240 cond_resched();
241 }
242
243 return ret;
266} 244}
267 245
268/** 246/*
269 * do_lo_send_write - helper for writing data to a loop device
270 *
271 * This is the slow, transforming version that needs to double buffer the 247 * This is the slow, transforming version that needs to double buffer the
272 * data as it cannot do the transformations in place without having direct 248 * data as it cannot do the transformations in place without having direct
273 * access to the destination pages of the backing file. 249 * access to the destination pages of the backing file.
274 */ 250 */
275static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec, 251static int lo_write_transfer(struct loop_device *lo, struct request *rq,
276 loff_t pos, struct page *page) 252 loff_t pos)
277{ 253{
278 int ret = lo_do_transfer(lo, WRITE, page, 0, bvec->bv_page, 254 struct bio_vec bvec, b;
279 bvec->bv_offset, bvec->bv_len, pos >> 9);
280 if (likely(!ret))
281 return __do_lo_send_write(lo->lo_backing_file,
282 page_address(page), bvec->bv_len,
283 pos);
284 printk_ratelimited(KERN_ERR "loop: Transfer error at byte offset %llu, "
285 "length %i.\n", (unsigned long long)pos, bvec->bv_len);
286 if (ret > 0)
287 ret = -EIO;
288 return ret;
289}
290
291static int lo_send(struct loop_device *lo, struct request *rq, loff_t pos)
292{
293 int (*do_lo_send)(struct loop_device *, struct bio_vec *, loff_t,
294 struct page *page);
295 struct bio_vec bvec;
296 struct req_iterator iter; 255 struct req_iterator iter;
297 struct page *page = NULL; 256 struct page *page;
298 int ret = 0; 257 int ret = 0;
299 258
300 if (lo->transfer != transfer_none) { 259 page = alloc_page(GFP_NOIO);
301 page = alloc_page(GFP_NOIO | __GFP_HIGHMEM); 260 if (unlikely(!page))
302 if (unlikely(!page)) 261 return -ENOMEM;
303 goto fail;
304 kmap(page);
305 do_lo_send = do_lo_send_write;
306 } else {
307 do_lo_send = do_lo_send_direct_write;
308 }
309 262
310 rq_for_each_segment(bvec, rq, iter) { 263 rq_for_each_segment(bvec, rq, iter) {
311 ret = do_lo_send(lo, &bvec, pos, page); 264 ret = lo_do_transfer(lo, WRITE, page, 0, bvec.bv_page,
265 bvec.bv_offset, bvec.bv_len, pos >> 9);
266 if (unlikely(ret))
267 break;
268
269 b.bv_page = page;
270 b.bv_offset = 0;
271 b.bv_len = bvec.bv_len;
272 ret = lo_write_bvec(lo->lo_backing_file, &b, &pos);
312 if (ret < 0) 273 if (ret < 0)
313 break; 274 break;
314 pos += bvec.bv_len;
315 } 275 }
316 if (page) { 276
317 kunmap(page); 277 __free_page(page);
318 __free_page(page);
319 }
320out:
321 return ret; 278 return ret;
322fail:
323 printk_ratelimited(KERN_ERR "loop: Failed to allocate temporary page for write.\n");
324 ret = -ENOMEM;
325 goto out;
326} 279}
327 280
328struct lo_read_data { 281static int lo_read_simple(struct loop_device *lo, struct request *rq,
329 struct loop_device *lo; 282 loff_t pos)
330 struct page *page; 283{
331 unsigned offset; 284 struct bio_vec bvec;
332 int bsize; 285 struct req_iterator iter;
333}; 286 struct iov_iter i;
287 ssize_t len;
334 288
335static int 289 rq_for_each_segment(bvec, rq, iter) {
336lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, 290 iov_iter_bvec(&i, ITER_BVEC, &bvec, 1, bvec.bv_len);
337 struct splice_desc *sd) 291 len = vfs_iter_read(lo->lo_backing_file, &i, &pos);
338{ 292 if (len < 0)
339 struct lo_read_data *p = sd->u.data; 293 return len;
340 struct loop_device *lo = p->lo;
341 struct page *page = buf->page;
342 sector_t IV;
343 int size;
344
345 IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) +
346 (buf->offset >> 9);
347 size = sd->len;
348 if (size > p->bsize)
349 size = p->bsize;
350
351 if (lo_do_transfer(lo, READ, page, buf->offset, p->page, p->offset, size, IV)) {
352 printk_ratelimited(KERN_ERR "loop: transfer error block %ld\n",
353 page->index);
354 size = -EINVAL;
355 }
356 294
357 flush_dcache_page(p->page); 295 flush_dcache_page(bvec.bv_page);
358 296
359 if (size > 0) 297 if (len != bvec.bv_len) {
360 p->offset += size; 298 struct bio *bio;
361 299
362 return size; 300 __rq_for_each_bio(bio, rq)
363} 301 zero_fill_bio(bio);
302 break;
303 }
304 cond_resched();
305 }
364 306
365static int 307 return 0;
366lo_direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc *sd)
367{
368 return __splice_from_pipe(pipe, sd, lo_splice_actor);
369} 308}
370 309
371static ssize_t 310static int lo_read_transfer(struct loop_device *lo, struct request *rq,
372do_lo_receive(struct loop_device *lo, 311 loff_t pos)
373 struct bio_vec *bvec, int bsize, loff_t pos)
374{ 312{
375 struct lo_read_data cookie; 313 struct bio_vec bvec, b;
376 struct splice_desc sd; 314 struct req_iterator iter;
377 struct file *file; 315 struct iov_iter i;
378 ssize_t retval; 316 struct page *page;
317 ssize_t len;
318 int ret = 0;
379 319
380 cookie.lo = lo; 320 page = alloc_page(GFP_NOIO);
381 cookie.page = bvec->bv_page; 321 if (unlikely(!page))
382 cookie.offset = bvec->bv_offset; 322 return -ENOMEM;
383 cookie.bsize = bsize;
384 323
385 sd.len = 0; 324 rq_for_each_segment(bvec, rq, iter) {
386 sd.total_len = bvec->bv_len; 325 loff_t offset = pos;
387 sd.flags = 0;
388 sd.pos = pos;
389 sd.u.data = &cookie;
390 326
391 file = lo->lo_backing_file; 327 b.bv_page = page;
392 retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor); 328 b.bv_offset = 0;
329 b.bv_len = bvec.bv_len;
393 330
394 return retval; 331 iov_iter_bvec(&i, ITER_BVEC, &b, 1, b.bv_len);
395} 332 len = vfs_iter_read(lo->lo_backing_file, &i, &pos);
333 if (len < 0) {
334 ret = len;
335 goto out_free_page;
336 }
396 337
397static int 338 ret = lo_do_transfer(lo, READ, page, 0, bvec.bv_page,
398lo_receive(struct loop_device *lo, struct request *rq, int bsize, loff_t pos) 339 bvec.bv_offset, len, offset >> 9);
399{ 340 if (ret)
400 struct bio_vec bvec; 341 goto out_free_page;
401 struct req_iterator iter;
402 ssize_t s;
403 342
404 rq_for_each_segment(bvec, rq, iter) { 343 flush_dcache_page(bvec.bv_page);
405 s = do_lo_receive(lo, &bvec, bsize, pos);
406 if (s < 0)
407 return s;
408 344
409 if (s != bvec.bv_len) { 345 if (len != bvec.bv_len) {
410 struct bio *bio; 346 struct bio *bio;
411 347
412 __rq_for_each_bio(bio, rq) 348 __rq_for_each_bio(bio, rq)
413 zero_fill_bio(bio); 349 zero_fill_bio(bio);
414 break; 350 break;
415 } 351 }
416 pos += bvec.bv_len;
417 } 352 }
418 return 0; 353
354 ret = 0;
355out_free_page:
356 __free_page(page);
357 return ret;
419} 358}
420 359
421static int lo_discard(struct loop_device *lo, struct request *rq, loff_t pos) 360static int lo_discard(struct loop_device *lo, struct request *rq, loff_t pos)
@@ -464,10 +403,17 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
464 ret = lo_req_flush(lo, rq); 403 ret = lo_req_flush(lo, rq);
465 else if (rq->cmd_flags & REQ_DISCARD) 404 else if (rq->cmd_flags & REQ_DISCARD)
466 ret = lo_discard(lo, rq, pos); 405 ret = lo_discard(lo, rq, pos);
406 else if (lo->transfer)
407 ret = lo_write_transfer(lo, rq, pos);
467 else 408 else
468 ret = lo_send(lo, rq, pos); 409 ret = lo_write_simple(lo, rq, pos);
469 } else 410
470 ret = lo_receive(lo, rq, lo->lo_blocksize, pos); 411 } else {
412 if (lo->transfer)
413 ret = lo_read_transfer(lo, rq, pos);
414 else
415 ret = lo_read_simple(lo, rq, pos);
416 }
471 417
472 return ret; 418 return ret;
473} 419}
@@ -788,7 +734,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
788 lo->lo_device = bdev; 734 lo->lo_device = bdev;
789 lo->lo_flags = lo_flags; 735 lo->lo_flags = lo_flags;
790 lo->lo_backing_file = file; 736 lo->lo_backing_file = file;
791 lo->transfer = transfer_none; 737 lo->transfer = NULL;
792 lo->ioctl = NULL; 738 lo->ioctl = NULL;
793 lo->lo_sizelimit = 0; 739 lo->lo_sizelimit = 0;
794 lo->old_gfp_mask = mapping_gfp_mask(mapping); 740 lo->old_gfp_mask = mapping_gfp_mask(mapping);
@@ -1007,7 +953,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
1007 memcpy(lo->lo_encrypt_key, info->lo_encrypt_key, 953 memcpy(lo->lo_encrypt_key, info->lo_encrypt_key,
1008 info->lo_encrypt_key_size); 954 info->lo_encrypt_key_size);
1009 lo->lo_key_owner = uid; 955 lo->lo_key_owner = uid;
1010 } 956 }
1011 957
1012 return 0; 958 return 0;
1013} 959}