splice: implement default splice_read method
[linux-2.6-block.git] / drivers / block / loop.c
index ddae80825899ae0459bff4a8109d8fc3468868c3..801f4ab83302556e9b48f1ddf139201a05e8c304 100644 (file)
@@ -511,11 +511,7 @@ out:
  */
 static void loop_add_bio(struct loop_device *lo, struct bio *bio)
 {
-       if (lo->lo_biotail) {
-               lo->lo_biotail->bi_next = bio;
-               lo->lo_biotail = bio;
-       } else
-               lo->lo_bio = lo->lo_biotail = bio;
+       bio_list_add(&lo->lo_bio_list, bio);
 }
 
 /*
@@ -523,16 +519,7 @@ static void loop_add_bio(struct loop_device *lo, struct bio *bio)
  */
 static struct bio *loop_get_bio(struct loop_device *lo)
 {
-       struct bio *bio;
-
-       if ((bio = lo->lo_bio)) {
-               if (bio == lo->lo_biotail)
-                       lo->lo_biotail = NULL;
-               lo->lo_bio = bio->bi_next;
-               bio->bi_next = NULL;
-       }
-
-       return bio;
+       return bio_list_pop(&lo->lo_bio_list);
 }
 
 static int loop_make_request(struct request_queue *q, struct bio *old_bio)
@@ -609,12 +596,13 @@ static int loop_thread(void *data)
 
        set_user_nice(current, -20);
 
-       while (!kthread_should_stop() || lo->lo_bio) {
+       while (!kthread_should_stop() || !bio_list_empty(&lo->lo_bio_list)) {
 
                wait_event_interruptible(lo->lo_event,
-                               lo->lo_bio || kthread_should_stop());
+                               !bio_list_empty(&lo->lo_bio_list) ||
+                               kthread_should_stop());
 
-               if (!lo->lo_bio)
+               if (bio_list_empty(&lo->lo_bio_list))
                        continue;
                spin_lock_irq(&lo->lo_lock);
                bio = loop_get_bio(lo);
@@ -721,10 +709,6 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
        if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
                goto out_putf;
 
-       /* new backing store needs to support loop (eg splice_read) */
-       if (!inode->i_fop->splice_read)
-               goto out_putf;
-
        /* size of the new backing store needs to be the same */
        if (get_loop_size(lo, file) != get_loop_size(lo, old_file))
                goto out_putf;
@@ -800,12 +784,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
        error = -EINVAL;
        if (S_ISREG(inode->i_mode) || S_ISBLK(inode->i_mode)) {
                const struct address_space_operations *aops = mapping->a_ops;
-               /*
-                * If we can't read - sorry. If we only can't write - well,
-                * it's going to be read-only.
-                */
-               if (!file->f_op->splice_read)
-                       goto out_putf;
+
                if (aops->write_begin)
                        lo_flags |= LO_FLAGS_USE_AOPS;
                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,
        lo->old_gfp_mask = mapping_gfp_mask(mapping);
        mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
 
-       lo->lo_bio = lo->lo_biotail = NULL;
+       bio_list_init(&lo->lo_bio_list);
 
        /*
         * set queue make_request_fn, and add limits based on lower level