[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#847549: kernel bug dcache.c 2373 invalid opcode 0000 d_materialise_unique



Control: tag -1 moreinfo

On Fri, 9 Dec 2016 09:35:40 +0100 Daniel Pocock <daniel@pocock.pro> wrote:
> Package: linux
> Version: 3.16.36-1+deb8u1
> Severity: important
> 
> The system is an NFS server running linux-image-3.16.0-4-amd64
> 
> At times of heavy load on NFS, such as "git checkout some-branch" in a
> large repository, the system crashes (dmesg output attached).  It has
> been happening regularly since the upgrade to jessie and with every
> kernel released through stable updates.  I don't recall seeing this in
> wheezy.
> 
> I've installed kdump-tools.  Sometimes it captures the dmesg output, a
> recent example from a crash on 2016-12-02 is attached.  I'm not sure if
> the crashes without /var/crash logs are the same bug.
> 
> The same crash was reported[1] on linux-fsdevel by another Debian user.

Can you test the attached patches?  The first is the one J. Bruce
Fields pointed to and the second is in the same area; both of them went
upstream in 3.17.

Instructions for rebuilding the kernel with patches:
https://kernel-handbook.alioth.debian.org/ch-common-tasks.html#s-common-official

> I don't mind trying a backports kernel as a workaround, but can anybody
> comment on whether the backports kernel 4.7.8-1~bpo8+1 will match with
> the NFS user space packages in jessie, or do I need to update some of
> those packages too?
[...]

I don't believe that's necessary; no-one has asked for a backport of
nfs-utils.

Ben.

-- 
Ben Hutchings
The two most common things in the universe are hydrogen and stupidity.
From: "J. Bruce Fields" <bfields@redhat.com>
Date: Mon, 17 Feb 2014 17:45:56 -0500
Subject: dcache: close d_move race in d_splice_alias
Origin: https://git.kernel.org/linus/75a2352d0110960aeee1a28ddc09a55f97c99100
Bug-Debian: https://bugs.debian.org/847549

d_splice_alias will d_move an IS_ROOT() directory dentry into place if
one exists.  This should be safe as long as the dentry remains IS_ROOT,
but I can't see what guarantees that: once we drop the i_lock all we
hold here is the i_mutex on an unrelated parent directory.

Instead copy the logic of d_materialise_unique.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/dcache.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/fs/dcache.c b/fs/dcache.c
index 8bdae36a095f..8c09db9bb2a4 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1907,9 +1907,14 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
 		new = __d_find_alias(inode, 1);
 		if (new) {
 			BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));
+			write_seqlock(&rename_lock);
+			__d_materialise_dentry(dentry, new);
+			write_sequnlock(&rename_lock);
+			__d_drop(new);
+			_d_rehash(new);
+			spin_unlock(&new->d_lock);
 			spin_unlock(&inode->i_lock);
 			security_d_instantiate(new, inode);
-			d_move(new, dentry);
 			iput(inode);
 		} else {
 			/* already taking inode->i_lock, so d_add() by hand */
From: Al Viro <viro@zeniv.linux.org.uk>
Date: Thu, 11 Sep 2014 18:55:50 -0400
Subject: move the call of __d_drop(anon) into __d_materialise_unique(dentry,
 anon)
Origin: https://git.kernel.org/linus/6f18493e541c690169c3b1479d47d95f624161cf
Bug-Debian: https://bugs.debian.org/847549

and lock the right list there

Cc: stable@vger.kernel.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
[bwh: Backported to 3.16: adjust hunk order]
---
 fs/dcache.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/fs/dcache.c b/fs/dcache.c
index d30ce699ae4b..5c6e71dc23f5 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1910,7 +1910,6 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
 			write_seqlock(&rename_lock);
 			__d_materialise_dentry(dentry, new);
 			write_sequnlock(&rename_lock);
-			__d_drop(new);
 			_d_rehash(new);
 			spin_unlock(&new->d_lock);
 			spin_unlock(&inode->i_lock);
@@ -2723,6 +2722,12 @@ static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
 	dentry->d_parent = dentry;
 	list_del_init(&dentry->d_child);
 	anon->d_parent = dparent;
+	if (likely(!d_unhashed(anon))) {
+		hlist_bl_lock(&anon->d_sb->s_anon);
+		__hlist_bl_del(&anon->d_hash);
+		anon->d_hash.pprev = NULL;
+		hlist_bl_unlock(&anon->d_sb->s_anon);
+	}
 	list_move(&anon->d_child, &dparent->d_subdirs);
 
 	write_seqcount_end(&dentry->d_seq);
@@ -2776,7 +2781,6 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
 				 * could splice into our tree? */
 				__d_materialise_dentry(dentry, alias);
 				write_sequnlock(&rename_lock);
-				__d_drop(alias);
 				goto found;
 			} else {
 				/* Nope, but we must(!) avoid directory

Attachment: signature.asc
Description: This is a digitally signed message part


Reply to: