[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <464B4DE4.9060100@gmail.com>
Date: Wed, 16 May 2007 20:31:00 +0200
From: Tejun Heo <htejun@...il.com>
To: Andrew Morton <akpm@...ux-foundation.org>
CC: Clemens Schwaighofer <cs@...uila.co.jp>,
linux-kernel <linux-kernel@...r.kernel.org>,
Maneesh Soni <maneesh@...ibm.com>,
Dipankar Sarma <dipankar@...ibm.com>, Greg KH <greg@...ah.com>,
Chuck Ebbert <cebbert@...hat.com>
Subject: [PATCH -stable] sysfs: disable reclamation by default
sd->s_dentry updates made by dentry/inode reclamation are racy and can
lead to BUG() or oops. This is already fixed in -mm and the fix is
scheduled to be merged into upstream for 2.6.23 but the fix
reimplements sysfs dentry dropping and is too risky for -stable
kernels.
This is an interim solution for -stable kernels. sysfs reclamation is
disabled by default and can be enabled by using sysfs.enable_reclaim
kernel parameter. Note that dentries are still created on demand, so
attribute and symlinks nodes aren't allocated on creation. They're
allocated on first lookup and deallocated when the sysfs node is
removed.
Signed-off-by: Tejun Heo <htejun@...il.com>
---
Okay, I wasn't sure about the backport, so this is what I've come up
with. It's ugly but, as Chuck pointed out, anything is better than
oopsing.
Clemens, can you please test this one too?
If anyone has any better idea, feel free to override this one.
Thanks.
Documentation/kernel-parameters.txt | 8 ++++++++
fs/sysfs/Makefile | 3 ++-
fs/sysfs/dir.c | 11 +++++++++++
fs/sysfs/inode.c | 3 +++
fs/sysfs/sysfs.h | 1 +
5 files changed, 25 insertions(+), 1 deletion(-)
Index: tree0/fs/sysfs/dir.c
===================================================================
--- tree0.orig/fs/sysfs/dir.c
+++ tree0/fs/sysfs/dir.c
@@ -14,6 +14,13 @@
DECLARE_RWSEM(sysfs_rename_sem);
+/*
+ * sysfs dentry/inode reclaming has race conditions around
+ * sd->s_dentry. Disable it by default.
+ */
+int sysfs_enable_reclaim;
+module_param_named(enable_reclaim, sysfs_enable_reclaim, bool, 0444);
+
static void sysfs_d_iput(struct dentry * dentry, struct inode * inode)
{
struct sysfs_dirent * sd = dentry->d_fsdata;
@@ -289,6 +296,10 @@ static struct dentry * sysfs_lookup(stru
err = sysfs_attach_link(sd, dentry);
else
err = sysfs_attach_attr(sd, dentry);
+
+ if (err == 0 && !sysfs_enable_reclaim)
+ dget(dentry);
+
break;
}
}
Index: tree0/fs/sysfs/inode.c
===================================================================
--- tree0.orig/fs/sysfs/inode.c
+++ tree0/fs/sysfs/inode.c
@@ -266,6 +266,9 @@ void sysfs_drop_dentry(struct sysfs_dire
spin_unlock(&dentry->d_lock);
spin_unlock(&dcache_lock);
}
+
+ if (!sysfs_enable_reclaim)
+ dput(dentry);
}
}
Index: tree0/fs/sysfs/Makefile
===================================================================
--- tree0.orig/fs/sysfs/Makefile
+++ tree0/fs/sysfs/Makefile
@@ -2,5 +2,6 @@
# Makefile for the sysfs virtual filesystem
#
-obj-y := inode.o file.o dir.o symlink.o mount.o bin.o \
+obj-y := sysfs.o
+sysfs-objs := inode.o file.o dir.o symlink.o mount.o bin.o \
group.o
Index: tree0/Documentation/kernel-parameters.txt
===================================================================
--- tree0.orig/Documentation/kernel-parameters.txt
+++ tree0/Documentation/kernel-parameters.txt
@@ -1721,6 +1721,14 @@ and is between 256 and 4096 characters.
sym53c416= [HW,SCSI]
See header of drivers/scsi/sym53c416.c.
+ sysfs.enable_reclaim
+ Enable dentry and inode reclamation for
+ attribute and symlink nodes. This is buggy
+ and can cause oops or trigger BUG. Do not
+ enable unless you know what you're doing.
+ This kernel parameter will be removed after
+ reclamation is fixed.
+
sysrq_always_enabled
[KNL]
Ignore sysrq setting - this boot parameter will
Index: tree0/fs/sysfs/sysfs.h
===================================================================
--- tree0.orig/fs/sysfs/sysfs.h
+++ tree0/fs/sysfs/sysfs.h
@@ -12,6 +12,7 @@ struct sysfs_dirent {
extern struct vfsmount * sysfs_mount;
extern struct kmem_cache *sysfs_dir_cachep;
+extern int sysfs_enable_reclaim;
extern void sysfs_delete_inode(struct inode *inode);
extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists