diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-05 17:27:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-05 17:27:02 -0400 |
commit | 3526dd0c7832f1011a0477cc6d903662bae05ea8 (patch) | |
tree | 22fbac64eb40a0b29bfa4c029695f39b2f591e62 /drivers/block/loop.c | |
parent | dd972f924df6bdbc0ab185a38d5d2361dbc26311 (diff) | |
parent | bc6d65e6dc89c3b7ff78e4ad797117c122ffde8e (diff) |
Merge tag 'for-4.17/block-20180402' of git://git.kernel.dk/linux-block
Pull block layer updates from Jens Axboe:
"It's a pretty quiet round this time, which is nice. This contains:
- series from Bart, cleaning up the way we set/test/clear atomic
queue flags.
- series from Bart, fixing races between gendisk and queue
registration and removal.
- set of bcache fixes and improvements from various folks, by way of
Michael Lyle.
- set of lightnvm updates from Matias, most of it being the 1.2 to
2.0 transition.
- removal of unused DIO flags from Nikolay.
- blk-mq/sbitmap memory ordering fixes from Omar.
- divide-by-zero fix for BFQ from Paolo.
- minor documentation patches from Randy.
- timeout fix from Tejun.
- Alpha "can't write a char atomically" fix from Mikulas.
- set of NVMe fixes by way of Keith.
- bsg and bsg-lib improvements from Christoph.
- a few sed-opal fixes from Jonas.
- cdrom check-disk-change deadlock fix from Maurizio.
- various little fixes, comment fixes, etc from various folks"
* tag 'for-4.17/block-20180402' of git://git.kernel.dk/linux-block: (139 commits)
blk-mq: Directly schedule q->timeout_work when aborting a request
blktrace: fix comment in blktrace_api.h
lightnvm: remove function name in strings
lightnvm: pblk: remove some unnecessary NULL checks
lightnvm: pblk: don't recover unwritten lines
lightnvm: pblk: implement 2.0 support
lightnvm: pblk: implement get log report chunk
lightnvm: pblk: rename ppaf* to addrf*
lightnvm: pblk: check for supported version
lightnvm: implement get log report chunk helpers
lightnvm: make address conversions depend on generic device
lightnvm: add support for 2.0 address format
lightnvm: normalize geometry nomenclature
lightnvm: complete geo structure with maxoc*
lightnvm: add shorten OCSSD version in geo
lightnvm: add minor version to generic geometry
lightnvm: simplify geometry structure
lightnvm: pblk: refactor init/exit sequences
lightnvm: Avoid validation of default op value
lightnvm: centralize permission check for lightnvm ioctl
...
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r-- | drivers/block/loop.c | 77 |
1 files changed, 48 insertions, 29 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index ee62d2d517bf..264abaaff662 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -214,10 +214,10 @@ static void __loop_update_dio(struct loop_device *lo, bool dio) | |||
214 | blk_mq_freeze_queue(lo->lo_queue); | 214 | blk_mq_freeze_queue(lo->lo_queue); |
215 | lo->use_dio = use_dio; | 215 | lo->use_dio = use_dio; |
216 | if (use_dio) { | 216 | if (use_dio) { |
217 | queue_flag_clear_unlocked(QUEUE_FLAG_NOMERGES, lo->lo_queue); | 217 | blk_queue_flag_clear(QUEUE_FLAG_NOMERGES, lo->lo_queue); |
218 | lo->lo_flags |= LO_FLAGS_DIRECT_IO; | 218 | lo->lo_flags |= LO_FLAGS_DIRECT_IO; |
219 | } else { | 219 | } else { |
220 | queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES, lo->lo_queue); | 220 | blk_queue_flag_set(QUEUE_FLAG_NOMERGES, lo->lo_queue); |
221 | lo->lo_flags &= ~LO_FLAGS_DIRECT_IO; | 221 | lo->lo_flags &= ~LO_FLAGS_DIRECT_IO; |
222 | } | 222 | } |
223 | blk_mq_unfreeze_queue(lo->lo_queue); | 223 | blk_mq_unfreeze_queue(lo->lo_queue); |
@@ -817,7 +817,7 @@ static void loop_config_discard(struct loop_device *lo) | |||
817 | q->limits.discard_alignment = 0; | 817 | q->limits.discard_alignment = 0; |
818 | blk_queue_max_discard_sectors(q, 0); | 818 | blk_queue_max_discard_sectors(q, 0); |
819 | blk_queue_max_write_zeroes_sectors(q, 0); | 819 | blk_queue_max_write_zeroes_sectors(q, 0); |
820 | queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q); | 820 | blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q); |
821 | return; | 821 | return; |
822 | } | 822 | } |
823 | 823 | ||
@@ -826,7 +826,7 @@ static void loop_config_discard(struct loop_device *lo) | |||
826 | 826 | ||
827 | blk_queue_max_discard_sectors(q, UINT_MAX >> 9); | 827 | blk_queue_max_discard_sectors(q, UINT_MAX >> 9); |
828 | blk_queue_max_write_zeroes_sectors(q, UINT_MAX >> 9); | 828 | blk_queue_max_write_zeroes_sectors(q, UINT_MAX >> 9); |
829 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); | 829 | blk_queue_flag_set(QUEUE_FLAG_DISCARD, q); |
830 | } | 830 | } |
831 | 831 | ||
832 | static void loop_unprepare_queue(struct loop_device *lo) | 832 | static void loop_unprepare_queue(struct loop_device *lo) |
@@ -1167,21 +1167,17 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) | |||
1167 | static int | 1167 | static int |
1168 | loop_get_status(struct loop_device *lo, struct loop_info64 *info) | 1168 | loop_get_status(struct loop_device *lo, struct loop_info64 *info) |
1169 | { | 1169 | { |
1170 | struct file *file = lo->lo_backing_file; | 1170 | struct file *file; |
1171 | struct kstat stat; | 1171 | struct kstat stat; |
1172 | int error; | 1172 | int ret; |
1173 | 1173 | ||
1174 | if (lo->lo_state != Lo_bound) | 1174 | if (lo->lo_state != Lo_bound) { |
1175 | mutex_unlock(&lo->lo_ctl_mutex); | ||
1175 | return -ENXIO; | 1176 | return -ENXIO; |
1176 | error = vfs_getattr(&file->f_path, &stat, | 1177 | } |
1177 | STATX_INO, AT_STATX_SYNC_AS_STAT); | 1178 | |
1178 | if (error) | ||
1179 | return error; | ||
1180 | memset(info, 0, sizeof(*info)); | 1179 | memset(info, 0, sizeof(*info)); |
1181 | info->lo_number = lo->lo_number; | 1180 | info->lo_number = lo->lo_number; |
1182 | info->lo_device = huge_encode_dev(stat.dev); | ||
1183 | info->lo_inode = stat.ino; | ||
1184 | info->lo_rdevice = huge_encode_dev(lo->lo_device ? stat.rdev : stat.dev); | ||
1185 | info->lo_offset = lo->lo_offset; | 1181 | info->lo_offset = lo->lo_offset; |
1186 | info->lo_sizelimit = lo->lo_sizelimit; | 1182 | info->lo_sizelimit = lo->lo_sizelimit; |
1187 | info->lo_flags = lo->lo_flags; | 1183 | info->lo_flags = lo->lo_flags; |
@@ -1194,7 +1190,19 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info) | |||
1194 | memcpy(info->lo_encrypt_key, lo->lo_encrypt_key, | 1190 | memcpy(info->lo_encrypt_key, lo->lo_encrypt_key, |
1195 | lo->lo_encrypt_key_size); | 1191 | lo->lo_encrypt_key_size); |
1196 | } | 1192 | } |
1197 | return 0; | 1193 | |
1194 | /* Drop lo_ctl_mutex while we call into the filesystem. */ | ||
1195 | file = get_file(lo->lo_backing_file); | ||
1196 | mutex_unlock(&lo->lo_ctl_mutex); | ||
1197 | ret = vfs_getattr(&file->f_path, &stat, STATX_INO, | ||
1198 | AT_STATX_SYNC_AS_STAT); | ||
1199 | if (!ret) { | ||
1200 | info->lo_device = huge_encode_dev(stat.dev); | ||
1201 | info->lo_inode = stat.ino; | ||
1202 | info->lo_rdevice = huge_encode_dev(stat.rdev); | ||
1203 | } | ||
1204 | fput(file); | ||
1205 | return ret; | ||
1198 | } | 1206 | } |
1199 | 1207 | ||
1200 | static void | 1208 | static void |
@@ -1352,7 +1360,10 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, | |||
1352 | struct loop_device *lo = bdev->bd_disk->private_data; | 1360 | struct loop_device *lo = bdev->bd_disk->private_data; |
1353 | int err; | 1361 | int err; |
1354 | 1362 | ||
1355 | mutex_lock_nested(&lo->lo_ctl_mutex, 1); | 1363 | err = mutex_lock_killable_nested(&lo->lo_ctl_mutex, 1); |
1364 | if (err) | ||
1365 | goto out_unlocked; | ||
1366 | |||
1356 | switch (cmd) { | 1367 | switch (cmd) { |
1357 | case LOOP_SET_FD: | 1368 | case LOOP_SET_FD: |
1358 | err = loop_set_fd(lo, mode, bdev, arg); | 1369 | err = loop_set_fd(lo, mode, bdev, arg); |
@@ -1374,7 +1385,8 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, | |||
1374 | break; | 1385 | break; |
1375 | case LOOP_GET_STATUS: | 1386 | case LOOP_GET_STATUS: |
1376 | err = loop_get_status_old(lo, (struct loop_info __user *) arg); | 1387 | err = loop_get_status_old(lo, (struct loop_info __user *) arg); |
1377 | break; | 1388 | /* loop_get_status() unlocks lo_ctl_mutex */ |
1389 | goto out_unlocked; | ||
1378 | case LOOP_SET_STATUS64: | 1390 | case LOOP_SET_STATUS64: |
1379 | err = -EPERM; | 1391 | err = -EPERM; |
1380 | if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) | 1392 | if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) |
@@ -1383,7 +1395,8 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, | |||
1383 | break; | 1395 | break; |
1384 | case LOOP_GET_STATUS64: | 1396 | case LOOP_GET_STATUS64: |
1385 | err = loop_get_status64(lo, (struct loop_info64 __user *) arg); | 1397 | err = loop_get_status64(lo, (struct loop_info64 __user *) arg); |
1386 | break; | 1398 | /* loop_get_status() unlocks lo_ctl_mutex */ |
1399 | goto out_unlocked; | ||
1387 | case LOOP_SET_CAPACITY: | 1400 | case LOOP_SET_CAPACITY: |
1388 | err = -EPERM; | 1401 | err = -EPERM; |
1389 | if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) | 1402 | if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) |
@@ -1535,16 +1548,20 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode, | |||
1535 | 1548 | ||
1536 | switch(cmd) { | 1549 | switch(cmd) { |
1537 | case LOOP_SET_STATUS: | 1550 | case LOOP_SET_STATUS: |
1538 | mutex_lock(&lo->lo_ctl_mutex); | 1551 | err = mutex_lock_killable(&lo->lo_ctl_mutex); |
1539 | err = loop_set_status_compat( | 1552 | if (!err) { |
1540 | lo, (const struct compat_loop_info __user *) arg); | 1553 | err = loop_set_status_compat(lo, |
1541 | mutex_unlock(&lo->lo_ctl_mutex); | 1554 | (const struct compat_loop_info __user *)arg); |
1555 | mutex_unlock(&lo->lo_ctl_mutex); | ||
1556 | } | ||
1542 | break; | 1557 | break; |
1543 | case LOOP_GET_STATUS: | 1558 | case LOOP_GET_STATUS: |
1544 | mutex_lock(&lo->lo_ctl_mutex); | 1559 | err = mutex_lock_killable(&lo->lo_ctl_mutex); |
1545 | err = loop_get_status_compat( | 1560 | if (!err) { |
1546 | lo, (struct compat_loop_info __user *) arg); | 1561 | err = loop_get_status_compat(lo, |
1547 | mutex_unlock(&lo->lo_ctl_mutex); | 1562 | (struct compat_loop_info __user *)arg); |
1563 | /* loop_get_status() unlocks lo_ctl_mutex */ | ||
1564 | } | ||
1548 | break; | 1565 | break; |
1549 | case LOOP_SET_CAPACITY: | 1566 | case LOOP_SET_CAPACITY: |
1550 | case LOOP_CLR_FD: | 1567 | case LOOP_CLR_FD: |
@@ -1808,7 +1825,7 @@ static int loop_add(struct loop_device **l, int i) | |||
1808 | * page. For directio mode, merge does help to dispatch bigger request | 1825 | * page. For directio mode, merge does help to dispatch bigger request |
1809 | * to underlayer disk. We will enable merge once directio is enabled. | 1826 | * to underlayer disk. We will enable merge once directio is enabled. |
1810 | */ | 1827 | */ |
1811 | queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES, lo->lo_queue); | 1828 | blk_queue_flag_set(QUEUE_FLAG_NOMERGES, lo->lo_queue); |
1812 | 1829 | ||
1813 | err = -ENOMEM; | 1830 | err = -ENOMEM; |
1814 | disk = lo->lo_disk = alloc_disk(1 << part_shift); | 1831 | disk = lo->lo_disk = alloc_disk(1 << part_shift); |
@@ -1864,8 +1881,8 @@ out: | |||
1864 | 1881 | ||
1865 | static void loop_remove(struct loop_device *lo) | 1882 | static void loop_remove(struct loop_device *lo) |
1866 | { | 1883 | { |
1867 | blk_cleanup_queue(lo->lo_queue); | ||
1868 | del_gendisk(lo->lo_disk); | 1884 | del_gendisk(lo->lo_disk); |
1885 | blk_cleanup_queue(lo->lo_queue); | ||
1869 | blk_mq_free_tag_set(&lo->tag_set); | 1886 | blk_mq_free_tag_set(&lo->tag_set); |
1870 | put_disk(lo->lo_disk); | 1887 | put_disk(lo->lo_disk); |
1871 | kfree(lo); | 1888 | kfree(lo); |
@@ -1949,7 +1966,9 @@ static long loop_control_ioctl(struct file *file, unsigned int cmd, | |||
1949 | ret = loop_lookup(&lo, parm); | 1966 | ret = loop_lookup(&lo, parm); |
1950 | if (ret < 0) | 1967 | if (ret < 0) |
1951 | break; | 1968 | break; |
1952 | mutex_lock(&lo->lo_ctl_mutex); | 1969 | ret = mutex_lock_killable(&lo->lo_ctl_mutex); |
1970 | if (ret) | ||
1971 | break; | ||
1953 | if (lo->lo_state != Lo_unbound) { | 1972 | if (lo->lo_state != Lo_unbound) { |
1954 | ret = -EBUSY; | 1973 | ret = -EBUSY; |
1955 | mutex_unlock(&lo->lo_ctl_mutex); | 1974 | mutex_unlock(&lo->lo_ctl_mutex); |