Commit 9f636537 authored by Patrick Mochel's avatar Patrick Mochel Committed by Patrick Mochel

Fix driverfs deadlock on file/directory removal

parent da5550b2
...@@ -584,29 +584,6 @@ driverfs_create_file(struct driver_file_entry * entry, ...@@ -584,29 +584,6 @@ driverfs_create_file(struct driver_file_entry * entry,
return error; return error;
} }
/**
* __remove_file - remove a regular file in the filesystem
* @dentry: dentry of file to remove
*
* Call unlink to remove the file, and dput on the dentry to drop
* the refcount.
*/
static void __remove_file(struct dentry * dentry)
{
dget(dentry);
down(&dentry->d_inode->i_sem);
vfs_unlink(dentry->d_parent->d_inode,dentry);
up(&dentry->d_inode->i_sem);
dput(dentry);
/* remove reference count from when file was created */
dput(dentry);
put_mount();
}
/** /**
* driverfs_remove_file - exported file removal * driverfs_remove_file - exported file removal
* @dir: directory the file supposedly resides in * @dir: directory the file supposedly resides in
...@@ -617,14 +594,12 @@ static void __remove_file(struct dentry * dentry) ...@@ -617,14 +594,12 @@ static void __remove_file(struct dentry * dentry)
*/ */
void driverfs_remove_file(struct driver_dir_entry * dir, const char * name) void driverfs_remove_file(struct driver_dir_entry * dir, const char * name)
{ {
struct dentry * dentry;
struct list_head * node; struct list_head * node;
if (!dir->dentry) if (!dir->dentry)
return; return;
dentry = dget(dir->dentry); down(&dir->dentry->d_inode->i_sem);
down(&dentry->d_inode->i_sem);
node = dir->files.next; node = dir->files.next;
while (node != &dir->files) { while (node != &dir->files) {
...@@ -633,14 +608,13 @@ void driverfs_remove_file(struct driver_dir_entry * dir, const char * name) ...@@ -633,14 +608,13 @@ void driverfs_remove_file(struct driver_dir_entry * dir, const char * name)
entry = list_entry(node,struct driver_file_entry,node); entry = list_entry(node,struct driver_file_entry,node);
if (!strcmp(entry->name,name)) { if (!strcmp(entry->name,name)) {
list_del_init(node); list_del_init(node);
vfs_unlink(entry->dentry->d_parent->d_inode,entry->dentry);
__remove_file(entry->dentry); put_mount();
break; break;
} }
node = node->next; node = node->next;
} }
up(&dentry->d_inode->i_sem); up(&dir->dentry->d_inode->i_sem);
dput(dentry);
} }
/** /**
...@@ -669,15 +643,14 @@ void driverfs_remove_dir(struct driver_dir_entry * dir) ...@@ -669,15 +643,14 @@ void driverfs_remove_dir(struct driver_dir_entry * dir)
entry = list_entry(node,struct driver_file_entry,node); entry = list_entry(node,struct driver_file_entry,node);
list_del_init(node); list_del_init(node);
vfs_unlink(dentry->d_inode,entry->dentry);
__remove_file(entry->dentry); put_mount();
node = dir->files.next; node = dir->files.next;
} }
up(&dentry->d_inode->i_sem);
vfs_rmdir(dentry->d_parent->d_inode,dentry); vfs_rmdir(dentry->d_parent->d_inode,dentry);
up(&dentry->d_parent->d_inode->i_sem); up(&dentry->d_parent->d_inode->i_sem);
up(&dentry->d_inode->i_sem);
dput(dentry); dput(dentry);
done: done:
put_mount(); put_mount();
......
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