diff options
| author | 2012-11-09 14:58:01 -0800 | |
|---|---|---|
| committer | 2012-11-09 14:58:01 -0800 | |
| commit | edf8dde393f879fc2d8c22d4bc01ff8d37b80e1a (patch) | |
| tree | 61425adc8b2059a9c12a3ce66ba7361fea1b0bb3 /drivers/block/loop.c | |
| parent | ARM: OMAP: Remove omap_init_consistent_dma_size() (diff) | |
| parent | Linux 3.7-rc4 (diff) | |
Merge branch 'linus' into omap-for-v3.8/cleanup-headers-prepare-multiplatform-v3
Diffstat (limited to 'drivers/block/loop.c')
| -rw-r--r-- | drivers/block/loop.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index e9d594fd12cb..54046e51160a 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -976,8 +976,21 @@ static int loop_clr_fd(struct loop_device *lo) if (lo->lo_state != Lo_bound) return -ENXIO; - if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */ - return -EBUSY; + /* + * If we've explicitly asked to tear down the loop device, + * and it has an elevated reference count, set it for auto-teardown when + * the last reference goes away. This stops $!~#$@ udev from + * preventing teardown because it decided that it needs to run blkid on + * the loopback device whenever they appear. xfstests is notorious for + * failing tests because blkid via udev races with a losetup + * <dev>/do something like mkfs/losetup -d <dev> causing the losetup -d + * command to fail with EBUSY. + */ + if (lo->lo_refcnt > 1) { + lo->lo_flags |= LO_FLAGS_AUTOCLEAR; + mutex_unlock(&lo->lo_ctl_mutex); + return 0; + } if (filp == NULL) return -EINVAL; |
