aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/loop.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-28 16:16:07 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-28 16:16:07 -0500
commitf042fea0da78d9dc077a9c736b33b60eb8f35195 (patch)
treefce1c64a68a8ccd54b36e4d89d3b946a995e9fd2 /drivers/block/loop.c
parentee89f81252179dcbf6cd65bd48299f5e52292d88 (diff)
parentb7a1da695f3fb33d093e6de20b1dfc238e3c9587 (diff)
Merge branch 'for-3.9/drivers' of git://git.kernel.dk/linux-block
Pull block driver bits from Jens Axboe: "After the block IO core bits are in, please grab the driver updates from below as well. It contains: - Fix ancient regression in dac960. Nobody must be using that anymore... - Some good fixes from Guo Ghao for loop, fixing both potential oopses and deadlocks. - Improve mtip32xx for NUMA systems, by being a bit more clever in distributing work. - Add IBM RamSan 70/80 driver. A second round of fixes for that is pending, that will come in through for-linus during the 3.9 cycle as per usual. - A few xen-blk{back,front} fixes from Konrad and Roger. - Other minor fixes and improvements." * 'for-3.9/drivers' of git://git.kernel.dk/linux-block: loopdev: ignore negative offset when calculate loop device size loopdev: remove an user triggerable oops loopdev: move common code into loop_figure_size() loopdev: update block device size in loop_set_status() loopdev: fix a deadlock xen-blkback: use balloon pages for persistent grants xen-blkfront: drop the use of llist_for_each_entry_safe xen/blkback: Don't trust the handle from the frontend. xen-blkback: do not leak mode property block: IBM RamSan 70/80 driver fixes rsxx: add slab.h include to dma.c drivers/block/mtip32xx: add missing GENERIC_HARDIRQS dependency block: remove new __devinit/exit annotations on ramsam driver block: IBM RamSan 70/80 device driver drivers/block/mtip32xx/mtip32xx.c:1726:5: sparse: symbol 'mtip_send_trim' was not declared. Should it be static? drivers/block/mtip32xx/mtip32xx.c:4029:1: sparse: symbol 'mtip_workq_sdbf0' was not declared. Should it be static? dac960: return success instead of -ENOTTY mtip32xx: add trim support mtip32xx: Add workqueue and NUMA support block: delete super ancient PC-XT driver for 1980's hardware
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r--drivers/block/loop.c61
1 files changed, 29 insertions, 32 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index f47dccbda1d4..747bb2af69dc 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -162,12 +162,13 @@ static struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = {
162 162
163static loff_t get_size(loff_t offset, loff_t sizelimit, struct file *file) 163static loff_t get_size(loff_t offset, loff_t sizelimit, struct file *file)
164{ 164{
165 loff_t size, loopsize; 165 loff_t loopsize;
166 166
167 /* Compute loopsize in bytes */ 167 /* Compute loopsize in bytes */
168 size = i_size_read(file->f_mapping->host); 168 loopsize = i_size_read(file->f_mapping->host);
169 loopsize = size - offset; 169 if (offset > 0)
170 /* offset is beyond i_size, wierd but possible */ 170 loopsize -= offset;
171 /* offset is beyond i_size, weird but possible */
171 if (loopsize < 0) 172 if (loopsize < 0)
172 return 0; 173 return 0;
173 174
@@ -190,6 +191,7 @@ figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit)
190{ 191{
191 loff_t size = get_size(offset, sizelimit, lo->lo_backing_file); 192 loff_t size = get_size(offset, sizelimit, lo->lo_backing_file);
192 sector_t x = (sector_t)size; 193 sector_t x = (sector_t)size;
194 struct block_device *bdev = lo->lo_device;
193 195
194 if (unlikely((loff_t)x != size)) 196 if (unlikely((loff_t)x != size))
195 return -EFBIG; 197 return -EFBIG;
@@ -198,6 +200,9 @@ figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit)
198 if (lo->lo_sizelimit != sizelimit) 200 if (lo->lo_sizelimit != sizelimit)
199 lo->lo_sizelimit = sizelimit; 201 lo->lo_sizelimit = sizelimit;
200 set_capacity(lo->lo_disk, x); 202 set_capacity(lo->lo_disk, x);
203 bd_set_size(bdev, (loff_t)get_capacity(bdev->bd_disk) << 9);
204 /* let user-space know about the new size */
205 kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);
201 return 0; 206 return 0;
202} 207}
203 208
@@ -1091,10 +1096,10 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
1091 return err; 1096 return err;
1092 1097
1093 if (lo->lo_offset != info->lo_offset || 1098 if (lo->lo_offset != info->lo_offset ||
1094 lo->lo_sizelimit != info->lo_sizelimit) { 1099 lo->lo_sizelimit != info->lo_sizelimit)
1095 if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) 1100 if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit))
1096 return -EFBIG; 1101 return -EFBIG;
1097 } 1102
1098 loop_config_discard(lo); 1103 loop_config_discard(lo);
1099 1104
1100 memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE); 1105 memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE);
@@ -1271,28 +1276,10 @@ loop_get_status64(struct loop_device *lo, struct loop_info64 __user *arg) {
1271 1276
1272static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev) 1277static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev)
1273{ 1278{
1274 int err;
1275 sector_t sec;
1276 loff_t sz;
1277
1278 err = -ENXIO;
1279 if (unlikely(lo->lo_state != Lo_bound)) 1279 if (unlikely(lo->lo_state != Lo_bound))
1280 goto out; 1280 return -ENXIO;
1281 err = figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit);
1282 if (unlikely(err))
1283 goto out;
1284 sec = get_capacity(lo->lo_disk);
1285 /* the width of sector_t may be narrow for bit-shift */
1286 sz = sec;
1287 sz <<= 9;
1288 mutex_lock(&bdev->bd_mutex);
1289 bd_set_size(bdev, sz);
1290 /* let user-space know about the new size */
1291 kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);
1292 mutex_unlock(&bdev->bd_mutex);
1293 1281
1294 out: 1282 return figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit);
1295 return err;
1296} 1283}
1297 1284
1298static int lo_ioctl(struct block_device *bdev, fmode_t mode, 1285static int lo_ioctl(struct block_device *bdev, fmode_t mode,
@@ -1845,11 +1832,15 @@ static int __init loop_init(void)
1845 max_part = (1UL << part_shift) - 1; 1832 max_part = (1UL << part_shift) - 1;
1846 } 1833 }
1847 1834
1848 if ((1UL << part_shift) > DISK_MAX_PARTS) 1835 if ((1UL << part_shift) > DISK_MAX_PARTS) {
1849 return -EINVAL; 1836 err = -EINVAL;
1837 goto misc_out;
1838 }
1850 1839
1851 if (max_loop > 1UL << (MINORBITS - part_shift)) 1840 if (max_loop > 1UL << (MINORBITS - part_shift)) {
1852 return -EINVAL; 1841 err = -EINVAL;
1842 goto misc_out;
1843 }
1853 1844
1854 /* 1845 /*
1855 * If max_loop is specified, create that many devices upfront. 1846 * If max_loop is specified, create that many devices upfront.
@@ -1867,8 +1858,10 @@ static int __init loop_init(void)
1867 range = 1UL << MINORBITS; 1858 range = 1UL << MINORBITS;
1868 } 1859 }
1869 1860
1870 if (register_blkdev(LOOP_MAJOR, "loop")) 1861 if (register_blkdev(LOOP_MAJOR, "loop")) {
1871 return -EIO; 1862 err = -EIO;
1863 goto misc_out;
1864 }
1872 1865
1873 blk_register_region(MKDEV(LOOP_MAJOR, 0), range, 1866 blk_register_region(MKDEV(LOOP_MAJOR, 0), range,
1874 THIS_MODULE, loop_probe, NULL, NULL); 1867 THIS_MODULE, loop_probe, NULL, NULL);
@@ -1881,6 +1874,10 @@ static int __init loop_init(void)
1881 1874
1882 printk(KERN_INFO "loop: module loaded\n"); 1875 printk(KERN_INFO "loop: module loaded\n");
1883 return 0; 1876 return 0;
1877
1878misc_out:
1879 misc_deregister(&loop_misc);
1880 return err;
1884} 1881}
1885 1882
1886static int loop_exit_cb(int id, void *ptr, void *data) 1883static int loop_exit_cb(int id, void *ptr, void *data)