Pull vector-domain into release branch
[sfrench/cifs-2.6.git] / fs / namei.c
index 94b2f60aec22b8d25e697382182f7cebf047cc66..a83160acd7487328a0b86d318ac4e3427df7e329 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/quotaops.h>
 #include <linux/pagemap.h>
 #include <linux/fsnotify.h>
-#include <linux/smp_lock.h>
 #include <linux/personality.h>
 #include <linux/security.h>
 #include <linux/syscalls.h>
  * any extra contention...
  */
 
+static int fastcall link_path_walk(const char *name, struct nameidata *nd);
+
 /* In order to reduce some races, while at the same time doing additional
  * checking and hopefully speeding things up, we copy filenames to the
  * kernel data space before using them..
@@ -999,7 +1000,7 @@ return_err:
  * Retry the whole path once, forcing real lookup requests
  * instead of relying on the dcache.
  */
-int fastcall link_path_walk(const char *name, struct nameidata *nd)
+static int fastcall link_path_walk(const char *name, struct nameidata *nd)
 {
        struct nameidata save = *nd;
        int result;
@@ -1023,7 +1024,7 @@ int fastcall link_path_walk(const char *name, struct nameidata *nd)
        return result;
 }
 
-int fastcall path_walk(const char * name, struct nameidata *nd)
+static int fastcall path_walk(const char * name, struct nameidata *nd)
 {
        current->total_link_count = 0;
        return link_path_walk(name, nd);
@@ -1153,14 +1154,12 @@ static int fastcall do_path_lookup(int dfd, const char *name,
 
                fput_light(file, fput_needed);
        }
-       current->total_link_count = 0;
-       retval = link_path_walk(name, nd);
+
+       retval = path_walk(name, nd);
 out:
-       if (likely(retval == 0)) {
-               if (unlikely(!audit_dummy_context() && nd && nd->dentry &&
+       if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
                                nd->dentry->d_inode))
                audit_inode(name, nd->dentry->d_inode);
-       }
 out_fail:
        return retval;
 
@@ -1175,6 +1174,37 @@ int fastcall path_lookup(const char *name, unsigned int flags,
        return do_path_lookup(AT_FDCWD, name, flags, nd);
 }
 
+/**
+ * vfs_path_lookup - lookup a file path relative to a dentry-vfsmount pair
+ * @dentry:  pointer to dentry of the base directory
+ * @mnt: pointer to vfs mount of the base directory
+ * @name: pointer to file name
+ * @flags: lookup flags
+ * @nd: pointer to nameidata
+ */
+int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
+                   const char *name, unsigned int flags,
+                   struct nameidata *nd)
+{
+       int retval;
+
+       /* same as do_path_lookup */
+       nd->last_type = LAST_ROOT;
+       nd->flags = flags;
+       nd->depth = 0;
+
+       nd->mnt = mntget(mnt);
+       nd->dentry = dget(dentry);
+
+       retval = path_walk(name, nd);
+       if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
+                               nd->dentry->d_inode))
+               audit_inode(name, nd->dentry->d_inode);
+
+       return retval;
+
+}
+
 static int __path_lookup_intent_open(int dfd, const char *name,
                unsigned int lookup_flags, struct nameidata *nd,
                int open_flags, int create_mode)
@@ -1350,17 +1380,6 @@ struct dentry *lookup_one_len_kern(const char *name, struct dentry *base, int le
        return __lookup_hash_kern(&this, base, NULL);
 }
 
-/*
- *     namei()
- *
- * is used by most simple commands to get the inode of a specified name.
- * Open, link etc use their own routines, but this is enough for things
- * like 'chmod' etc.
- *
- * namei exists in two versions: namei/lnamei. The only difference is
- * that namei follows links, while lnamei does not.
- * SMP-safe
- */
 int fastcall __user_walk_fd(int dfd, const char __user *name, unsigned flags,
                            struct nameidata *nd)
 {
@@ -1590,7 +1609,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
 
        /* O_NOATIME can only be set by the owner or superuser */
        if (flag & O_NOATIME)
-               if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER))
+               if (!is_owner_or_cap(inode))
                        return -EPERM;
 
        /*
@@ -1733,7 +1752,7 @@ do_last:
         * It already exists.
         */
        mutex_unlock(&dir->d_inode->i_mutex);
-       audit_inode_update(path.dentry->d_inode);
+       audit_inode(pathname, path.dentry->d_inode);
 
        error = -EEXIST;
        if (flag & O_EXCL)
@@ -2788,8 +2807,8 @@ EXPORT_SYMBOL(__page_symlink);
 EXPORT_SYMBOL(page_symlink);
 EXPORT_SYMBOL(page_symlink_inode_operations);
 EXPORT_SYMBOL(path_lookup);
+EXPORT_SYMBOL(vfs_path_lookup);
 EXPORT_SYMBOL(path_release);
-EXPORT_SYMBOL(path_walk);
 EXPORT_SYMBOL(permission);
 EXPORT_SYMBOL(vfs_permission);
 EXPORT_SYMBOL(file_permission);