aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/loop.c
diff options
context:
space:
mode:
authorNikanth Karthikesan <knikanth@suse.de>2009-03-24 07:33:41 -0400
committerJens Axboe <jens.axboe@oracle.com>2009-03-26 06:01:19 -0400
commitf028f3b2f987ebc61cef382ab7a5c449917b728e (patch)
tree6006b562900361a0af3cc50f564466ffce29c2a2 /drivers/block/loop.c
parent68db1961bbf4e16c220ccec4a780e966bc1fece3 (diff)
loop: fix circular locking in loop_clr_fd()
With CONFIG_PROVE_LOCKING enabled $ losetup /dev/loop0 file $ losetup -o 32256 /dev/loop1 /dev/loop0 $ losetup -d /dev/loop1 $ losetup -d /dev/loop0 triggers a [ INFO: possible circular locking dependency detected ] I think this warning is a false positive. Open/close on a loop device acquires bd_mutex of the device before acquiring lo_ctl_mutex of the same device. For ioctl(LOOP_CLR_FD) after acquiring lo_ctl_mutex, fput on the backing_file might acquire the bd_mutex of a device, if backing file is a device and this is the last reference to the file being dropped . But it is guaranteed that it is impossible to have a circular list of backing devices.(say loop2->loop1->loop0->loop2 is not possible), which guarantees that this can never deadlock. So this warning should be suppressed. It is very difficult to annotate lockdep not to warn here in the correct way. A simple way to silence lockdep could be to mark the lo_ctl_mutex in ioctl to be a sub class, but this might mask some other real bugs. @@ -1164,7 +1164,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, struct loop_device *lo = bdev->bd_disk->private_data; int err; - mutex_lock(&lo->lo_ctl_mutex); + mutex_lock_nested(&lo->lo_ctl_mutex, 1); switch (cmd) { case LOOP_SET_FD: err = loop_set_fd(lo, mode, bdev, arg); Or actually marking the bd_mutex after lo_ctl_mutex as a sub class could be a better solution. Luckily it is easy to avoid calling fput on backing file with lo_ctl_mutex held, so no lockdep annotation is required. If you do not like the special handling of the lo_ctl_mutex just for the LOOP_CLR_FD ioctl in lo_ioctl(), the mutex handling could be moved inside each of the individual ioctl handlers and I could send you another patch. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r--drivers/block/loop.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 9721d100caf1..2621ed2ce6d2 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -969,11 +969,18 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
969 bd_set_size(bdev, 0); 969 bd_set_size(bdev, 0);
970 mapping_set_gfp_mask(filp->f_mapping, gfp); 970 mapping_set_gfp_mask(filp->f_mapping, gfp);
971 lo->lo_state = Lo_unbound; 971 lo->lo_state = Lo_unbound;
972 fput(filp);
973 /* This is safe: open() is still holding a reference. */ 972 /* This is safe: open() is still holding a reference. */
974 module_put(THIS_MODULE); 973 module_put(THIS_MODULE);
975 if (max_part > 0) 974 if (max_part > 0)
976 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);
977 return 0; 984 return 0;
978} 985}
979 986
@@ -1191,7 +1198,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
1191 struct loop_device *lo = bdev->bd_disk->private_data; 1198 struct loop_device *lo = bdev->bd_disk->private_data;
1192 int err; 1199 int err;
1193 1200
1194 mutex_lock(&lo->lo_ctl_mutex); 1201 mutex_lock_nested(&lo->lo_ctl_mutex, 1);
1195 switch (cmd) { 1202 switch (cmd) {
1196 case LOOP_SET_FD: 1203 case LOOP_SET_FD:
1197 err = loop_set_fd(lo, mode, bdev, arg); 1204 err = loop_set_fd(lo, mode, bdev, arg);
@@ -1200,7 +1207,10 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
1200 err = loop_change_fd(lo, bdev, arg); 1207 err = loop_change_fd(lo, bdev, arg);
1201 break; 1208 break;
1202 case LOOP_CLR_FD: 1209 case LOOP_CLR_FD:
1210 /* loop_clr_fd would have unlocked lo_ctl_mutex on success */
1203 err = loop_clr_fd(lo, bdev); 1211 err = loop_clr_fd(lo, bdev);
1212 if (!err)
1213 goto out_unlocked;
1204 break; 1214 break;
1205 case LOOP_SET_STATUS: 1215 case LOOP_SET_STATUS:
1206 err = loop_set_status_old(lo, (struct loop_info __user *) arg); 1216 err = loop_set_status_old(lo, (struct loop_info __user *) arg);
@@ -1218,6 +1228,8 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
1218 err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL; 1228 err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
1219 } 1229 }
1220 mutex_unlock(&lo->lo_ctl_mutex); 1230 mutex_unlock(&lo->lo_ctl_mutex);
1231
1232out_unlocked:
1221 return err; 1233 return err;
1222} 1234}
1223 1235