diff options
author | Ian Kent <raven@themaw.net> | 2005-06-21 20:16:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-21 22:07:35 -0400 |
commit | 9b1e3afd6d56937ced3914971621d0f053ea9178 (patch) | |
tree | 059762a20c069273247b423b6075adcd89624e42 | |
parent | 8818760512424f60ad9fafb7a087b007a9274eb3 (diff) |
[PATCH] autofs4: avoid panic on bind mount of autofs owned directory
While this is not a solution to bind and move mounts on autofs owned
directories it is necessary to fix the trady error handling.
At least it avoids the kernel panic I observed checking out bug #4589.
Signed-off-by: Ian Kent <raven@themaw.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | fs/autofs4/autofs_i.h | 13 | ||||
-rw-r--r-- | fs/autofs4/expire.c | 5 | ||||
-rw-r--r-- | fs/autofs4/root.c | 6 |
3 files changed, 19 insertions, 5 deletions
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index c7b2b8890188..9c09641ce907 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h | |||
@@ -185,6 +185,19 @@ int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify); | |||
185 | int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int); | 185 | int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int); |
186 | void autofs4_catatonic_mode(struct autofs_sb_info *); | 186 | void autofs4_catatonic_mode(struct autofs_sb_info *); |
187 | 187 | ||
188 | static inline int autofs4_follow_mount(struct vfsmount **mnt, struct dentry **dentry) | ||
189 | { | ||
190 | int res = 0; | ||
191 | |||
192 | while (d_mountpoint(*dentry)) { | ||
193 | int followed = follow_down(mnt, dentry); | ||
194 | if (!followed) | ||
195 | break; | ||
196 | res = 1; | ||
197 | } | ||
198 | return res; | ||
199 | } | ||
200 | |||
188 | static inline int simple_positive(struct dentry *dentry) | 201 | static inline int simple_positive(struct dentry *dentry) |
189 | { | 202 | { |
190 | return dentry->d_inode && !d_unhashed(dentry); | 203 | return dentry->d_inode && !d_unhashed(dentry); |
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 500425e24fba..feb6ac427d05 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c | |||
@@ -56,12 +56,9 @@ static int autofs4_check_mount(struct vfsmount *mnt, struct dentry *dentry) | |||
56 | mntget(mnt); | 56 | mntget(mnt); |
57 | dget(dentry); | 57 | dget(dentry); |
58 | 58 | ||
59 | if (!follow_down(&mnt, &dentry)) | 59 | if (!autofs4_follow_mount(&mnt, &dentry)) |
60 | goto done; | 60 | goto done; |
61 | 61 | ||
62 | while (d_mountpoint(dentry) && follow_down(&mnt, &dentry)) | ||
63 | ; | ||
64 | |||
65 | /* This is an autofs submount, we can't expire it */ | 62 | /* This is an autofs submount, we can't expire it */ |
66 | if (is_autofs4_dentry(dentry)) | 63 | if (is_autofs4_dentry(dentry)) |
67 | goto done; | 64 | goto done; |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 3765c047f157..e137acf0543d 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -205,7 +205,11 @@ static int autofs4_dir_open(struct inode *inode, struct file *file) | |||
205 | struct vfsmount *fp_mnt = mntget(mnt); | 205 | struct vfsmount *fp_mnt = mntget(mnt); |
206 | struct dentry *fp_dentry = dget(dentry); | 206 | struct dentry *fp_dentry = dget(dentry); |
207 | 207 | ||
208 | while (follow_down(&fp_mnt, &fp_dentry) && d_mountpoint(fp_dentry)); | 208 | if (!autofs4_follow_mount(&fp_mnt, &fp_dentry)) { |
209 | dput(fp_dentry); | ||
210 | mntput(fp_mnt); | ||
211 | return -ENOENT; | ||
212 | } | ||
209 | 213 | ||
210 | fp = dentry_open(fp_dentry, fp_mnt, file->f_flags); | 214 | fp = dentry_open(fp_dentry, fp_mnt, file->f_flags); |
211 | status = PTR_ERR(fp); | 215 | status = PTR_ERR(fp); |