aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r--drivers/block/loop.c48
1 files changed, 44 insertions, 4 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index bf0345577672..2621ed2ce6d2 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -474,10 +474,35 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
474 int ret; 474 int ret;
475 475
476 pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset; 476 pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset;
477 if (bio_rw(bio) == WRITE) 477
478 if (bio_rw(bio) == WRITE) {
479 int barrier = bio_barrier(bio);
480 struct file *file = lo->lo_backing_file;
481
482 if (barrier) {
483 if (unlikely(!file->f_op->fsync)) {
484 ret = -EOPNOTSUPP;
485 goto out;
486 }
487
488 ret = vfs_fsync(file, file->f_path.dentry, 0);
489 if (unlikely(ret)) {
490 ret = -EIO;
491 goto out;
492 }
493 }
494
478 ret = lo_send(lo, bio, pos); 495 ret = lo_send(lo, bio, pos);
479 else 496
497 if (barrier && !ret) {
498 ret = vfs_fsync(file, file->f_path.dentry, 0);
499 if (unlikely(ret))
500 ret = -EIO;
501 }
502 } else
480 ret = lo_receive(lo, bio, lo->lo_blocksize, pos); 503 ret = lo_receive(lo, bio, lo->lo_blocksize, pos);
504
505out:
481 return ret; 506 return ret;
482} 507}
483 508
@@ -826,6 +851,9 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
826 lo->lo_queue->queuedata = lo; 851 lo->lo_queue->queuedata = lo;
827 lo->lo_queue->unplug_fn = loop_unplug; 852 lo->lo_queue->unplug_fn = loop_unplug;
828 853
854 if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync)
855 blk_queue_ordered(lo->lo_queue, QUEUE_ORDERED_DRAIN, NULL);
856
829 set_capacity(lo->lo_disk, size); 857 set_capacity(lo->lo_disk, size);
830 bd_set_size(bdev, size << 9); 858 bd_set_size(bdev, size << 9);
831 859
@@ -941,11 +969,18 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
941 bd_set_size(bdev, 0); 969 bd_set_size(bdev, 0);
942 mapping_set_gfp_mask(filp->f_mapping, gfp); 970 mapping_set_gfp_mask(filp->f_mapping, gfp);
943 lo->lo_state = Lo_unbound; 971 lo->lo_state = Lo_unbound;
944 fput(filp);
945 /* This is safe: open() is still holding a reference. */ 972 /* This is safe: open() is still holding a reference. */
946 module_put(THIS_MODULE); 973 module_put(THIS_MODULE);
947 if (max_part > 0) 974 if (max_part > 0)
948 ioctl_by_bdev(bdev, BLKRRPART, 0); 975 ioctl_by_bdev(bdev, BLKRRPART, 0);
976 mutex_unlock(&lo->lo_ctl_mutex);
977 /*
978 * Need not hold lo_ctl_mutex to fput backing file.
979 * Calling fput holding lo_ctl_mutex triggers a circular
980 * lock dependency possibility warning as fput can take
981 * bd_mutex which is usually taken before lo_ctl_mutex.
982 */
983 fput(filp);
949 return 0; 984 return 0;
950} 985}
951 986
@@ -1163,7 +1198,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
1163 struct loop_device *lo = bdev->bd_disk->private_data; 1198 struct loop_device *lo = bdev->bd_disk->private_data;
1164 int err; 1199 int err;
1165 1200
1166 mutex_lock(&lo->lo_ctl_mutex); 1201 mutex_lock_nested(&lo->lo_ctl_mutex, 1);
1167 switch (cmd) { 1202 switch (cmd) {
1168 case LOOP_SET_FD: 1203 case LOOP_SET_FD:
1169 err = loop_set_fd(lo, mode, bdev, arg); 1204 err = loop_set_fd(lo, mode, bdev, arg);
@@ -1172,7 +1207,10 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
1172 err = loop_change_fd(lo, bdev, arg); 1207 err = loop_change_fd(lo, bdev, arg);
1173 break; 1208 break;
1174 case LOOP_CLR_FD: 1209 case LOOP_CLR_FD:
1210 /* loop_clr_fd would have unlocked lo_ctl_mutex on success */
1175 err = loop_clr_fd(lo, bdev); 1211 err = loop_clr_fd(lo, bdev);
1212 if (!err)
1213 goto out_unlocked;
1176 break; 1214 break;
1177 case LOOP_SET_STATUS: 1215 case LOOP_SET_STATUS:
1178 err = loop_set_status_old(lo, (struct loop_info __user *) arg); 1216 err = loop_set_status_old(lo, (struct loop_info __user *) arg);
@@ -1190,6 +1228,8 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
1190 err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL; 1228 err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
1191 } 1229 }
1192 mutex_unlock(&lo->lo_ctl_mutex); 1230 mutex_unlock(&lo->lo_ctl_mutex);
1231
1232out_unlocked:
1193 return err; 1233 return err;
1194} 1234}
1195 1235