linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Nick Piggin <npiggin@gmail.com>
To: Valdis.Kletnieks@vt.edu
Cc: Alexander Viro <viro@zeniv.linux.org.uk>,
	Joel Becker <joel.becker@oracle.com>,
	linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: Re: 2.6.37-next - kernel BUG at fs/dcache.c:1363
Date: Fri, 7 Jan 2011 00:12:09 +1100	[thread overview]
Message-ID: <AANLkTi=nVJNJdBChyuD43sqWEf3O_1tDj0FTO8O_Ukib@mail.gmail.com> (raw)
In-Reply-To: <AANLkTimtrinH-7tnGE2zxtoNNTEnqqD3ZDTTTWM-m0Uk@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1122 bytes --]

On Thu, Jan 6, 2011 at 9:44 PM, Nick Piggin <npiggin@gmail.com> wrote:
> On Thu, Jan 6, 2011 at 4:15 AM,  <Valdis.Kletnieks@vt.edu> wrote:
>> Saw this crash on a linux-next pulled yesterday at 2PM EST, kernel dies very
>> early (looks like first time it touches configfs for anything - trying to boot
>> with netconsole enabled caused it to die even faster).  I can bisect this if
>> it doesn't immediately ring a bell...
>
> Thanks, bah configfs isn't widely used.
>
>
>> It dies here:
>>
>> void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
>> {
>>        BUG_ON(dentry->d_op);
>>
>> Am guessing configfs passed in a dentry that wasn't filled in enough.
>>
>> (hand-transcribed from a crappy cellphone pic)
>>
>> kernel BUG at fs/dcache.c:1363
>
> Thanks. It actually passed in a dentry that appears to have already been
> used for something. This is not exactly a nice thing for a filesystem to do
> and probably indicates an underlying bug anyway (or at least something
> the vfs doesn't guarantee the safety of).
>
> Taking a look now.

This patch fixes it here

[-- Attachment #2: dentry-debug.patch --]
[-- Type: application/octet-stream, Size: 2449 bytes --]

config fs: avoid switching ->d_op on live dentry

Switching d_op on a live dentry is racy in general, so avoid it. In this case
it is a negative dentry, which is safer, but there are still concurrent ops
which may be called on d_op in that case (eg. d_revalidate). So in general
a filesystem may not do this. Fix configfs so as not to do this.

[to be backmerged or replaced with Al Viro's alternative]

Signed-off-by: Nick Piggin <npiggin@kernel.dk>

Index: linux-2.6/fs/configfs/dir.c
===================================================================
--- linux-2.6.orig/fs/configfs/dir.c	2011-01-06 21:55:58.000000000 +1100
+++ linux-2.6/fs/configfs/dir.c	2011-01-07 00:06:43.000000000 +1100
@@ -232,10 +232,8 @@ int configfs_make_dirent(struct configfs
 
 	sd->s_mode = mode;
 	sd->s_dentry = dentry;
-	if (dentry) {
+	if (dentry)
 		dentry->d_fsdata = configfs_get(sd);
-		d_set_d_op(dentry, &configfs_dentry_ops);
-	}
 
 	return 0;
 }
@@ -278,7 +276,6 @@ static int create_dir(struct config_item
 		error = configfs_create(d, mode, init_dir);
 		if (!error) {
 			inc_nlink(p->d_inode);
-			d_set_d_op((d), &configfs_dentry_ops);
 		} else {
 			struct configfs_dirent *sd = d->d_fsdata;
 			if (sd) {
@@ -371,9 +368,7 @@ int configfs_create_link(struct configfs
 				   CONFIGFS_ITEM_LINK);
 	if (!err) {
 		err = configfs_create(dentry, mode, init_symlink);
-		if (!err)
-			d_set_d_op(dentry, &configfs_dentry_ops);
-		else {
+		if (err) {
 			struct configfs_dirent *sd = dentry->d_fsdata;
 			if (sd) {
 				spin_lock(&configfs_dirent_lock);
@@ -492,7 +487,11 @@ static struct dentry * configfs_lookup(s
 		 * If it doesn't exist and it isn't a NOT_PINNED item,
 		 * it must be negative.
 		 */
-		return simple_lookup(dir, dentry, nd);
+		if (dentry->d_name.len > NAME_MAX)
+			return ERR_PTR(-ENAMETOOLONG);
+		d_set_d_op(dentry, &configfs_dentry_ops);
+		d_add(dentry, NULL);
+		return NULL;
 	}
 
 out:
@@ -684,6 +683,7 @@ static int create_default_group(struct c
 	ret = -ENOMEM;
 	child = d_alloc(parent, &name);
 	if (child) {
+		d_set_d_op(child, &configfs_dentry_ops);
 		d_add(child, NULL);
 
 		ret = configfs_attach_group(&parent_group->cg_item,
@@ -1681,6 +1681,7 @@ int configfs_register_subsystem(struct c
 	err = -ENOMEM;
 	dentry = d_alloc(configfs_sb->s_root, &name);
 	if (dentry) {
+		d_set_d_op(dentry, &configfs_dentry_ops);
 		d_add(dentry, NULL);
 
 		err = configfs_attach_group(sd->s_element, &group->cg_item,

  reply	other threads:[~2011-01-06 13:12 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-05 17:15 2.6.37-next - kernel BUG at fs/dcache.c:1363 Valdis.Kletnieks
2011-01-06 10:44 ` Nick Piggin
2011-01-06 13:12   ` Nick Piggin [this message]
2011-01-07 17:10     ` Valdis.Kletnieks

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='AANLkTi=nVJNJdBChyuD43sqWEf3O_1tDj0FTO8O_Ukib@mail.gmail.com' \
    --to=npiggin@gmail.com \
    --cc=Valdis.Kletnieks@vt.edu \
    --cc=joel.becker@oracle.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).