aboutsummaryrefslogtreecommitdiffstats
path: root/fs/autofs4/inode.c
diff options
context:
space:
mode:
authorIan Kent <raven@themaw.net>2005-07-27 14:43:45 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-27 19:25:51 -0400
commit104e49fc1e1656142869fab0e75d7df52b72eed9 (patch)
tree4ba88793943da0fda56bbc98b404ea862ba89af6 /fs/autofs4/inode.c
parent0f94c8e1256fcb786e1918e30bdaeccf669bf63c (diff)
[PATCH] autofs4: fix infamous "Busy inodes after umount ..." message
If the automount daemon receives a signal which causes it to sumarily terminate the autofs4 module leaks dentries. The same problem exists with detached mount requests without the warning. This patch cleans these dentries at umount. Signed-off-by: Ian Kent <raven@themaw.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/autofs4/inode.c')
-rw-r--r--fs/autofs4/inode.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 4bb14cc68040..0a3c05d10167 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -16,6 +16,7 @@
16#include <linux/pagemap.h> 16#include <linux/pagemap.h>
17#include <linux/parser.h> 17#include <linux/parser.h>
18#include <linux/bitops.h> 18#include <linux/bitops.h>
19#include <linux/smp_lock.h>
19#include "autofs_i.h" 20#include "autofs_i.h"
20#include <linux/module.h> 21#include <linux/module.h>
21 22
@@ -76,6 +77,66 @@ void autofs4_free_ino(struct autofs_info *ino)
76 kfree(ino); 77 kfree(ino);
77} 78}
78 79
80/*
81 * Deal with the infamous "Busy inodes after umount ..." message.
82 *
83 * Clean up the dentry tree. This happens with autofs if the user
84 * space program goes away due to a SIGKILL, SIGSEGV etc.
85 */
86static void autofs4_force_release(struct autofs_sb_info *sbi)
87{
88 struct dentry *this_parent = sbi->root;
89 struct list_head *next;
90
91 spin_lock(&dcache_lock);
92repeat:
93 next = this_parent->d_subdirs.next;
94resume:
95 while (next != &this_parent->d_subdirs) {
96 struct dentry *dentry = list_entry(next, struct dentry, d_child);
97
98 /* Negative dentry - don`t care */
99 if (!simple_positive(dentry)) {
100 next = next->next;
101 continue;
102 }
103
104 if (!list_empty(&dentry->d_subdirs)) {
105 this_parent = dentry;
106 goto repeat;
107 }
108
109 next = next->next;
110 spin_unlock(&dcache_lock);
111
112 DPRINTK("dentry %p %.*s",
113 dentry, (int)dentry->d_name.len, dentry->d_name.name);
114
115 dput(dentry);
116 spin_lock(&dcache_lock);
117 }
118
119 if (this_parent != sbi->root) {
120 struct dentry *dentry = this_parent;
121
122 next = this_parent->d_child.next;
123 this_parent = this_parent->d_parent;
124 spin_unlock(&dcache_lock);
125 DPRINTK("parent dentry %p %.*s",
126 dentry, (int)dentry->d_name.len, dentry->d_name.name);
127 dput(dentry);
128 spin_lock(&dcache_lock);
129 goto resume;
130 }
131 spin_unlock(&dcache_lock);
132
133 dput(sbi->root);
134 sbi->root = NULL;
135 shrink_dcache_sb(sbi->sb);
136
137 return;
138}
139
79static void autofs4_put_super(struct super_block *sb) 140static void autofs4_put_super(struct super_block *sb)
80{ 141{
81 struct autofs_sb_info *sbi = autofs4_sbi(sb); 142 struct autofs_sb_info *sbi = autofs4_sbi(sb);
@@ -85,6 +146,10 @@ static void autofs4_put_super(struct super_block *sb)
85 if ( !sbi->catatonic ) 146 if ( !sbi->catatonic )
86 autofs4_catatonic_mode(sbi); /* Free wait queues, close pipe */ 147 autofs4_catatonic_mode(sbi); /* Free wait queues, close pipe */
87 148
149 /* Clean up and release dangling references */
150 if (sbi)
151 autofs4_force_release(sbi);
152
88 kfree(sbi); 153 kfree(sbi);
89 154
90 DPRINTK("shutting down"); 155 DPRINTK("shutting down");
@@ -199,6 +264,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
199 264
200 s->s_fs_info = sbi; 265 s->s_fs_info = sbi;
201 sbi->magic = AUTOFS_SBI_MAGIC; 266 sbi->magic = AUTOFS_SBI_MAGIC;
267 sbi->root = NULL;
202 sbi->catatonic = 0; 268 sbi->catatonic = 0;
203 sbi->exp_timeout = 0; 269 sbi->exp_timeout = 0;
204 sbi->oz_pgrp = process_group(current); 270 sbi->oz_pgrp = process_group(current);
@@ -267,6 +333,13 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
267 sbi->pipe = pipe; 333 sbi->pipe = pipe;
268 334
269 /* 335 /*
336 * Take a reference to the root dentry so we get a chance to
337 * clean up the dentry tree on umount.
338 * See autofs4_force_release.
339 */
340 sbi->root = dget(root);
341
342 /*
270 * Success! Install the root dentry now to indicate completion. 343 * Success! Install the root dentry now to indicate completion.
271 */ 344 */
272 s->s_root = root; 345 s->s_root = root;