Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.com>2018-11-01 14:04:41 +1100
committerNeilBrown <neilb@suse.com>2018-11-01 14:05:58 +1100
commit8c6c11a7a447e3ff9c46123ee73b471320bb4a40 (patch)
tree3a0c6d3db9fbd01a572af57d3105215e44a2ca35
parentb5c10ec2c7aeb10717a908d55c139206a28517ba (diff)
make sure that __dentry_kill() always invalidates d_seq,
unhashed or not (git-fixes).
-rw-r--r--patches.fixes/make-sure-that-__dentry_kill-always-invalidates-d_se.patch49
-rw-r--r--series.conf1
2 files changed, 50 insertions, 0 deletions
diff --git a/patches.fixes/make-sure-that-__dentry_kill-always-invalidates-d_se.patch b/patches.fixes/make-sure-that-__dentry_kill-always-invalidates-d_se.patch
new file mode 100644
index 0000000000..96bc7d39f0
--- /dev/null
+++ b/patches.fixes/make-sure-that-__dentry_kill-always-invalidates-d_se.patch
@@ -0,0 +1,49 @@
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Thu, 9 Aug 2018 10:15:54 -0400
+Subject: [PATCH] make sure that __dentry_kill() always invalidates d_seq,
+ unhashed or not
+Git-commit: 4c0d7cd5c8416b1ef41534d19163cb07ffaa03ab
+Patch-mainline: v4.18
+References: git-fixes
+
+RCU pathwalk relies upon the assumption that anything that changes
+->d_inode of a dentry will invalidate its ->d_seq. That's almost
+true - the one exception is that the final dput() of already unhashed
+dentry does *not* touch ->d_seq at all. Unhashing does, though,
+so for anything we'd found by RCU dcache lookup we are fine.
+Unfortunately, we can *start* with an unhashed dentry or jump into
+it.
+
+We could try and be careful in the (few) places where that could
+happen. Or we could just make the final dput() invalidate the damn
+thing, unhashed or not. The latter is much simpler and easier to
+backport, so let's do it that way.
+
+Reported-by: "Dae R. Jeong" <threeearcat@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Acked-by: NeilBrown <neilb@suse.com>
+
+---
+ fs/dcache.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -355,14 +355,11 @@ static void dentry_unlink_inode(struct d
+ __releases(dentry->d_inode->i_lock)
+ {
+ struct inode *inode = dentry->d_inode;
+- bool hashed = !d_unhashed(dentry);
+
+- if (hashed)
+- raw_write_seqcount_begin(&dentry->d_seq);
++ raw_write_seqcount_begin(&dentry->d_seq);
+ __d_clear_type_and_inode(dentry);
+ hlist_del_init(&dentry->d_u.d_alias);
+- if (hashed)
+- raw_write_seqcount_end(&dentry->d_seq);
++ raw_write_seqcount_end(&dentry->d_seq);
+ spin_unlock(&dentry->d_lock);
+ spin_unlock(&inode->i_lock);
+ if (!inode->i_nlink)
diff --git a/series.conf b/series.conf
index b0dd3a60e1..41b791eeea 100644
--- a/series.conf
+++ b/series.conf
@@ -17188,6 +17188,7 @@
patches.fixes/root-dentries-need-RCU-delayed-freeing.patch
patches.fixes/fix-mntputmntput-race.patch
patches.fixes/fix-__legitimize_mntmntput-race.patch
+ patches.fixes/make-sure-that-__dentry_kill-always-invalidates-d_se.patch
patches.fixes/init-rename-and-re-order-boot_cpu_state_init.patch
patches.drivers/scsi-qla2xxx-fix-memory-leak-for-allocating-abort-iocb.patch
patches.fixes/debugobjects-Make-stack-check-warning-more-informati.patch