]> Pileus Git - ~andy/linux/blobdiff - fs/autofs4/waitq.c
autofs4: Fix wait validation
[~andy/linux] / fs / autofs4 / waitq.c
index 4be8f778a4189872a6956be82d57c19ff2ba9e83..56010056b2e6d9001280597b73146ccb839d1b87 100644 (file)
@@ -194,14 +194,15 @@ static int autofs4_getpath(struct autofs_sb_info *sbi,
 rename_retry:
        buf = *name;
        len = 0;
+
        seq = read_seqbegin(&rename_lock);
        rcu_read_lock();
-       spin_lock(&dcache_lock);
+       spin_lock(&autofs4_lock);
        for (tmp = dentry ; tmp != root ; tmp = tmp->d_parent)
                len += tmp->d_name.len + 1;
 
        if (!len || --len > NAME_MAX) {
-               spin_unlock(&dcache_lock);
+               spin_unlock(&autofs4_lock);
                rcu_read_unlock();
                if (read_seqretry(&rename_lock, seq))
                        goto rename_retry;
@@ -217,7 +218,7 @@ rename_retry:
                p -= tmp->d_name.len;
                strncpy(p, tmp->d_name.name, tmp->d_name.len);
        }
-       spin_unlock(&dcache_lock);
+       spin_unlock(&autofs4_lock);
        rcu_read_unlock();
        if (read_seqretry(&rename_lock, seq))
                goto rename_retry;
@@ -308,6 +309,9 @@ static int validate_request(struct autofs_wait_queue **wait,
         * completed while we waited on the mutex ...
         */
        if (notify == NFY_MOUNT) {
+               struct dentry *new = NULL;
+               int valid = 1;
+
                /*
                 * If the dentry was successfully mounted while we slept
                 * on the wait queue mutex we can return success. If it
@@ -315,8 +319,20 @@ static int validate_request(struct autofs_wait_queue **wait,
                 * a multi-mount with no mount at it's base) we can
                 * continue on and create a new request.
                 */
+               if (!IS_ROOT(dentry)) {
+                       if (dentry->d_inode && d_unhashed(dentry)) {
+                               struct dentry *parent = dentry->d_parent;
+                               new = d_lookup(parent, &dentry->d_name);
+                               if (new)
+                                       dentry = new;
+                       }
+               }
                if (have_submounts(dentry))
-                       return 0;
+                       valid = 0;
+
+               if (new)
+                       dput(new);
+               return valid;
        }
 
        return 1;