]> Pileus Git - ~andy/linux/blobdiff - fs/namei.c
Merge branch 'for-38-rc2' of git://codeaurora.org/quic/kernel/davidb/linux-msm
[~andy/linux] / fs / namei.c
index 5c89695ae1e47754fc4e716854b3b8f6902f8f7c..7d77f24d32a98a115e320605369006eeef30ae0d 100644 (file)
@@ -367,18 +367,6 @@ void path_get(struct path *path)
 }
 EXPORT_SYMBOL(path_get);
 
-/**
- * path_get_long - get a long reference to a path
- * @path: path to get the reference to
- *
- * Given a path increment the reference count to the dentry and the vfsmount.
- */
-void path_get_long(struct path *path)
-{
-       mntget_long(path->mnt);
-       dget(path->dentry);
-}
-
 /**
  * path_put - put a reference to a path
  * @path: path to put the reference to
@@ -392,18 +380,6 @@ void path_put(struct path *path)
 }
 EXPORT_SYMBOL(path_put);
 
-/**
- * path_put_long - put a long reference to a path
- * @path: path to put the reference to
- *
- * Given a path decrement the reference count to the dentry and the vfsmount.
- */
-void path_put_long(struct path *path)
-{
-       dput(path->dentry);
-       mntput_long(path->mnt);
-}
-
 /**
  * nameidata_drop_rcu - drop this nameidata out of rcu-walk
  * @nd: nameidata pathwalk data to drop
@@ -900,6 +876,7 @@ static int follow_automount(struct path *path, unsigned flags,
                            bool *need_mntput)
 {
        struct vfsmount *mnt;
+       int err;
 
        if (!path->dentry->d_op || !path->dentry->d_op->d_automount)
                return -EREMOTE;
@@ -942,22 +919,28 @@ static int follow_automount(struct path *path, unsigned flags,
                        return -EREMOTE;
                return PTR_ERR(mnt);
        }
+
        if (!mnt) /* mount collision */
                return 0;
 
-       if (mnt->mnt_sb == path->mnt->mnt_sb &&
-           mnt->mnt_root == path->dentry) {
-               mntput(mnt);
-               return -ELOOP;
+       err = finish_automount(mnt, path);
+
+       switch (err) {
+       case -EBUSY:
+               /* Someone else made a mount here whilst we were busy */
+               return 0;
+       case 0:
+               dput(path->dentry);
+               if (*need_mntput)
+                       mntput(path->mnt);
+               path->mnt = mnt;
+               path->dentry = dget(mnt->mnt_root);
+               *need_mntput = true;
+               return 0;
+       default:
+               return err;
        }
 
-       dput(path->dentry);
-       if (*need_mntput)
-               mntput(path->mnt);
-       path->mnt = mnt;
-       path->dentry = dget(mnt->mnt_root);
-       *need_mntput = true;
-       return 0;
 }
 
 /*
@@ -1289,8 +1272,10 @@ done:
        path->mnt = mnt;
        path->dentry = dentry;
        err = follow_managed(path, nd->flags);
-       if (unlikely(err < 0))
+       if (unlikely(err < 0)) {
+               path_put_conditional(path, nd);
                return err;
+       }
        *inode = path->dentry->d_inode;
        return 0;