aboutsummaryrefslogtreecommitdiffstats
path: root/fs/autofs4/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/autofs4/inode.c')
-rw-r--r--fs/autofs4/inode.c63
1 files changed, 2 insertions, 61 deletions
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 69c8142da838..821b2b955dac 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -49,6 +49,7 @@ struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
49 ino->dentry = NULL; 49 ino->dentry = NULL;
50 ino->size = 0; 50 ino->size = 0;
51 INIT_LIST_HEAD(&ino->active); 51 INIT_LIST_HEAD(&ino->active);
52 ino->active_count = 0;
52 INIT_LIST_HEAD(&ino->expiring); 53 INIT_LIST_HEAD(&ino->expiring);
53 atomic_set(&ino->count, 0); 54 atomic_set(&ino->count, 0);
54 } 55 }
@@ -95,63 +96,6 @@ void autofs4_free_ino(struct autofs_info *ino)
95 kfree(ino); 96 kfree(ino);
96} 97}
97 98
98/*
99 * Deal with the infamous "Busy inodes after umount ..." message.
100 *
101 * Clean up the dentry tree. This happens with autofs if the user
102 * space program goes away due to a SIGKILL, SIGSEGV etc.
103 */
104static void autofs4_force_release(struct autofs_sb_info *sbi)
105{
106 struct dentry *this_parent = sbi->sb->s_root;
107 struct list_head *next;
108
109 if (!sbi->sb->s_root)
110 return;
111
112 spin_lock(&dcache_lock);
113repeat:
114 next = this_parent->d_subdirs.next;
115resume:
116 while (next != &this_parent->d_subdirs) {
117 struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
118
119 /* Negative dentry - don`t care */
120 if (!simple_positive(dentry)) {
121 next = next->next;
122 continue;
123 }
124
125 if (!list_empty(&dentry->d_subdirs)) {
126 this_parent = dentry;
127 goto repeat;
128 }
129
130 next = next->next;
131 spin_unlock(&dcache_lock);
132
133 DPRINTK("dentry %p %.*s",
134 dentry, (int)dentry->d_name.len, dentry->d_name.name);
135
136 dput(dentry);
137 spin_lock(&dcache_lock);
138 }
139
140 if (this_parent != sbi->sb->s_root) {
141 struct dentry *dentry = this_parent;
142
143 next = this_parent->d_u.d_child.next;
144 this_parent = this_parent->d_parent;
145 spin_unlock(&dcache_lock);
146 DPRINTK("parent dentry %p %.*s",
147 dentry, (int)dentry->d_name.len, dentry->d_name.name);
148 dput(dentry);
149 spin_lock(&dcache_lock);
150 goto resume;
151 }
152 spin_unlock(&dcache_lock);
153}
154
155void autofs4_kill_sb(struct super_block *sb) 99void autofs4_kill_sb(struct super_block *sb)
156{ 100{
157 struct autofs_sb_info *sbi = autofs4_sbi(sb); 101 struct autofs_sb_info *sbi = autofs4_sbi(sb);
@@ -168,15 +112,12 @@ void autofs4_kill_sb(struct super_block *sb)
168 /* Free wait queues, close pipe */ 112 /* Free wait queues, close pipe */
169 autofs4_catatonic_mode(sbi); 113 autofs4_catatonic_mode(sbi);
170 114
171 /* Clean up and release dangling references */
172 autofs4_force_release(sbi);
173
174 sb->s_fs_info = NULL; 115 sb->s_fs_info = NULL;
175 kfree(sbi); 116 kfree(sbi);
176 117
177out_kill_sb: 118out_kill_sb:
178 DPRINTK("shutting down"); 119 DPRINTK("shutting down");
179 kill_anon_super(sb); 120 kill_litter_super(sb);
180} 121}
181 122
182static int autofs4_show_options(struct seq_file *m, struct vfsmount *mnt) 123static int autofs4_show_options(struct seq_file *m, struct vfsmount *mnt)