2436 lines · 59.6 KB · C
RawDownload
/* *  linux/drivers/block/loop.c * *  Written by Theodore Ts'o, 3/29/93 * * Copyright 1993 by Theodore Ts'o.  Redistribution of this file is * permitted under the GNU General Public License. * * DES encryption plus some minor changes by Werner Almesberger, 30-MAY-1993 * more DES encryption plus IDEA encryption by Nicholas J. Leon, June 20, 1996 * * Modularized and updated for 1.1.16 kernel - Mitch Dsouza 28th May 1994 * Adapted for 1.3.59 kernel - Andries Brouwer, 1 Feb 1996 * * Fixed do_loop_request() re-entrancy - Vincent.Renardias@waw.com Mar 20, 1997 * * Added devfs support - Richard Gooch <rgooch@atnf.csiro.au> 16-Jan-1998 * * Handle sparse backing files correctly - Kenn Humborg, Jun 28, 1998 * * Loadable modules and other fixes by AK, 1998 * * Make real block number available to downstream transfer functions, enables * CBC (and relatives) mode encryption requiring unique IVs per data block. * Reed H. Petty, rhp@draper.net * * Maximum number of loop devices now dynamic via max_loop module parameter. * Russell Kroll <rkroll@exploits.org> 19990701 * * Maximum number of loop devices when compiled-in now selectable by passing * max_loop=<1-255> to the kernel on boot. * Erik I. Bolsø, <eriki@himolde.no>, Oct 31, 1999 * * Completely rewrite request handling to be make_request_fn style and * non blocking, pushing work to a helper thread. Lots of fixes from * Al Viro too. * Jens Axboe <axboe@suse.de>, Nov 2000 * * Support up to 256 loop devices * Heinz Mauelshagen <mge@sistina.com>, Feb 2002 * * Support for falling back on the write file operation when the address space * operations write_begin is not available on the backing filesystem. * Anton Altaparmakov, 16 Feb 2005 * * Still To Fix: * - Advisory locking is ignored here. * - Should use an own CAP_* category instead of CAP_SYS_ADMIN * */ #include <linux/module.h>#include <linux/moduleparam.h>#include <linux/sched.h>#include <linux/fs.h>#include <linux/file.h>#include <linux/stat.h>#include <linux/errno.h>#include <linux/major.h>#include <linux/wait.h>#include <linux/blkdev.h>#include <linux/blkpg.h>#include <linux/init.h>#include <linux/swap.h>#include <linux/slab.h>#include <linux/compat.h>#include <linux/suspend.h>#include <linux/freezer.h>#include <linux/mutex.h>#include <linux/writeback.h>#include <linux/completion.h>#include <linux/highmem.h>#include <linux/kthread.h>#include <linux/splice.h>#include <linux/sysfs.h>#include <linux/miscdevice.h>#include <linux/falloc.h>#include <linux/uio.h>#include <linux/ioprio.h>#include <linux/blk-cgroup.h> #include "loop.h" #include <linux/uaccess.h> static DEFINE_IDR(loop_index_idr);static DEFINE_MUTEX(loop_ctl_mutex); static int max_part;static int part_shift; static int transfer_xor(struct loop_device *lo, int cmd,			struct page *raw_page, unsigned raw_off,			struct page *loop_page, unsigned loop_off,			int size, sector_t real_block){	char *raw_buf = kmap_atomic(raw_page) + raw_off;	char *loop_buf = kmap_atomic(loop_page) + loop_off;	char *in, *out, *key;	int i, keysize; 	if (cmd == READ) {		in = raw_buf;		out = loop_buf;	} else {		in = loop_buf;		out = raw_buf;	} 	key = lo->lo_encrypt_key;	keysize = lo->lo_encrypt_key_size;	for (i = 0; i < size; i++)		*out++ = *in++ ^ key[(i & 511) % keysize]; 	kunmap_atomic(loop_buf);	kunmap_atomic(raw_buf);	cond_resched();	return 0;} static int xor_init(struct loop_device *lo, const struct loop_info64 *info){	if (unlikely(info->lo_encrypt_key_size <= 0))		return -EINVAL;	return 0;} static struct loop_func_table none_funcs = {	.number = LO_CRYPT_NONE,};  static struct loop_func_table xor_funcs = {	.number = LO_CRYPT_XOR,	.transfer = transfer_xor,	.init = xor_init};  /* xfer_funcs[0] is special - its release function is never called */static struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = {	&none_funcs,	&xor_funcs}; static loff_t get_size(loff_t offset, loff_t sizelimit, struct file *file){	loff_t loopsize; 	/* Compute loopsize in bytes */	loopsize = i_size_read(file->f_mapping->host);	if (offset > 0)		loopsize -= offset;	/* offset is beyond i_size, weird but possible */	if (loopsize < 0)		return 0; 	if (sizelimit > 0 && sizelimit < loopsize)		loopsize = sizelimit;	/*	 * Unfortunately, if we want to do I/O on the device,	 * the number of 512-byte sectors has to fit into a sector_t.	 */	return loopsize >> 9;} static loff_t get_loop_size(struct loop_device *lo, struct file *file){	return get_size(lo->lo_offset, lo->lo_sizelimit, file);} static void __loop_update_dio(struct loop_device *lo, bool dio){	struct file *file = lo->lo_backing_file;	struct address_space *mapping = file->f_mapping;	struct inode *inode = mapping->host;	unsigned short sb_bsize = 0;	unsigned dio_align = 0;	bool use_dio; 	if (inode->i_sb->s_bdev) {		sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev);		dio_align = sb_bsize - 1;	} 	/*	 * We support direct I/O only if lo_offset is aligned with the	 * logical I/O size of backing device, and the logical block	 * size of loop is bigger than the backing device's and the loop	 * needn't transform transfer.	 *	 * TODO: the above condition may be loosed in the future, and	 * direct I/O may be switched runtime at that time because most	 * of requests in sane applications should be PAGE_SIZE aligned	 */	if (dio) {		if (queue_logical_block_size(lo->lo_queue) >= sb_bsize &&				!(lo->lo_offset & dio_align) &&				mapping->a_ops->direct_IO &&				!lo->transfer)			use_dio = true;		else			use_dio = false;	} else {		use_dio = false;	} 	if (lo->use_dio == use_dio)		return; 	/* flush dirty pages before changing direct IO */	vfs_fsync(file, 0); 	/*	 * The flag of LO_FLAGS_DIRECT_IO is handled similarly with	 * LO_FLAGS_READ_ONLY, both are set from kernel, and losetup	 * will get updated by ioctl(LOOP_GET_STATUS)	 */	if (lo->lo_state == Lo_bound)		blk_mq_freeze_queue(lo->lo_queue);	lo->use_dio = use_dio;	if (use_dio) {		blk_queue_flag_clear(QUEUE_FLAG_NOMERGES, lo->lo_queue);		lo->lo_flags |= LO_FLAGS_DIRECT_IO;	} else {		blk_queue_flag_set(QUEUE_FLAG_NOMERGES, lo->lo_queue);		lo->lo_flags &= ~LO_FLAGS_DIRECT_IO;	}	if (lo->lo_state == Lo_bound)		blk_mq_unfreeze_queue(lo->lo_queue);} /** * loop_validate_block_size() - validates the passed in block size * @bsize: size to validate */static intloop_validate_block_size(unsigned short bsize){	if (bsize < 512 || bsize > PAGE_SIZE || !is_power_of_2(bsize))		return -EINVAL; 	return 0;} /** * loop_set_size() - sets device size and notifies userspace * @lo: struct loop_device to set the size for * @size: new size of the loop device * * Callers must validate that the size passed into this function fits into * a sector_t, eg using loop_validate_size() */static void loop_set_size(struct loop_device *lo, loff_t size){	struct block_device *bdev = lo->lo_device; 	bd_set_nr_sectors(bdev, size); 	if (!set_capacity_revalidate_and_notify(lo->lo_disk, size, false))		kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);} static inline intlo_do_transfer(struct loop_device *lo, int cmd,	       struct page *rpage, unsigned roffs,	       struct page *lpage, unsigned loffs,	       int size, sector_t rblock){	int ret; 	ret = lo->transfer(lo, cmd, rpage, roffs, lpage, loffs, size, rblock);	if (likely(!ret))		return 0; 	printk_ratelimited(KERN_ERR		"loop: Transfer error at byte offset %llu, length %i.\n",		(unsigned long long)rblock << 9, size);	return ret;} static int lo_write_bvec(struct file *file, struct bio_vec *bvec, loff_t *ppos){	struct iov_iter i;	ssize_t bw; 	iov_iter_bvec(&i, WRITE, bvec, 1, bvec->bv_len); 	file_start_write(file);	bw = vfs_iter_write(file, &i, ppos, 0);	file_end_write(file); 	if (likely(bw ==  bvec->bv_len))		return 0; 	printk_ratelimited(KERN_ERR		"loop: Write error at byte offset %llu, length %i.\n",		(unsigned long long)*ppos, bvec->bv_len);	if (bw >= 0)		bw = -EIO;	return bw;} static int lo_write_simple(struct loop_device *lo, struct request *rq,		loff_t pos){	struct bio_vec bvec;	struct req_iterator iter;	int ret = 0; 	rq_for_each_segment(bvec, rq, iter) {		ret = lo_write_bvec(lo->lo_backing_file, &bvec, &pos);		if (ret < 0)			break;		cond_resched();	} 	return ret;} /* * This is the slow, transforming version that needs to double buffer the * data as it cannot do the transformations in place without having direct * access to the destination pages of the backing file. */static int lo_write_transfer(struct loop_device *lo, struct request *rq,		loff_t pos){	struct bio_vec bvec, b;	struct req_iterator iter;	struct page *page;	int ret = 0; 	page = alloc_page(GFP_NOIO);	if (unlikely(!page))		return -ENOMEM; 	rq_for_each_segment(bvec, rq, iter) {		ret = lo_do_transfer(lo, WRITE, page, 0, bvec.bv_page,			bvec.bv_offset, bvec.bv_len, pos >> 9);		if (unlikely(ret))			break; 		b.bv_page = page;		b.bv_offset = 0;		b.bv_len = bvec.bv_len;		ret = lo_write_bvec(lo->lo_backing_file, &b, &pos);		if (ret < 0)			break;	} 	__free_page(page);	return ret;} static int lo_read_simple(struct loop_device *lo, struct request *rq,		loff_t pos){	struct bio_vec bvec;	struct req_iterator iter;	struct iov_iter i;	ssize_t len; 	rq_for_each_segment(bvec, rq, iter) {		iov_iter_bvec(&i, READ, &bvec, 1, bvec.bv_len);		len = vfs_iter_read(lo->lo_backing_file, &i, &pos, 0);		if (len < 0)			return len; 		flush_dcache_page(bvec.bv_page); 		if (len != bvec.bv_len) {			struct bio *bio; 			__rq_for_each_bio(bio, rq)				zero_fill_bio(bio);			break;		}		cond_resched();	} 	return 0;} static int lo_read_transfer(struct loop_device *lo, struct request *rq,		loff_t pos){	struct bio_vec bvec, b;	struct req_iterator iter;	struct iov_iter i;	struct page *page;	ssize_t len;	int ret = 0; 	page = alloc_page(GFP_NOIO);	if (unlikely(!page))		return -ENOMEM; 	rq_for_each_segment(bvec, rq, iter) {		loff_t offset = pos; 		b.bv_page = page;		b.bv_offset = 0;		b.bv_len = bvec.bv_len; 		iov_iter_bvec(&i, READ, &b, 1, b.bv_len);		len = vfs_iter_read(lo->lo_backing_file, &i, &pos, 0);		if (len < 0) {			ret = len;			goto out_free_page;		} 		ret = lo_do_transfer(lo, READ, page, 0, bvec.bv_page,			bvec.bv_offset, len, offset >> 9);		if (ret)			goto out_free_page; 		flush_dcache_page(bvec.bv_page); 		if (len != bvec.bv_len) {			struct bio *bio; 			__rq_for_each_bio(bio, rq)				zero_fill_bio(bio);			break;		}	} 	ret = 0;out_free_page:	__free_page(page);	return ret;} static int lo_fallocate(struct loop_device *lo, struct request *rq, loff_t pos,			int mode){	/*	 * We use fallocate to manipulate the space mappings used by the image	 * a.k.a. discard/zerorange. However we do not support this if	 * encryption is enabled, because it may give an attacker useful	 * information.	 */	struct file *file = lo->lo_backing_file;	struct request_queue *q = lo->lo_queue;	int ret; 	mode |= FALLOC_FL_KEEP_SIZE; 	if (!blk_queue_discard(q)) {		ret = -EOPNOTSUPP;		goto out;	} 	ret = file->f_op->fallocate(file, mode, pos, blk_rq_bytes(rq));	if (unlikely(ret && ret != -EINVAL && ret != -EOPNOTSUPP))		ret = -EIO; out:	return ret;} static int lo_req_flush(struct loop_device *lo, struct request *rq){	struct file *file = lo->lo_backing_file;	int ret = vfs_fsync(file, 0);	if (unlikely(ret && ret != -EINVAL))		ret = -EIO; 	return ret;} static void lo_complete_rq(struct request *rq){	struct loop_cmd *cmd = blk_mq_rq_to_pdu(rq);	blk_status_t ret = BLK_STS_OK; 	if (!cmd->use_aio || cmd->ret < 0 || cmd->ret == blk_rq_bytes(rq) ||	    req_op(rq) != REQ_OP_READ) {		if (cmd->ret < 0)			ret = errno_to_blk_status(cmd->ret);		goto end_io;	} 	/*	 * Short READ - if we got some data, advance our request and	 * retry it. If we got no data, end the rest with EIO.	 */	if (cmd->ret) {		blk_update_request(rq, BLK_STS_OK, cmd->ret);		cmd->ret = 0;		blk_mq_requeue_request(rq, true);	} else {		if (cmd->use_aio) {			struct bio *bio = rq->bio; 			while (bio) {				zero_fill_bio(bio);				bio = bio->bi_next;			}		}		ret = BLK_STS_IOERR;end_io:

Lines 1–500 of 2436.