#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..
* 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;
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);
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;
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)
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)
{
/* 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;
/*
* 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)
struct address_space *mapping = dentry->d_inode->i_mapping;
page = read_mapping_page(mapping, 0, NULL);
if (IS_ERR(page))
- goto sync_fail;
- wait_on_page_locked(page);
- if (!PageUptodate(page))
- goto async_fail;
+ return (char*)page;
*ppage = page;
return kmap(page);
-
-async_fail:
- page_cache_release(page);
- return ERR_PTR(-EIO);
-
-sync_fail:
- return (char*)page;
}
int page_readlink(struct dentry *dentry, char __user *buffer, int buflen)
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);