[PATCH] autofs4: avoid panic on bind mount of autofs owned directory
authorIan Kent <raven@themaw.net>
Wed, 22 Jun 2005 00:16:38 +0000 (17:16 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Wed, 22 Jun 2005 02:07:35 +0000 (19:07 -0700)
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>
fs/autofs4/autofs_i.h
fs/autofs4/expire.c
fs/autofs4/root.c

index c7b2b88..9c09641 100644 (file)
@@ -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);
 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)
 {
        return dentry->d_inode && !d_unhashed(dentry);
index 500425e..feb6ac4 100644 (file)
@@ -56,12 +56,9 @@ static int autofs4_check_mount(struct vfsmount *mnt, struct dentry *dentry)
        mntget(mnt);
        dget(dentry);
 
-       if (!follow_down(&mnt, &dentry))
+       if (!autofs4_follow_mount(&mnt, &dentry))
                goto done;
 
-       while (d_mountpoint(dentry) && follow_down(&mnt, &dentry))
-               ;
-
        /* This is an autofs submount, we can't expire it */
        if (is_autofs4_dentry(dentry))
                goto done;
index 3765c04..e137acf 100644 (file)
@@ -205,7 +205,11 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
                struct vfsmount *fp_mnt = mntget(mnt);
                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);
                status = PTR_ERR(fp);