From: Jan Kara <jack@suse.cz>
To: "Fernando Luis Vázquez Cao" <fernando_b1@lab.ntt.co.jp>
Cc: Al Viro <viro@zeniv.linux.org.uk>,
Josef Bacik <jbacik@fusionio.com>,
Eric Sandeen <sandeen@redhat.com>,
Dave Chinner <dchinner@redhat.com>,
Christoph Hellwig <hch@infradead.org>, Jan Kara <jack@suse.cz>,
linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH 4/9] fsfreeze: emergency thaw will deadlock on s_umount
Date: Mon, 8 Oct 2012 15:57:33 +0200 [thread overview]
Message-ID: <20121008135733.GC9243@quack.suse.cz> (raw)
In-Reply-To: <1349415353.7347.8.camel@nexus.lab.ntt.co.jp>
On Fri 05-10-12 14:35:53, Fernando Luis Vázquez Cao wrote:
> The emergency thaw process uses iterate_super() which holds the
> sb->s_umount lock in read mode. The current thaw_super() code takes
> the sb->s_umount lock in write mode, hence leading to an instant
> deadlock.
>
> Use the unlocked version of thaw_super() to do the thawing and replace
> iterate_supers() with __iterate_supers() so that the unfreeze operation can
^^ iterate_supers_write()
> be performed with s_umount held as the locking rules for fsfreeze indicate.
>
> As a bonus, by using thaw_super(), which does not nest, instead of thaw_bdev()
> when can get rid of the ugly while loop.
>
> Jan Kara pointed out that with this approach we will leave the block devices
> frozen, but this is a problem we have had since the introduction of the
> superblock level API: if we thaw the filesystem using the superblock level API
> (be it through the thaw ioctl or emergency thaw) the bdev level freeze
> reference counter (bd_fsfreeze_count) will not be updated and even though
> subsequent calls to thaw_bdev() will decrease it it will never get back to 0
> (if thaw_super() returns an error, and it will when the superblock is unfrozen,
> thaw_bdev() will return without decreasing the counter). The solution I propose
> (and will be implementing in the followup patch "fsfreeze: freeze_super and
> thaw_bdev don't play well together") is letting bd_fsfreeze_count
> become zero when the superblock sitting on top of it is unfrozen, so that
> future calls to freeze_bdev() actually try to freeze the superblock.
>
> Cc: Josef Bacik <jbacik@fusionio.com>
> Cc: Eric Sandeen <sandeen@redhat.com>
> Cc: Christoph Hellwig <hch@infradead.org>
> Cc: Jan Kara <jack@suse.cz>
> Cc: Dave Chinner <dchinner@redhat.com>
> Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
> ---
>
> diff -urNp linux-3.6.0-rc7-orig/fs/buffer.c linux-3.6.0-rc7/fs/buffer.c
> --- linux-3.6.0-rc7-orig/fs/buffer.c 2012-09-26 13:20:14.842365056 +0900
> +++ linux-3.6.0-rc7/fs/buffer.c 2012-09-26 15:02:22.630595704 +0900
> @@ -513,15 +513,28 @@ repeat:
>
> static void do_thaw_one(struct super_block *sb, void *unused)
> {
> - char b[BDEVNAME_SIZE];
> - while (sb->s_bdev && !thaw_bdev(sb->s_bdev, sb))
> - printk(KERN_WARNING "Emergency Thaw on %s\n",
> + int res;
> +
> + if (sb->s_bdev) {
> + char b[BDEVNAME_SIZE];
> + printk(KERN_WARNING "Emergency Thaw on %s.\n",
> bdevname(sb->s_bdev, b));
> + }
> +
> + /* We got here from __iterate_supers with the superblock lock taken
> + * so we can call the lockless version of thaw_super() safely. */
> + res = __thaw_super(sb);
> + /* If we are going to drop the final active reference call
> + * deactivate_locked_super to clean things up. In the general case
> + * we avoid calling deactivate_locked_super() because it would relase
> + * the superblock lock, which is __iterate_supers()'s job. */
> + if (!res && !atomic_add_unless(&sb->s_active, -1, 1))
> + deactivate_locked_super(sb);
This just looks wrong. When we *do* end up calling
deactivate_locked_super() we will return with sb unlocked which makes
iterate_supers_write() unlock already unlocked lock. What I would put here
is:
if (!res) {
deactivate_locked_super(sb);
/*
* We have to re-acquire s_umount because
* iterate_supers_write() will unlock it. It still holds
* passive reference so sb cannot be freed under us.
*/
down_write(&sb->s_umount);
}
Is there any problem with this I miss?
Honza
--
Jan Kara <jack@suse.cz>
SUSE Labs, CR
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2012-10-08 13:57 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-05 5:24 [PATCH 0/9 v5] fsfreeze: miscellaneous fixes and cleanups Fernando Luis Vázquez Cao
2012-10-05 5:31 ` [PATCH 1/9] vfs: add __iterate_supers() and helpers around it Fernando Luis Vázquez Cao
2012-10-08 13:48 ` Jan Kara
2012-10-05 5:33 ` [PATCH 2/9] fsfreeze: add unlocked version of thaw_super Fernando Luis Vázquez Cao
2012-10-05 5:34 ` [PATCH 3/9] fsfreeze: Prevent emergency thaw from looping infinitely Fernando Luis Vázquez Cao
2012-10-05 5:35 ` [PATCH 4/9] fsfreeze: emergency thaw will deadlock on s_umount Fernando Luis Vázquez Cao
2012-10-08 13:57 ` Jan Kara [this message]
2012-10-09 5:07 ` Fernando Luis Vazquez Cao
2012-10-09 8:20 ` Jan Kara
2012-10-09 9:52 ` Fernando Luis Vazquez Cao
2012-10-05 5:38 ` [PATCH 5/9] xfs: switch to using super methods for fsfreeze Fernando Luis Vázquez Cao
2012-10-05 5:39 ` [PATCH 6/9] fsfreeze: move emergency thaw code to fs/super.c Fernando Luis Vázquez Cao
2012-10-05 5:42 ` [PATCH 7/9] fsfreeze: freeze_super and thaw_bdev don't play well together Fernando Luis Vázquez Cao
2012-10-08 14:17 ` Jan Kara
2012-10-05 5:43 ` [PATCH 8/9] fsfreeze: add vfs ioctl to check freeze state Fernando Luis Vázquez Cao
2012-10-08 15:05 ` Jan Kara
2012-10-09 9:46 ` Fernando Luis Vazquez Cao
2012-10-09 14:55 ` Jan Kara
2012-10-10 2:17 ` Fernando Luis Vazquez Cao
2012-10-11 16:26 ` Jan Kara
2012-10-05 5:44 ` [PATCH 9/9] fsfreeze: add block device " Fernando Luis Vázquez Cao
-- strict thread matches above, loose matches on Subject: below --
2012-09-14 6:43 [RFC, PATCH 0/9 v4] fsfreeze: miscellaneous fixes and cleanups Fernando Luis Vázquez Cao
2012-09-14 6:48 ` [PATCH 4/9] fsfreeze: emergency thaw will deadlock on s_umount Fernando Luis Vázquez Cao
2012-09-25 9:24 ` Jan Kara
2012-09-25 10:31 ` Fernando Luis Vazquez Cao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20121008135733.GC9243@quack.suse.cz \
--to=jack@suse.cz \
--cc=dchinner@redhat.com \
--cc=fernando_b1@lab.ntt.co.jp \
--cc=hch@infradead.org \
--cc=jbacik@fusionio.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=sandeen@redhat.com \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.