1891 lines · 45.9 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 "loop.h" #include <asm/uaccess.h> static DEFINE_IDR(loop_index_idr);static DEFINE_MUTEX(loop_index_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 intfigure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit){	loff_t size = get_size(offset, sizelimit, lo->lo_backing_file);	sector_t x = (sector_t)size;	struct block_device *bdev = lo->lo_device; 	if (unlikely((loff_t)x != size))		return -EFBIG;	if (lo->lo_offset != offset)		lo->lo_offset = offset;	if (lo->lo_sizelimit != sizelimit)		lo->lo_sizelimit = sizelimit;	set_capacity(lo->lo_disk, x);	bd_set_size(bdev, (loff_t)get_capacity(bdev->bd_disk) << 9);	/* let user-space know about the new size */	kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);	return 0;} 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, ITER_BVEC, bvec, 1, bvec->bv_len); 	file_start_write(file);	bw = vfs_iter_write(file, &i, ppos);	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, ITER_BVEC, &bvec, 1, bvec.bv_len);		len = vfs_iter_read(lo->lo_backing_file, &i, &pos);		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, ITER_BVEC, &b, 1, b.bv_len);		len = vfs_iter_read(lo->lo_backing_file, &i, &pos);		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_discard(struct loop_device *lo, struct request *rq, loff_t 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.	 */	struct file *file = lo->lo_backing_file;	int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE;	int ret; 	if ((!file->f_op->fallocate) || lo->lo_encrypt_key_size) {		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 int do_req_filebacked(struct loop_device *lo, struct request *rq){	loff_t pos;	int ret; 	pos = ((loff_t) blk_rq_pos(rq) << 9) + lo->lo_offset; 	if (rq->cmd_flags & REQ_WRITE) {		if (rq->cmd_flags & REQ_FLUSH)			ret = lo_req_flush(lo, rq);		else if (rq->cmd_flags & REQ_DISCARD)			ret = lo_discard(lo, rq, pos);		else if (lo->transfer)			ret = lo_write_transfer(lo, rq, pos);		else			ret = lo_write_simple(lo, rq, pos); 	} else {		if (lo->transfer)			ret = lo_read_transfer(lo, rq, pos);		else			ret = lo_read_simple(lo, rq, pos);	} 	return ret;} struct switch_request {	struct file *file;	struct completion wait;}; /* * Do the actual switch; called from the BIO completion routine */static void do_loop_switch(struct loop_device *lo, struct switch_request *p){	struct file *file = p->file;	struct file *old_file = lo->lo_backing_file;	struct address_space *mapping; 	/* if no new file, only flush of queued bios requested */	if (!file)		return; 	mapping = file->f_mapping;	mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask);	lo->lo_backing_file = file;	lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ?		mapping->host->i_bdev->bd_block_size : PAGE_SIZE;	lo->old_gfp_mask = mapping_gfp_mask(mapping);	mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));} /* * loop_switch performs the hard work of switching a backing store. * First it needs to flush existing IO, it does this by sending a magic * BIO down the pipe. The completion of this BIO does the actual switch. */static int loop_switch(struct loop_device *lo, struct file *file){	struct switch_request w; 	w.file = file; 	/* freeze queue and wait for completion of scheduled requests */	blk_mq_freeze_queue(lo->lo_queue); 	/* do the switch action */	do_loop_switch(lo, &w); 	/* unfreeze */	blk_mq_unfreeze_queue(lo->lo_queue); 	return 0;} /* * Helper to flush the IOs in loop, but keeping loop thread running */static int loop_flush(struct loop_device *lo){	return loop_switch(lo, NULL);} static void loop_reread_partitions(struct loop_device *lo,				   struct block_device *bdev){	int rc; 	/*	 * bd_mutex has been held already in release path, so don't	 * acquire it if this function is called in such case.	 *	 * If the reread partition isn't from release path, lo_refcnt	 * must be at least one and it can only become zero when the	 * current holder is released.	 */	if (!atomic_read(&lo->lo_refcnt))		rc = __blkdev_reread_part(bdev);	else		rc = blkdev_reread_part(bdev);	if (rc)		pr_warn("%s: partition scan of loop%d (%s) failed (rc=%d)\n",			__func__, lo->lo_number, lo->lo_file_name, rc);} /* * loop_change_fd switched the backing store of a loopback device to

Lines 1–500 of 1891.