[PATCH] autofs4: panic after mount fail

Resolve the panic on failed mount of an autofs filesystem originally
reported by Mao Bibo.

It addresses two issues that happen after the mount fail. The first a NULL
pointer reference to a field (pipe) in the autofs superblock info structure
and second the lack of super block cleanup by the autofs and autofs4
modules.

Signed-off-by: Ian Kent <raven@themaw.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Ian Kent and committed by Linus Torvalds ba8df43c 6a34b57b

+32 -6
+13 -1
fs/autofs/inode.c
··· 25 25 struct autofs_sb_info *sbi = autofs_sbi(sb); 26 26 unsigned int n; 27 27 28 + /* 29 + * In the event of a failure in get_sb_nodev the superblock 30 + * info is not present so nothing else has been setup, so 31 + * just exit when we are called from deactivate_super. 32 + */ 33 + if (!sbi) 34 + return; 35 + 28 36 if ( !sbi->catatonic ) 29 37 autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */ 30 38 ··· 144 136 145 137 s->s_fs_info = sbi; 146 138 sbi->magic = AUTOFS_SBI_MAGIC; 147 - sbi->catatonic = 0; 139 + sbi->pipe = NULL; 140 + sbi->catatonic = 1; 148 141 sbi->exp_timeout = 0; 149 142 sbi->oz_pgrp = process_group(current); 150 143 autofs_initialize_hash(&sbi->dirhash); ··· 189 180 if ( !pipe->f_op || !pipe->f_op->write ) 190 181 goto fail_fput; 191 182 sbi->pipe = pipe; 183 + sbi->catatonic = 0; 192 184 193 185 /* 194 186 * Success! Install the root dentry now to indicate completion. ··· 208 198 iput(root_inode); 209 199 fail_free: 210 200 kfree(sbi); 201 + s->s_fs_info = NULL; 202 + kill_anon_super(s); 211 203 fail_unlock: 212 204 return -EINVAL; 213 205 }
+1
fs/autofs/waitq.c
··· 41 41 wq = nwq; 42 42 } 43 43 fput(sbi->pipe); /* Close the pipe */ 44 + sbi->pipe = NULL; 44 45 autofs_hash_dputall(&sbi->dirhash); /* Remove all dentry pointers */ 45 46 } 46 47
+16 -1
fs/autofs4/inode.c
··· 99 99 struct dentry *this_parent = sbi->sb->s_root; 100 100 struct list_head *next; 101 101 102 + if (!sbi->sb->s_root) 103 + return; 104 + 102 105 spin_lock(&dcache_lock); 103 106 repeat: 104 107 next = this_parent->d_subdirs.next; ··· 148 145 void autofs4_kill_sb(struct super_block *sb) 149 146 { 150 147 struct autofs_sb_info *sbi = autofs4_sbi(sb); 148 + 149 + /* 150 + * In the event of a failure in get_sb_nodev the superblock 151 + * info is not present so nothing else has been setup, so 152 + * just exit when we are called from deactivate_super. 153 + */ 154 + if (!sbi) 155 + return; 151 156 152 157 sb->s_fs_info = NULL; 153 158 ··· 321 310 s->s_fs_info = sbi; 322 311 sbi->magic = AUTOFS_SBI_MAGIC; 323 312 sbi->pipefd = -1; 324 - sbi->catatonic = 0; 313 + sbi->pipe = NULL; 314 + sbi->catatonic = 1; 325 315 sbi->exp_timeout = 0; 326 316 sbi->oz_pgrp = process_group(current); 327 317 sbi->sb = s; ··· 400 388 goto fail_fput; 401 389 sbi->pipe = pipe; 402 390 sbi->pipefd = pipefd; 391 + sbi->catatonic = 0; 403 392 404 393 /* 405 394 * Success! Install the root dentry now to indicate completion. ··· 425 412 kfree(ino); 426 413 fail_free: 427 414 kfree(sbi); 415 + s->s_fs_info = NULL; 416 + kill_anon_super(s); 428 417 fail_unlock: 429 418 return -EINVAL; 430 419 }
+2 -4
fs/autofs4/waitq.c
··· 41 41 wake_up_interruptible(&wq->queue); 42 42 wq = nwq; 43 43 } 44 - if (sbi->pipe) { 45 - fput(sbi->pipe); /* Close the pipe */ 46 - sbi->pipe = NULL; 47 - } 44 + fput(sbi->pipe); /* Close the pipe */ 45 + sbi->pipe = NULL; 48 46 } 49 47 50 48 static int autofs4_write(struct file *file, const void *addr, int bytes)