[PATCH] add procfs tunable to enable immediate panic when there arebusy inodes after umount

From: Jeff Layton
Date: Tue May 29 2007 - 11:40:55 EST


After spending quite a bit of time tracking down a "VFS: busy inodes
after unmount" problem, it occurs to me that it would be nice to be
able to force a panic when that occurs. While an oops message alone is
not generally helpful for tracking down this sort of problem,
collecting and analyzing a coredump when this occurs can be.

The following patch adds a procfs tunable that allows you to force a
core when a "busy inodes after umount" problem occurs. It also changes
the classic error message to be something a bit less cryptic to users.

Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>

diff --git a/fs/block_dev.c b/fs/block_dev.c
diff --git a/fs/inode.c b/fs/inode.c
index 9a012cc..0e638b0 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -327,7 +327,7 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose)
count++;
continue;
}
- busy = 1;
+ ++busy;
}
/* only unused inodes may be cached with i_count zero */
inodes_stat.nr_unused -= count;
diff --git a/fs/super.c b/fs/super.c
index 5260d62..9c2871b 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -287,6 +287,8 @@ int fsync_super(struct super_block *sb)
void generic_shutdown_super(struct super_block *sb)
{
const struct super_operations *sop = sb->s_op;
+ extern int umount_debug;
+ int busy;

if (sb->s_root) {
shrink_dcache_for_umount(sb);
@@ -303,10 +305,15 @@ void generic_shutdown_super(struct super_block *sb)
sop->put_super(sb);

/* Forget any remaining inodes */
- if (invalidate_inodes(sb)) {
- printk("VFS: Busy inodes after unmount of %s. "
- "Self-destruct in 5 seconds. Have a nice day...\n",
- sb->s_id);
+ if (busy = invalidate_inodes(sb)) {
+ printk("VFS: %d busy inodes after unmount of %s. ",
+ busy, sb->s_id);
+ if (umount_debug != 0) {
+ printk("Crashing host on request.\n");
+ BUG();
+ } else {
+ printk("This machine will likely crash eventually. Consider a reboot.\n");
+ }
}

unlock_kernel();
diff --git a/include/linux/fs.h b/include/linux/fs.h
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 47f1c53..176b984 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -818,6 +818,7 @@ enum
FS_AIO_NR=18, /* current system-wide number of aio requests */
FS_AIO_MAX_NR=19, /* system-wide maximum number of aio requests */
FS_INOTIFY=20, /* inotify submenu */
+ FS_UMOUNT_DEBUG=21, /* busy inodes on umount debug switch */
FS_OCFS2=988, /* ocfs2 */
};

diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 30ee462..8e62c34 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -156,6 +156,7 @@ extern ctl_table pty_table[];
extern ctl_table inotify_table[];
#endif

+int umount_debug;
#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
int sysctl_legacy_va_layout;
#endif
@@ -962,6 +963,14 @@ static ctl_table fs_table[] = {
.mode = 0644,
.proc_handler = &proc_dointvec,
},
+ {
+ .ctl_name = FS_UMOUNT_DEBUG,
+ .procname = "umount_debug",
+ .data = &umount_debug,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
#ifdef CONFIG_DNOTIFY
{
.ctl_name = FS_DIR_NOTIFY,
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/