nfsd: move most of nfsfh.h to fs/nfsd
[safe/jmp/linux-2.6] / fs / autofs4 / waitq.c
index 6d87bb1..2341375 100644 (file)
@@ -297,20 +297,14 @@ static int validate_request(struct autofs_wait_queue **wait,
         */
        if (notify == NFY_MOUNT) {
                /*
-                * If the dentry isn't hashed just go ahead and try the
-                * mount again with a new wait (not much else we can do).
-               */
-               if (!d_unhashed(dentry)) {
-                       /*
-                        * But if the dentry is hashed, that means that we
-                        * got here through the revalidate path.  Thus, we
-                        * need to check if the dentry has been mounted
-                        * while we waited on the wq_mutex. If it has,
-                        * simply return success.
-                        */
-                       if (d_mountpoint(dentry))
-                               return 0;
-               }
+                * If the dentry was successfully mounted while we slept
+                * on the wait queue mutex we can return success. If it
+                * isn't mounted (doesn't have submounts for the case of
+                * a multi-mount with no mount at it's base) we can
+                * continue on and create a new request.
+                */
+               if (have_submounts(dentry))
+                       return 0;
        }
 
        return 1;
@@ -337,7 +331,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
                 * is very similar for indirect mounts except only dentrys
                 * in the root of the autofs file system may be negative.
                 */
-               if (sbi->type & AUTOFS_TYPE_TRIGGER)
+               if (autofs_type_trigger(sbi->type))
                        return -ENOENT;
                else if (!IS_ROOT(dentry->d_parent))
                        return -ENOENT;
@@ -348,7 +342,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
                return -ENOMEM;
 
        /* If this is a direct mount request create a dummy name */
-       if (IS_ROOT(dentry) && sbi->type & AUTOFS_TYPE_TRIGGER)
+       if (IS_ROOT(dentry) && autofs_type_trigger(sbi->type))
                qstr.len = sprintf(name, "%p", dentry);
        else {
                qstr.len = autofs4_getpath(sbi, dentry, &name);
@@ -391,8 +385,8 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
                memcpy(&wq->name, &qstr, sizeof(struct qstr));
                wq->dev = autofs4_get_dev(sbi);
                wq->ino = autofs4_get_ino(sbi);
-               wq->uid = current->uid;
-               wq->gid = current->gid;
+               wq->uid = current_uid();
+               wq->gid = current_gid();
                wq->pid = current->pid;
                wq->tgid = current->tgid;
                wq->status = -EINTR; /* Status return if interrupted */
@@ -406,11 +400,11 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
                                type = autofs_ptype_expire_multi;
                } else {
                        if (notify == NFY_MOUNT)
-                               type = (sbi->type & AUTOFS_TYPE_TRIGGER) ?
+                               type = autofs_type_trigger(sbi->type) ?
                                        autofs_ptype_missing_direct :
                                         autofs_ptype_missing_indirect;
                        else
-                               type = (sbi->type & AUTOFS_TYPE_TRIGGER) ?
+                               type = autofs_type_trigger(sbi->type) ?
                                        autofs_ptype_expire_direct :
                                        autofs_ptype_expire_indirect;
                }
@@ -457,6 +451,40 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
 
        status = wq->status;
 
+       /*
+        * For direct and offset mounts we need to track the requester's
+        * uid and gid in the dentry info struct. This is so it can be
+        * supplied, on request, by the misc device ioctl interface.
+        * This is needed during daemon resatart when reconnecting
+        * to existing, active, autofs mounts. The uid and gid (and
+        * related string values) may be used for macro substitution
+        * in autofs mount maps.
+        */
+       if (!status) {
+               struct autofs_info *ino;
+               struct dentry *de = NULL;
+
+               /* direct mount or browsable map */
+               ino = autofs4_dentry_ino(dentry);
+               if (!ino) {
+                       /* If not lookup actual dentry used */
+                       de = d_lookup(dentry->d_parent, &dentry->d_name);
+                       if (de)
+                               ino = autofs4_dentry_ino(de);
+               }
+
+               /* Set mount requester */
+               if (ino) {
+                       spin_lock(&sbi->fs_lock);
+                       ino->uid = wq->uid;
+                       ino->gid = wq->gid;
+                       spin_unlock(&sbi->fs_lock);
+               }
+
+               if (de)
+                       dput(de);
+       }
+
        /* Are we the last process to need status? */
        mutex_lock(&sbi->wq_mutex);
        if (!--wq->wait_ctr)