Commit 04af9e58 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] is_devfsd_or_child() deadlock fix

From: Andrey Borzenkov <arvidjaar@mail.ru>

The code that did proper check existed in 2.4 and was removed in 2.5 for
whatever reason. The patch restores it slightly modified as below.

2.4 code looks somewhat unclean in that

- it traverses task list without lock.

- it starts from current->real_parent but nothing prevents current be
  init_task itself.  This hung for me on 2.5 during boot.  May be 2.4 does
  something differently.
parent 57732625
...@@ -676,6 +676,7 @@ ...@@ -676,6 +676,7 @@
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/version.h> #include <linux/version.h>
#include <linux/rwsem.h> #include <linux/rwsem.h>
#include <linux/sched.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -1325,8 +1326,20 @@ static void free_dentry (struct devfs_entry *de) ...@@ -1325,8 +1326,20 @@ static void free_dentry (struct devfs_entry *de)
static int is_devfsd_or_child (struct fs_info *fs_info) static int is_devfsd_or_child (struct fs_info *fs_info)
{ {
if (current == fs_info->devfsd_task) return (TRUE); struct task_struct *p = current;
if (current->pgrp == fs_info->devfsd_pgrp) return (TRUE);
if (p == fs_info->devfsd_task) return (TRUE);
if (p->pgrp == fs_info->devfsd_pgrp) return (TRUE);
read_lock(&tasklist_lock);
for ( ; p != &init_task; p = p->real_parent)
{
if (p == fs_info->devfsd_task)
{
read_unlock (&tasklist_lock);
return (TRUE);
}
}
read_unlock (&tasklist_lock);
return (FALSE); return (FALSE);
} /* End Function is_devfsd_or_child */ } /* End Function is_devfsd_or_child */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment