[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>
This commit is contained in:
@@ -185,6 +185,19 @@ int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify);
|
|||||||
int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int);
|
int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int);
|
||||||
void autofs4_catatonic_mode(struct autofs_sb_info *);
|
void autofs4_catatonic_mode(struct autofs_sb_info *);
|
||||||
|
|
||||||
|
static inline int autofs4_follow_mount(struct vfsmount **mnt, struct dentry **dentry)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
while (d_mountpoint(*dentry)) {
|
||||||
|
int followed = follow_down(mnt, dentry);
|
||||||
|
if (!followed)
|
||||||
|
break;
|
||||||
|
res = 1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int simple_positive(struct dentry *dentry)
|
static inline int simple_positive(struct dentry *dentry)
|
||||||
{
|
{
|
||||||
return dentry->d_inode && !d_unhashed(dentry);
|
return dentry->d_inode && !d_unhashed(dentry);
|
||||||
|
@@ -56,12 +56,9 @@ static int autofs4_check_mount(struct vfsmount *mnt, struct dentry *dentry)
|
|||||||
mntget(mnt);
|
mntget(mnt);
|
||||||
dget(dentry);
|
dget(dentry);
|
||||||
|
|
||||||
if (!follow_down(&mnt, &dentry))
|
if (!autofs4_follow_mount(&mnt, &dentry))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
while (d_mountpoint(dentry) && follow_down(&mnt, &dentry))
|
|
||||||
;
|
|
||||||
|
|
||||||
/* This is an autofs submount, we can't expire it */
|
/* This is an autofs submount, we can't expire it */
|
||||||
if (is_autofs4_dentry(dentry))
|
if (is_autofs4_dentry(dentry))
|
||||||
goto done;
|
goto done;
|
||||||
|
@@ -205,7 +205,11 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
|
|||||||
struct vfsmount *fp_mnt = mntget(mnt);
|
struct vfsmount *fp_mnt = mntget(mnt);
|
||||||
struct dentry *fp_dentry = dget(dentry);
|
struct dentry *fp_dentry = dget(dentry);
|
||||||
|
|
||||||
while (follow_down(&fp_mnt, &fp_dentry) && d_mountpoint(fp_dentry));
|
if (!autofs4_follow_mount(&fp_mnt, &fp_dentry)) {
|
||||||
|
dput(fp_dentry);
|
||||||
|
mntput(fp_mnt);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
fp = dentry_open(fp_dentry, fp_mnt, file->f_flags);
|
fp = dentry_open(fp_dentry, fp_mnt, file->f_flags);
|
||||||
status = PTR_ERR(fp);
|
status = PTR_ERR(fp);
|
||||||
|
Reference in New Issue
Block a user