aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r--drivers/block/loop.c37
1 files changed, 8 insertions, 29 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index ddae8082589..801f4ab8330 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -511,11 +511,7 @@ out:
511 */ 511 */
512static void loop_add_bio(struct loop_device *lo, struct bio *bio) 512static void loop_add_bio(struct loop_device *lo, struct bio *bio)
513{ 513{
514 if (lo->lo_biotail) { 514 bio_list_add(&lo->lo_bio_list, bio);
515 lo->lo_biotail->bi_next = bio;
516 lo->lo_biotail = bio;
517 } else
518 lo->lo_bio = lo->lo_biotail = bio;
519} 515}
520 516
521/* 517/*
@@ -523,16 +519,7 @@ static void loop_add_bio(struct loop_device *lo, struct bio *bio)
523 */ 519 */
524static struct bio *loop_get_bio(struct loop_device *lo) 520static struct bio *loop_get_bio(struct loop_device *lo)
525{ 521{
526 struct bio *bio; 522 return bio_list_pop(&lo->lo_bio_list);
527
528 if ((bio = lo->lo_bio)) {
529 if (bio == lo->lo_biotail)
530 lo->lo_biotail = NULL;
531 lo->lo_bio = bio->bi_next;
532 bio->bi_next = NULL;
533 }
534
535 return bio;
536} 523}
537 524
538static int loop_make_request(struct request_queue *q, struct bio *old_bio) 525static int loop_make_request(struct request_queue *q, struct bio *old_bio)
@@ -609,12 +596,13 @@ static int loop_thread(void *data)
609 596
610 set_user_nice(current, -20); 597 set_user_nice(current, -20);
611 598
612 while (!kthread_should_stop() || lo->lo_bio) { 599 while (!kthread_should_stop() || !bio_list_empty(&lo->lo_bio_list)) {
613 600
614 wait_event_interruptible(lo->lo_event, 601 wait_event_interruptible(lo->lo_event,
615 lo->lo_bio || kthread_should_stop()); 602 !bio_list_empty(&lo->lo_bio_list) ||
603 kthread_should_stop());
616 604
617 if (!lo->lo_bio) 605 if (bio_list_empty(&lo->lo_bio_list))
618 continue; 606 continue;
619 spin_lock_irq(&lo->lo_lock); 607 spin_lock_irq(&lo->lo_lock);
620 bio = loop_get_bio(lo); 608 bio = loop_get_bio(lo);
@@ -721,10 +709,6 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
721 if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) 709 if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
722 goto out_putf; 710 goto out_putf;
723 711
724 /* new backing store needs to support loop (eg splice_read) */
725 if (!inode->i_fop->splice_read)
726 goto out_putf;
727
728 /* size of the new backing store needs to be the same */ 712 /* size of the new backing store needs to be the same */
729 if (get_loop_size(lo, file) != get_loop_size(lo, old_file)) 713 if (get_loop_size(lo, file) != get_loop_size(lo, old_file))
730 goto out_putf; 714 goto out_putf;
@@ -800,12 +784,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
800 error = -EINVAL; 784 error = -EINVAL;
801 if (S_ISREG(inode->i_mode) || S_ISBLK(inode->i_mode)) { 785 if (S_ISREG(inode->i_mode) || S_ISBLK(inode->i_mode)) {
802 const struct address_space_operations *aops = mapping->a_ops; 786 const struct address_space_operations *aops = mapping->a_ops;
803 /* 787
804 * If we can't read - sorry. If we only can't write - well,
805 * it's going to be read-only.
806 */
807 if (!file->f_op->splice_read)
808 goto out_putf;
809 if (aops->write_begin) 788 if (aops->write_begin)
810 lo_flags |= LO_FLAGS_USE_AOPS; 789 lo_flags |= LO_FLAGS_USE_AOPS;
811 if (!(lo_flags & LO_FLAGS_USE_AOPS) && !file->f_op->write) 790 if (!(lo_flags & LO_FLAGS_USE_AOPS) && !file->f_op->write)
@@ -841,7 +820,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
841 lo->old_gfp_mask = mapping_gfp_mask(mapping); 820 lo->old_gfp_mask = mapping_gfp_mask(mapping);
842 mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); 821 mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
843 822
844 lo->lo_bio = lo->lo_biotail = NULL; 823 bio_list_init(&lo->lo_bio_list);
845 824
846 /* 825 /*
847 * set queue make_request_fn, and add limits based on lower level 826 * set queue make_request_fn, and add limits based on lower level