Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 5118
b: refs/heads/master
c: 104e49f
h: refs/heads/master
v: v3
  • Loading branch information
Ian Kent authored and Linus Torvalds committed Jul 27, 2005
1 parent 84d2606 commit 9b7d6c5
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0f94c8e1256fcb786e1918e30bdaeccf669bf63c
refs/heads/master: 104e49fc1e1656142869fab0e75d7df52b72eed9
1 change: 1 addition & 0 deletions trunk/fs/autofs4/autofs_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ struct autofs_wait_queue {

struct autofs_sb_info {
u32 magic;
struct dentry *root;
struct file *pipe;
pid_t oz_pgrp;
int catatonic;
Expand Down
73 changes: 73 additions & 0 deletions trunk/fs/autofs4/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/pagemap.h>
#include <linux/parser.h>
#include <linux/bitops.h>
#include <linux/smp_lock.h>
#include "autofs_i.h"
#include <linux/module.h>

Expand Down Expand Up @@ -76,6 +77,66 @@ void autofs4_free_ino(struct autofs_info *ino)
kfree(ino);
}

/*
* Deal with the infamous "Busy inodes after umount ..." message.
*
* Clean up the dentry tree. This happens with autofs if the user
* space program goes away due to a SIGKILL, SIGSEGV etc.
*/
static void autofs4_force_release(struct autofs_sb_info *sbi)
{
struct dentry *this_parent = sbi->root;
struct list_head *next;

spin_lock(&dcache_lock);
repeat:
next = this_parent->d_subdirs.next;
resume:
while (next != &this_parent->d_subdirs) {
struct dentry *dentry = list_entry(next, struct dentry, d_child);

/* Negative dentry - don`t care */
if (!simple_positive(dentry)) {
next = next->next;
continue;
}

if (!list_empty(&dentry->d_subdirs)) {
this_parent = dentry;
goto repeat;
}

next = next->next;
spin_unlock(&dcache_lock);

DPRINTK("dentry %p %.*s",
dentry, (int)dentry->d_name.len, dentry->d_name.name);

dput(dentry);
spin_lock(&dcache_lock);
}

if (this_parent != sbi->root) {
struct dentry *dentry = this_parent;

next = this_parent->d_child.next;
this_parent = this_parent->d_parent;
spin_unlock(&dcache_lock);
DPRINTK("parent dentry %p %.*s",
dentry, (int)dentry->d_name.len, dentry->d_name.name);
dput(dentry);
spin_lock(&dcache_lock);
goto resume;
}
spin_unlock(&dcache_lock);

dput(sbi->root);
sbi->root = NULL;
shrink_dcache_sb(sbi->sb);

return;
}

static void autofs4_put_super(struct super_block *sb)
{
struct autofs_sb_info *sbi = autofs4_sbi(sb);
Expand All @@ -85,6 +146,10 @@ static void autofs4_put_super(struct super_block *sb)
if ( !sbi->catatonic )
autofs4_catatonic_mode(sbi); /* Free wait queues, close pipe */

/* Clean up and release dangling references */
if (sbi)
autofs4_force_release(sbi);

kfree(sbi);

DPRINTK("shutting down");
Expand Down Expand Up @@ -199,6 +264,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)

s->s_fs_info = sbi;
sbi->magic = AUTOFS_SBI_MAGIC;
sbi->root = NULL;
sbi->catatonic = 0;
sbi->exp_timeout = 0;
sbi->oz_pgrp = process_group(current);
Expand Down Expand Up @@ -266,6 +332,13 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
goto fail_fput;
sbi->pipe = pipe;

/*
* Take a reference to the root dentry so we get a chance to
* clean up the dentry tree on umount.
* See autofs4_force_release.
*/
sbi->root = dget(root);

/*
* Success! Install the root dentry now to indicate completion.
*/
Expand Down

0 comments on commit 9b7d6c5

Please sign in to comment.