diff options
Diffstat (limited to 'drivers/block/loop.c')
| -rw-r--r-- | drivers/block/loop.c | 60 | 
1 files changed, 32 insertions, 28 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 40e715531aa..6cb1beb47c2 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -237,7 +237,7 @@ static int __do_lo_send_write(struct file *file,  	file_end_write(file);  	if (likely(bw == len))  		return 0; -	printk(KERN_ERR "loop: Write error at byte offset %llu, length %i.\n", +	printk_ratelimited(KERN_ERR "loop: Write error at byte offset %llu, length %i.\n",  			(unsigned long long)pos, len);  	if (bw >= 0)  		bw = -EIO; @@ -277,7 +277,7 @@ static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec,  		return __do_lo_send_write(lo->lo_backing_file,  				page_address(page), bvec->bv_len,  				pos); -	printk(KERN_ERR "loop: Transfer error at byte offset %llu, " +	printk_ratelimited(KERN_ERR "loop: Transfer error at byte offset %llu, "  			"length %i.\n", (unsigned long long)pos, bvec->bv_len);  	if (ret > 0)  		ret = -EIO; @@ -288,9 +288,10 @@ static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos)  {  	int (*do_lo_send)(struct loop_device *, struct bio_vec *, loff_t,  			struct page *page); -	struct bio_vec *bvec; +	struct bio_vec bvec; +	struct bvec_iter iter;  	struct page *page = NULL; -	int i, ret = 0; +	int ret = 0;  	if (lo->transfer != transfer_none) {  		page = alloc_page(GFP_NOIO | __GFP_HIGHMEM); @@ -302,11 +303,11 @@ static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos)  		do_lo_send = do_lo_send_direct_write;  	} -	bio_for_each_segment(bvec, bio, i) { -		ret = do_lo_send(lo, bvec, pos, page); +	bio_for_each_segment(bvec, bio, iter) { +		ret = do_lo_send(lo, &bvec, pos, page);  		if (ret < 0)  			break; -		pos += bvec->bv_len; +		pos += bvec.bv_len;  	}  	if (page) {  		kunmap(page); @@ -315,7 +316,7 @@ static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos)  out:  	return ret;  fail: -	printk(KERN_ERR "loop: Failed to allocate temporary page for write.\n"); +	printk_ratelimited(KERN_ERR "loop: Failed to allocate temporary page for write.\n");  	ret = -ENOMEM;  	goto out;  } @@ -344,7 +345,7 @@ lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,  		size = p->bsize;  	if (lo_do_transfer(lo, READ, page, buf->offset, p->page, p->offset, size, IV)) { -		printk(KERN_ERR "loop: transfer error block %ld\n", +		printk_ratelimited(KERN_ERR "loop: transfer error block %ld\n",  		       page->index);  		size = -EINVAL;  	} @@ -392,20 +393,20 @@ do_lo_receive(struct loop_device *lo,  static int  lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)  { -	struct bio_vec *bvec; +	struct bio_vec bvec; +	struct bvec_iter iter;  	ssize_t s; -	int i; -	bio_for_each_segment(bvec, bio, i) { -		s = do_lo_receive(lo, bvec, bsize, pos); +	bio_for_each_segment(bvec, bio, iter) { +		s = do_lo_receive(lo, &bvec, bsize, pos);  		if (s < 0)  			return s; -		if (s != bvec->bv_len) { +		if (s != bvec.bv_len) {  			zero_fill_bio(bio);  			break;  		} -		pos += bvec->bv_len; +		pos += bvec.bv_len;  	}  	return 0;  } @@ -415,7 +416,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)  	loff_t pos;  	int ret; -	pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset; +	pos = ((loff_t) bio->bi_iter.bi_sector << 9) + lo->lo_offset;  	if (bio_rw(bio) == WRITE) {  		struct file *file = lo->lo_backing_file; @@ -444,7 +445,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)  				goto out;  			}  			ret = file->f_op->fallocate(file, mode, pos, -						    bio->bi_size); +						    bio->bi_iter.bi_size);  			if (unlikely(ret && ret != -EINVAL &&  				     ret != -EOPNOTSUPP))  				ret = -EIO; @@ -547,7 +548,7 @@ static int loop_thread(void *data)  	struct loop_device *lo = data;  	struct bio *bio; -	set_user_nice(current, -20); +	set_user_nice(current, MIN_NICE);  	while (!kthread_should_stop() || !bio_list_empty(&lo->lo_bio_list)) { @@ -798,7 +799,7 @@ static void loop_config_discard(struct loop_device *lo)  	/*  	 * We use punch hole to reclaim the free space used by the -	 * image a.k.a. discard. However we do support discard if +	 * image a.k.a. discard. However we do not support discard if  	 * encryption is enabled, because it may give an attacker  	 * useful information.  	 */ @@ -894,13 +895,6 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,  	bio_list_init(&lo->lo_bio_list); -	/* -	 * set queue make_request_fn, and add limits based on lower level -	 * device -	 */ -	blk_queue_make_request(lo->lo_queue, loop_make_request); -	lo->lo_queue->queuedata = lo; -  	if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync)  		blk_queue_flush(lo->lo_queue, REQ_FLUSH); @@ -1618,6 +1612,8 @@ static int loop_add(struct loop_device **l, int i)  	if (!lo)  		goto out; +	lo->lo_state = Lo_unbound; +  	/* allocate id, if @id >= 0, we're requesting that specific id */  	if (i >= 0) {  		err = idr_alloc(&loop_index_idr, lo, i, i + 1, GFP_KERNEL); @@ -1633,7 +1629,13 @@ static int loop_add(struct loop_device **l, int i)  	err = -ENOMEM;  	lo->lo_queue = blk_alloc_queue(GFP_KERNEL);  	if (!lo->lo_queue) -		goto out_free_dev; +		goto out_free_idr; + +	/* +	 * set queue make_request_fn +	 */ +	blk_queue_make_request(lo->lo_queue, loop_make_request); +	lo->lo_queue->queuedata = lo;  	disk = lo->lo_disk = alloc_disk(1 << part_shift);  	if (!disk) @@ -1678,6 +1680,8 @@ static int loop_add(struct loop_device **l, int i)  out_free_queue:  	blk_cleanup_queue(lo->lo_queue); +out_free_idr: +	idr_remove(&loop_index_idr, i);  out_free_dev:  	kfree(lo);  out: @@ -1741,7 +1745,7 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data)  	if (err < 0)  		err = loop_add(&lo, MINOR(dev) >> part_shift);  	if (err < 0) -		kobj = ERR_PTR(err); +		kobj = NULL;  	else  		kobj = get_disk(lo->lo_disk);  	mutex_unlock(&loop_index_mutex);  | 
