Subject: Re: linux-next: manual merge of the block tree with the tree

From: Dave Kleikamp <[email-masked]>
Date: Thu, 07 Nov 2013 13:20:26 -0600

On 11/02/2013 03:50 PM, Dave Kleikamp wrote:
> On 11/01/2013 03:53 PM, Jens Axboe wrote:

>> So we've three immediate options:
>>
>> 1) You base it on top of the block tree
>> 2) I carry the loop updates
>> 3) You hand Stephen a merge patch for the resulting merge of the two
> 
> Attached is a merge patch and the merged loop.c. I'm having problems
> with the loop driver with both the block and my tree. I'll continue to
> look at that, but everything should build cleanly with this.

Looking back, I obviously rushed the last patch out. This merge patch,
and the resulting loop.c, fix my problem. My code is working with Jens'
block tree now.

Jens,
I ended up replacing a call to bio_iovec_idx() with __bvec_iter_bvec()
since the former was removed. It's not very elegant, but it works. I'm
open to suggestions on a cleaner fix, but it can wait until one or both
of these trees is merged.

I'll be out next week away from internet access, so I'm looking at the
later half of the merge window.

Thanks,
Shaggy
diff --cc drivers/block/loop.c
index e564769,33fde3a..0000000
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@@ -219,48 -218,6 +219,48 @@@ lo_do_transfer(struct loop_device *lo, 
  	return lo->transfer(lo, cmd, rpage, roffs, lpage, loffs, size, rblock);
  }
  
 +#ifdef CONFIG_AIO
 +static void lo_rw_aio_complete(u64 data, long res)
 +{
 +	struct bio *bio = (struct bio *)(uintptr_t)data;
 +
 +	if (res > 0)
 +		res = 0;
 +	else if (res < 0)
 +		res = -EIO;
 +
 +	bio_endio(bio, res);
 +}
 +
 +static int lo_rw_aio(struct loop_device *lo, struct bio *bio)
 +{
 +	struct file *file = lo->lo_backing_file;
 +	struct kiocb *iocb;
 +	unsigned int op;
 +	struct iov_iter iter;
 +	struct bio_vec *bvec;
 +	size_t nr_segs;
- 	loff_t pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset;
++	loff_t pos = ((loff_t) bio->bi_iter.bi_sector << 9) + lo->lo_offset;
 +
 +	iocb = aio_kernel_alloc(GFP_NOIO);
 +	if (!iocb)
 +		return -ENOMEM;
 +
 +	if (bio_rw(bio) & WRITE)
 +		op = IOCB_CMD_WRITE_ITER;
 +	else
 +		op = IOCB_CMD_READ_ITER;
 +
- 	bvec = bio_iovec_idx(bio, bio->bi_idx);
++	bvec = __bvec_iter_bvec(bio->bi_io_vec, bio->bi_iter);
 +	nr_segs = bio_segments(bio);
 +	iov_iter_init_bvec(&iter, bvec, nr_segs, bvec_length(bvec, nr_segs), 0);
 +	aio_kernel_init_rw(iocb, file, iov_iter_count(&iter), pos);
 +	aio_kernel_init_callback(iocb, lo_rw_aio_complete, (u64)(uintptr_t)bio);
 +
 +	return aio_kernel_submit(iocb, op, &iter);
 +}
 +#endif /* CONFIG_AIO */
 +
  /**
   * __do_lo_send_write - helper for writing data to a loop device
   *
@@@ -458,36 -416,53 +459,36 @@@ static int do_bio_filebacked(struct loo
  	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;
 +		ret = lo_send(lo, bio, pos);
 +	} else
 +		ret = lo_receive(lo, bio, lo->lo_blocksize, pos);
  
 -		if (bio->bi_rw & REQ_FLUSH) {
 -			ret = vfs_fsync(file, 0);
 -			if (unlikely(ret && ret != -EINVAL)) {
 -				ret = -EIO;
 -				goto out;
 -			}
 -		}
 +	return ret;
 +}
  
 -		/*
 -		 * We use punch hole to reclaim the free space used by the
 -		 * image a.k.a. discard. However we do not support discard if
 -		 * encryption is enabled, because it may give an attacker
 -		 * useful information.
 -		 */
 -		if (bio->bi_rw & REQ_DISCARD) {
 -			struct file *file = lo->lo_backing_file;
 -			int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE;
 -
 -			if ((!file->f_op->fallocate) ||
 -			    lo->lo_encrypt_key_size) {
 -				ret = -EOPNOTSUPP;
 -				goto out;
 -			}
 -			ret = file->f_op->fallocate(file, mode, pos,
 -						    bio->bi_iter.bi_size);
 -			if (unlikely(ret && ret != -EINVAL &&
 -				     ret != -EOPNOTSUPP))
 -				ret = -EIO;
 -			goto out;
 -		}
 +static int lo_discard(struct loop_device *lo, struct bio *bio)
 +{
 +	struct file *file = lo->lo_backing_file;
 +	int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE;
- 	loff_t pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset;
++	loff_t pos = ((loff_t) bio->bi_iter.bi_sector << 9) + lo->lo_offset;
 +	int ret;
  
 -		ret = lo_send(lo, bio, pos);
 +	/*
 +	 * We use punch hole to reclaim the free space used by the
 +	 * image a.k.a. discard. However we do not support discard if
 +	 * encryption is enabled, because it may give an attacker
 +	 * useful information.
 +	 */
  
 -		if ((bio->bi_rw & REQ_FUA) && !ret) {
 -			ret = vfs_fsync(file, 0);
 -			if (unlikely(ret && ret != -EINVAL))
 -				ret = -EIO;
 -		}
 -	} else
 -		ret = lo_receive(lo, bio, lo->lo_blocksize, pos);
 +	if ((!file->f_op->fallocate) || lo->lo_encrypt_key_size)
 +		return -EOPNOTSUPP;
  
- 	ret = file->f_op->fallocate(file, mode, pos, bio->bi_size);
 -out:
++	ret = file->f_op->fallocate(file, mode, pos, bio->bi_iter.bi_size);
 +	if (unlikely(ret && ret != -EINVAL && ret != -EOPNOTSUPP))
 +		ret = -EIO;
  	return ret;
  }