/* * 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 "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; /* * Transfer functions */static int transfer_none(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; if (cmd == READ) memcpy(loop_buf, raw_buf, size); else memcpy(raw_buf, loop_buf, size); kunmap_atomic(loop_buf); kunmap_atomic(raw_buf); cond_resched(); return 0;} 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, .transfer = transfer_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){ if (unlikely(!lo->transfer)) return 0; return lo->transfer(lo, cmd, rpage, roffs, lpage, loffs, size, rblock);} /** * __do_lo_send_write - helper for writing data to a loop device * * This helper just factors out common code between do_lo_send_direct_write() * and do_lo_send_write(). */static int __do_lo_send_write(struct file *file, u8 *buf, const int len, loff_t pos){ ssize_t bw; mm_segment_t old_fs = get_fs(); file_start_write(file); set_fs(get_ds()); bw = file->f_op->write(file, buf, len, &pos); set_fs(old_fs); file_end_write(file); if (likely(bw == len)) return 0; printk(KERN_ERR "loop: Write error at byte offset %llu, length %i.\n", (unsigned long long)pos, len); if (bw >= 0) bw = -EIO; return bw;} /** * do_lo_send_direct_write - helper for writing data to a loop device * * This is the fast, non-transforming version that does not need double * buffering. */static int do_lo_send_direct_write(struct loop_device *lo, struct bio_vec *bvec, loff_t pos, struct page *page){ ssize_t bw = __do_lo_send_write(lo->lo_backing_file, kmap(bvec->bv_page) + bvec->bv_offset, bvec->bv_len, pos); kunmap(bvec->bv_page); cond_resched(); return bw;} /** * do_lo_send_write - helper for writing data to a loop device * * 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 do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec, loff_t pos, struct page *page){ int ret = lo_do_transfer(lo, WRITE, page, 0, bvec->bv_page, bvec->bv_offset, bvec->bv_len, pos >> 9); if (likely(!ret)) 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, " "length %i.\n", (unsigned long long)pos, bvec->bv_len); if (ret > 0) ret = -EIO; return ret;} 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 bvec_iter iter; struct page *page = NULL; int ret = 0; if (lo->transfer != transfer_none) { page = alloc_page(GFP_NOIO | __GFP_HIGHMEM); if (unlikely(!page)) goto fail; kmap(page); do_lo_send = do_lo_send_write; } else { do_lo_send = do_lo_send_direct_write; } bio_for_each_segment(bvec, bio, iter) { ret = do_lo_send(lo, &bvec, pos, page); if (ret < 0) break; pos += bvec.bv_len; } if (page) { kunmap(page); __free_page(page); }out: return ret;fail: printk(KERN_ERR "loop: Failed to allocate temporary page for write.\n"); ret = -ENOMEM; goto out;} struct lo_read_data { struct loop_device *lo; struct page *page; unsigned offset; int bsize;}; static intlo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, struct splice_desc *sd){ struct lo_read_data *p = sd->u.data; struct loop_device *lo = p->lo; struct page *page = buf->page; sector_t IV; int size; IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) + (buf->offset >> 9); size = sd->len; if (size > p->bsize) 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", page->index); size = -EINVAL; } flush_dcache_page(p->page); if (size > 0) p->offset += size; return size;} static intlo_direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc *sd){ return __splice_from_pipe(pipe, sd, lo_splice_actor);} static ssize_tdo_lo_receive(struct loop_device *lo, struct bio_vec *bvec, int bsize, loff_t pos){ struct lo_read_data cookie; struct splice_desc sd; struct file *file; ssize_t retval; cookie.lo = lo; cookie.page = bvec->bv_page; cookie.offset = bvec->bv_offset; cookie.bsize = bsize; sd.len = 0; sd.total_len = bvec->bv_len; sd.flags = 0; sd.pos = pos; sd.u.data = &cookie; file = lo->lo_backing_file; retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor); return retval;} static intlo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos){ struct bio_vec bvec; struct bvec_iter iter; ssize_t s; 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) { zero_fill_bio(bio); break; } pos += bvec.bv_len; } return 0;} static int do_bio_filebacked(struct loop_device *lo, struct bio *bio){ loff_t pos; int ret; pos = ((loff_t) bio->bi_iter.bi_sector << 9) + lo->lo_offset; if (bio_rw(bio) == WRITE) { struct file *file = lo->lo_backing_file; if (bio->bi_rw & REQ_FLUSH) { ret = vfs_fsync(file, 0); if (unlikely(ret && ret != -EINVAL)) { ret = -EIO; goto out; } } /* * 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; } ret = lo_send(lo, bio, pos); 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); out: return ret;} /* * Add bio to back of pending list */static void loop_add_bio(struct loop_device *lo, struct bio *bio){ lo->lo_bio_count++; bio_list_add(&lo->lo_bio_list, bio);} /* * Grab first pending buffer */static struct bio *loop_get_bio(struct loop_device *lo){ lo->lo_bio_count--; return bio_list_pop(&lo->lo_bio_list);} static void loop_make_request(struct request_queue *q, struct bio *old_bio){ struct loop_device *lo = q->queuedata; int rw = bio_rw(old_bio); if (rw == READA) rw = READ; BUG_ON(!lo || (rw != READ && rw != WRITE)); spin_lock_irq(&lo->lo_lock); if (lo->lo_state != Lo_bound) goto out; if (unlikely(rw == WRITE && (lo->lo_flags & LO_FLAGS_READ_ONLY)))Lines 1–500 of 1929. Load more
/* * 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 "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; /* * Transfer functions */ static int transfer_none(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; if (cmd == READ) memcpy(loop_buf, raw_buf, size); else memcpy(raw_buf, loop_buf, size); kunmap_atomic(loop_buf); kunmap_atomic(raw_buf); cond_resched(); return 0; } 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, .transfer = transfer_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 int figure_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 int lo_do_transfer(struct loop_device *lo, int cmd, struct page *rpage, unsigned roffs, struct page *lpage, unsigned loffs, int size, sector_t rblock) { if (unlikely(!lo->transfer)) return 0; return lo->transfer(lo, cmd, rpage, roffs, lpage, loffs, size, rblock); } /** * __do_lo_send_write - helper for writing data to a loop device * * This helper just factors out common code between do_lo_send_direct_write() * and do_lo_send_write(). */ static int __do_lo_send_write(struct file *file, u8 *buf, const int len, loff_t pos) { ssize_t bw; mm_segment_t old_fs = get_fs(); file_start_write(file); set_fs(get_ds()); bw = file->f_op->write(file, buf, len, &pos); set_fs(old_fs); file_end_write(file); if (likely(bw == len)) return 0; printk(KERN_ERR "loop: Write error at byte offset %llu, length %i.\n", (unsigned long long)pos, len); if (bw >= 0) bw = -EIO; return bw; } /** * do_lo_send_direct_write - helper for writing data to a loop device * * This is the fast, non-transforming version that does not need double * buffering. */ static int do_lo_send_direct_write(struct loop_device *lo, struct bio_vec *bvec, loff_t pos, struct page *page) { ssize_t bw = __do_lo_send_write(lo->lo_backing_file, kmap(bvec->bv_page) + bvec->bv_offset, bvec->bv_len, pos); kunmap(bvec->bv_page); cond_resched(); return bw; } /** * do_lo_send_write - helper for writing data to a loop device * * 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 do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec, loff_t pos, struct page *page) { int ret = lo_do_transfer(lo, WRITE, page, 0, bvec->bv_page, bvec->bv_offset, bvec->bv_len, pos >> 9); if (likely(!ret)) 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, " "length %i.\n", (unsigned long long)pos, bvec->bv_len); if (ret > 0) ret = -EIO; return ret; } 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 bvec_iter iter; struct page *page = NULL; int ret = 0; if (lo->transfer != transfer_none) { page = alloc_page(GFP_NOIO | __GFP_HIGHMEM); if (unlikely(!page)) goto fail; kmap(page); do_lo_send = do_lo_send_write; } else { do_lo_send = do_lo_send_direct_write; } bio_for_each_segment(bvec, bio, iter) { ret = do_lo_send(lo, &bvec, pos, page); if (ret < 0) break; pos += bvec.bv_len; } if (page) { kunmap(page); __free_page(page); } out: return ret; fail: printk(KERN_ERR "loop: Failed to allocate temporary page for write.\n"); ret = -ENOMEM; goto out; } struct lo_read_data { struct loop_device *lo; struct page *page; unsigned offset; int bsize; }; static int lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, struct splice_desc *sd) { struct lo_read_data *p = sd->u.data; struct loop_device *lo = p->lo; struct page *page = buf->page; sector_t IV; int size; IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) + (buf->offset >> 9); size = sd->len; if (size > p->bsize) 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", page->index); size = -EINVAL; } flush_dcache_page(p->page); if (size > 0) p->offset += size; return size; } static int lo_direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc *sd) { return __splice_from_pipe(pipe, sd, lo_splice_actor); } static ssize_t do_lo_receive(struct loop_device *lo, struct bio_vec *bvec, int bsize, loff_t pos) { struct lo_read_data cookie; struct splice_desc sd; struct file *file; ssize_t retval; cookie.lo = lo; cookie.page = bvec->bv_page; cookie.offset = bvec->bv_offset; cookie.bsize = bsize; sd.len = 0; sd.total_len = bvec->bv_len; sd.flags = 0; sd.pos = pos; sd.u.data = &cookie; file = lo->lo_backing_file; retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor); return retval; } static int lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos) { struct bio_vec bvec; struct bvec_iter iter; ssize_t s; 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) { zero_fill_bio(bio); break; } pos += bvec.bv_len; } return 0; } static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) { loff_t pos; int ret; pos = ((loff_t) bio->bi_iter.bi_sector << 9) + lo->lo_offset; if (bio_rw(bio) == WRITE) { struct file *file = lo->lo_backing_file; if (bio->bi_rw & REQ_FLUSH) { ret = vfs_fsync(file, 0); if (unlikely(ret && ret != -EINVAL)) { ret = -EIO; goto out; } } /* * 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; } ret = lo_send(lo, bio, pos); 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); out: return ret; } /* * Add bio to back of pending list */ static void loop_add_bio(struct loop_device *lo, struct bio *bio) { lo->lo_bio_count++; bio_list_add(&lo->lo_bio_list, bio); } /* * Grab first pending buffer */ static struct bio *loop_get_bio(struct loop_device *lo) { lo->lo_bio_count--; return bio_list_pop(&lo->lo_bio_list); } static void loop_make_request(struct request_queue *q, struct bio *old_bio) { struct loop_device *lo = q->queuedata; int rw = bio_rw(old_bio); if (rw == READA) rw = READ; BUG_ON(!lo || (rw != READ && rw != WRITE)); spin_lock_irq(&lo->lo_lock); if (lo->lo_state != Lo_bound) goto out; if (unlikely(rw == WRITE && (lo->lo_flags & LO_FLAGS_READ_ONLY)))