Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1763447AbYBMUWk (ORCPT ); Wed, 13 Feb 2008 15:22:40 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1756808AbYBMUWc (ORCPT ); Wed, 13 Feb 2008 15:22:32 -0500 Received: from twin.jikos.cz ([213.151.79.26]:60020 "EHLO twin.jikos.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756746AbYBMUWc (ORCPT ); Wed, 13 Feb 2008 15:22:32 -0500 Date: Wed, 13 Feb 2008 21:22:25 +0100 (CET) From: Jiri Kosina X-X-Sender: jikos@twin.jikos.cz To: Zdenek Kabelac cc: linux-kernel@vger.kernel.org Subject: Re: losetup INFO: possible circular locking dependency detected In-Reply-To: Message-ID: References: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2626 Lines: 72 On Wed, 13 Feb 2008, Jiri Kosina wrote: > From: Jiri Kosina > > loop - fix deadlock against block > > A: B: > bdev_open() for ino X > (locks bd_mutex for bdev Y) > lo_ioctl(LOOP_CLR_FD) for ino X > (locks lo_ctl_mutex) > fput() > __fput() > blkdev_close() > (hangs on bd_mutex for bdev Y) > lo_open() > (hangs on lo_ctl_mutex) > > Fix this by letting releasing the lock inside loop_clr_fd() after the > loopback structure has been completely deinitialized, but before calling > final fput(). > > Signed-off-by: Jiri Kosina OK, the previous one was buggy, could you please try this one instead? diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 91ebb00..bfb2e90 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -881,6 +881,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) struct file *filp = lo->lo_backing_file; gfp_t gfp = lo->old_gfp_mask; + mutex_lock(&lo->lo_ctl_mutex); if (lo->lo_state != Lo_bound) return -ENXIO; @@ -916,6 +917,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) bd_set_size(bdev, 0); mapping_set_gfp_mask(filp->f_mapping, gfp); lo->lo_state = Lo_unbound; + mutex_unlock(&lo->lo_ctl_mutex); fput(filp); /* This is safe: open() is still holding a reference. */ module_put(THIS_MODULE); @@ -1143,8 +1145,11 @@ static int lo_ioctl(struct inode * inode, struct file * file, err = loop_change_fd(lo, file, inode->i_bdev, arg); break; case LOOP_CLR_FD: + /* loop_clr_fd must do the locking itself, so that it + * doesn't deadlock with bdev */ + mutex_unlock(&lo->lo_ctl_mutex); err = loop_clr_fd(lo, inode->i_bdev); - break; + goto out_unlocked; case LOOP_SET_STATUS: err = loop_set_status_old(lo, (struct loop_info __user *) arg); break; @@ -1161,6 +1166,7 @@ static int lo_ioctl(struct inode * inode, struct file * file, err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL; } mutex_unlock(&lo->lo_ctl_mutex); +out_unlocked: return err; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/