Merge branch 'work.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs namei updates from Al Viro: "Pathwalk-related stuff" [ Audit-related cleanups, misc simplifications, and easier to follow nd->root refcounts - Linus ] * 'work.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: devpts_pty_kill(): don't bother with d_delete() infiniband: don't bother with d_delete() hypfs: don't bother with d_delete() fs/namei.c: keep track of nd->root refcount status fs/namei.c: new helper - legitimize_root() kill the last users of user_{path,lpath,path_dir}() namei.h: get the comments on LOOKUP_... in sync with reality kill LOOKUP_NO_EVAL, don't bother including namei.h from audit.h audit_inode(): switch to passing AUDIT_INODE_... filename_mountpoint(): make LOOKUP_NO_EVAL unconditional there filename_lookup(): audit_inode() argument is always 0
This commit is contained in:
commit
53e5e7a7a7
|
@ -76,7 +76,7 @@ static void hypfs_remove(struct dentry *dentry)
|
||||||
else
|
else
|
||||||
simple_unlink(d_inode(parent), dentry);
|
simple_unlink(d_inode(parent), dentry);
|
||||||
}
|
}
|
||||||
d_delete(dentry);
|
d_drop(dentry);
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
inode_unlock(d_inode(parent));
|
inode_unlock(d_inode(parent));
|
||||||
}
|
}
|
||||||
|
|
|
@ -493,7 +493,7 @@ static int remove_device_files(struct super_block *sb,
|
||||||
remove_file(dir, "flash");
|
remove_file(dir, "flash");
|
||||||
inode_unlock(d_inode(dir));
|
inode_unlock(d_inode(dir));
|
||||||
ret = simple_rmdir(d_inode(root), dir);
|
ret = simple_rmdir(d_inode(root), dir);
|
||||||
d_delete(dir);
|
d_drop(dir);
|
||||||
dput(dir);
|
dput(dir);
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
|
|
|
@ -63,11 +63,8 @@ static long coda_pioctl(struct file *filp, unsigned int cmd,
|
||||||
* Look up the pathname. Note that the pathname is in
|
* Look up the pathname. Note that the pathname is in
|
||||||
* user memory, and namei takes care of this
|
* user memory, and namei takes care of this
|
||||||
*/
|
*/
|
||||||
if (data.follow)
|
error = user_path_at(AT_FDCWD, data.path,
|
||||||
error = user_path(data.path, &path);
|
data.follow ? LOOKUP_FOLLOW : 0, &path);
|
||||||
else
|
|
||||||
error = user_lpath(data.path, &path);
|
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
|
|
@ -622,7 +622,7 @@ void devpts_pty_kill(struct dentry *dentry)
|
||||||
dentry->d_fsdata = NULL;
|
dentry->d_fsdata = NULL;
|
||||||
drop_nlink(dentry->d_inode);
|
drop_nlink(dentry->d_inode);
|
||||||
fsnotify_unlink(d_inode(dentry->d_parent), dentry);
|
fsnotify_unlink(d_inode(dentry->d_parent), dentry);
|
||||||
d_delete(dentry);
|
d_drop(dentry);
|
||||||
dput(dentry); /* d_alloc_name() in devpts_pty_new() */
|
dput(dentry); /* d_alloc_name() in devpts_pty_new() */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
64
fs/namei.c
64
fs/namei.c
|
@ -596,14 +596,12 @@ static void terminate_walk(struct nameidata *nd)
|
||||||
path_put(&nd->path);
|
path_put(&nd->path);
|
||||||
for (i = 0; i < nd->depth; i++)
|
for (i = 0; i < nd->depth; i++)
|
||||||
path_put(&nd->stack[i].link);
|
path_put(&nd->stack[i].link);
|
||||||
if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) {
|
if (nd->flags & LOOKUP_ROOT_GRABBED) {
|
||||||
path_put(&nd->root);
|
path_put(&nd->root);
|
||||||
nd->root.mnt = NULL;
|
nd->flags &= ~LOOKUP_ROOT_GRABBED;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nd->flags &= ~LOOKUP_RCU;
|
nd->flags &= ~LOOKUP_RCU;
|
||||||
if (!(nd->flags & LOOKUP_ROOT))
|
|
||||||
nd->root.mnt = NULL;
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
nd->depth = 0;
|
nd->depth = 0;
|
||||||
|
@ -641,6 +639,14 @@ static bool legitimize_links(struct nameidata *nd)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool legitimize_root(struct nameidata *nd)
|
||||||
|
{
|
||||||
|
if (!nd->root.mnt || (nd->flags & LOOKUP_ROOT))
|
||||||
|
return true;
|
||||||
|
nd->flags |= LOOKUP_ROOT_GRABBED;
|
||||||
|
return legitimize_path(nd, &nd->root, nd->root_seq);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Path walking has 2 modes, rcu-walk and ref-walk (see
|
* Path walking has 2 modes, rcu-walk and ref-walk (see
|
||||||
* Documentation/filesystems/path-lookup.txt). In situations when we can't
|
* Documentation/filesystems/path-lookup.txt). In situations when we can't
|
||||||
|
@ -671,23 +677,18 @@ static int unlazy_walk(struct nameidata *nd)
|
||||||
|
|
||||||
nd->flags &= ~LOOKUP_RCU;
|
nd->flags &= ~LOOKUP_RCU;
|
||||||
if (unlikely(!legitimize_links(nd)))
|
if (unlikely(!legitimize_links(nd)))
|
||||||
goto out2;
|
|
||||||
if (unlikely(!legitimize_path(nd, &nd->path, nd->seq)))
|
|
||||||
goto out1;
|
goto out1;
|
||||||
if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) {
|
if (unlikely(!legitimize_path(nd, &nd->path, nd->seq)))
|
||||||
if (unlikely(!legitimize_path(nd, &nd->root, nd->root_seq)))
|
goto out;
|
||||||
goto out;
|
if (unlikely(!legitimize_root(nd)))
|
||||||
}
|
goto out;
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
BUG_ON(nd->inode != parent->d_inode);
|
BUG_ON(nd->inode != parent->d_inode);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out2:
|
out1:
|
||||||
nd->path.mnt = NULL;
|
nd->path.mnt = NULL;
|
||||||
nd->path.dentry = NULL;
|
nd->path.dentry = NULL;
|
||||||
out1:
|
|
||||||
if (!(nd->flags & LOOKUP_ROOT))
|
|
||||||
nd->root.mnt = NULL;
|
|
||||||
out:
|
out:
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
return -ECHILD;
|
return -ECHILD;
|
||||||
|
@ -727,23 +728,14 @@ static int unlazy_child(struct nameidata *nd, struct dentry *dentry, unsigned se
|
||||||
*/
|
*/
|
||||||
if (unlikely(!lockref_get_not_dead(&dentry->d_lockref)))
|
if (unlikely(!lockref_get_not_dead(&dentry->d_lockref)))
|
||||||
goto out;
|
goto out;
|
||||||
if (unlikely(read_seqcount_retry(&dentry->d_seq, seq))) {
|
if (unlikely(read_seqcount_retry(&dentry->d_seq, seq)))
|
||||||
rcu_read_unlock();
|
goto out_dput;
|
||||||
dput(dentry);
|
|
||||||
goto drop_root_mnt;
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* Sequence counts matched. Now make sure that the root is
|
* Sequence counts matched. Now make sure that the root is
|
||||||
* still valid and get it if required.
|
* still valid and get it if required.
|
||||||
*/
|
*/
|
||||||
if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) {
|
if (unlikely(!legitimize_root(nd)))
|
||||||
if (unlikely(!legitimize_path(nd, &nd->root, nd->root_seq))) {
|
goto out_dput;
|
||||||
rcu_read_unlock();
|
|
||||||
dput(dentry);
|
|
||||||
return -ECHILD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -753,9 +745,10 @@ out1:
|
||||||
nd->path.dentry = NULL;
|
nd->path.dentry = NULL;
|
||||||
out:
|
out:
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
drop_root_mnt:
|
return -ECHILD;
|
||||||
if (!(nd->flags & LOOKUP_ROOT))
|
out_dput:
|
||||||
nd->root.mnt = NULL;
|
rcu_read_unlock();
|
||||||
|
dput(dentry);
|
||||||
return -ECHILD;
|
return -ECHILD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -819,6 +812,7 @@ static void set_root(struct nameidata *nd)
|
||||||
} while (read_seqcount_retry(&fs->seq, seq));
|
} while (read_seqcount_retry(&fs->seq, seq));
|
||||||
} else {
|
} else {
|
||||||
get_fs_root(fs, &nd->root);
|
get_fs_root(fs, &nd->root);
|
||||||
|
nd->flags |= LOOKUP_ROOT_GRABBED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1735,8 +1729,6 @@ static int pick_link(struct nameidata *nd, struct path *link,
|
||||||
nd->flags &= ~LOOKUP_RCU;
|
nd->flags &= ~LOOKUP_RCU;
|
||||||
nd->path.mnt = NULL;
|
nd->path.mnt = NULL;
|
||||||
nd->path.dentry = NULL;
|
nd->path.dentry = NULL;
|
||||||
if (!(nd->flags & LOOKUP_ROOT))
|
|
||||||
nd->root.mnt = NULL;
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
} else if (likely(unlazy_walk(nd)) == 0)
|
} else if (likely(unlazy_walk(nd)) == 0)
|
||||||
error = nd_alloc_stack(nd);
|
error = nd_alloc_stack(nd);
|
||||||
|
@ -2350,7 +2342,7 @@ int filename_lookup(int dfd, struct filename *name, unsigned flags,
|
||||||
retval = path_lookupat(&nd, flags | LOOKUP_REVAL, path);
|
retval = path_lookupat(&nd, flags | LOOKUP_REVAL, path);
|
||||||
|
|
||||||
if (likely(!retval))
|
if (likely(!retval))
|
||||||
audit_inode(name, path->dentry, flags & LOOKUP_PARENT);
|
audit_inode(name, path->dentry, 0);
|
||||||
restore_nameidata();
|
restore_nameidata();
|
||||||
putname(name);
|
putname(name);
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -2391,7 +2383,7 @@ static struct filename *filename_parentat(int dfd, struct filename *name,
|
||||||
if (likely(!retval)) {
|
if (likely(!retval)) {
|
||||||
*last = nd.last;
|
*last = nd.last;
|
||||||
*type = nd.last_type;
|
*type = nd.last_type;
|
||||||
audit_inode(name, parent->dentry, LOOKUP_PARENT);
|
audit_inode(name, parent->dentry, AUDIT_INODE_PARENT);
|
||||||
} else {
|
} else {
|
||||||
putname(name);
|
putname(name);
|
||||||
name = ERR_PTR(retval);
|
name = ERR_PTR(retval);
|
||||||
|
@ -2718,7 +2710,7 @@ filename_mountpoint(int dfd, struct filename *name, struct path *path,
|
||||||
if (unlikely(error == -ESTALE))
|
if (unlikely(error == -ESTALE))
|
||||||
error = path_mountpoint(&nd, flags | LOOKUP_REVAL, path);
|
error = path_mountpoint(&nd, flags | LOOKUP_REVAL, path);
|
||||||
if (likely(!error))
|
if (likely(!error))
|
||||||
audit_inode(name, path->dentry, flags & LOOKUP_NO_EVAL);
|
audit_inode(name, path->dentry, AUDIT_INODE_NOEVAL);
|
||||||
restore_nameidata();
|
restore_nameidata();
|
||||||
putname(name);
|
putname(name);
|
||||||
return error;
|
return error;
|
||||||
|
@ -3299,7 +3291,7 @@ static int do_last(struct nameidata *nd,
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
audit_inode(nd->name, dir, LOOKUP_PARENT);
|
audit_inode(nd->name, dir, AUDIT_INODE_PARENT);
|
||||||
/* trailing slashes? */
|
/* trailing slashes? */
|
||||||
if (unlikely(nd->last.name[nd->last.len]))
|
if (unlikely(nd->last.name[nd->last.len]))
|
||||||
return -EISDIR;
|
return -EISDIR;
|
||||||
|
|
|
@ -1675,8 +1675,6 @@ int ksys_umount(char __user *name, int flags)
|
||||||
if (!(flags & UMOUNT_NOFOLLOW))
|
if (!(flags & UMOUNT_NOFOLLOW))
|
||||||
lookup_flags |= LOOKUP_FOLLOW;
|
lookup_flags |= LOOKUP_FOLLOW;
|
||||||
|
|
||||||
lookup_flags |= LOOKUP_NO_EVAL;
|
|
||||||
|
|
||||||
retval = user_path_mountpoint_at(AT_FDCWD, name, lookup_flags, &path);
|
retval = user_path_mountpoint_at(AT_FDCWD, name, lookup_flags, &path);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -3046,7 +3044,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* ... and get the mountpoint */
|
/* ... and get the mountpoint */
|
||||||
retval = user_path(dir_name, &path);
|
retval = user_path_at(AT_FDCWD, dir_name, LOOKUP_FOLLOW, &path);
|
||||||
if (retval)
|
if (retval)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
|
@ -3593,11 +3591,13 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
|
||||||
if (!may_mount())
|
if (!may_mount())
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
error = user_path_dir(new_root, &new);
|
error = user_path_at(AT_FDCWD, new_root,
|
||||||
|
LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &new);
|
||||||
if (error)
|
if (error)
|
||||||
goto out0;
|
goto out0;
|
||||||
|
|
||||||
error = user_path_dir(put_old, &old);
|
error = user_path_at(AT_FDCWD, put_old,
|
||||||
|
LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old);
|
||||||
if (error)
|
if (error)
|
||||||
goto out1;
|
goto out1;
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,6 @@ TRACE_DEFINE_ENUM(LOOKUP_PARENT);
|
||||||
TRACE_DEFINE_ENUM(LOOKUP_REVAL);
|
TRACE_DEFINE_ENUM(LOOKUP_REVAL);
|
||||||
TRACE_DEFINE_ENUM(LOOKUP_RCU);
|
TRACE_DEFINE_ENUM(LOOKUP_RCU);
|
||||||
TRACE_DEFINE_ENUM(LOOKUP_NO_REVAL);
|
TRACE_DEFINE_ENUM(LOOKUP_NO_REVAL);
|
||||||
TRACE_DEFINE_ENUM(LOOKUP_NO_EVAL);
|
|
||||||
TRACE_DEFINE_ENUM(LOOKUP_OPEN);
|
TRACE_DEFINE_ENUM(LOOKUP_OPEN);
|
||||||
TRACE_DEFINE_ENUM(LOOKUP_CREATE);
|
TRACE_DEFINE_ENUM(LOOKUP_CREATE);
|
||||||
TRACE_DEFINE_ENUM(LOOKUP_EXCL);
|
TRACE_DEFINE_ENUM(LOOKUP_EXCL);
|
||||||
|
@ -226,7 +225,6 @@ TRACE_DEFINE_ENUM(LOOKUP_DOWN);
|
||||||
{ LOOKUP_REVAL, "REVAL" }, \
|
{ LOOKUP_REVAL, "REVAL" }, \
|
||||||
{ LOOKUP_RCU, "RCU" }, \
|
{ LOOKUP_RCU, "RCU" }, \
|
||||||
{ LOOKUP_NO_REVAL, "NO_REVAL" }, \
|
{ LOOKUP_NO_REVAL, "NO_REVAL" }, \
|
||||||
{ LOOKUP_NO_EVAL, "NO_EVAL" }, \
|
|
||||||
{ LOOKUP_OPEN, "OPEN" }, \
|
{ LOOKUP_OPEN, "OPEN" }, \
|
||||||
{ LOOKUP_CREATE, "CREATE" }, \
|
{ LOOKUP_CREATE, "CREATE" }, \
|
||||||
{ LOOKUP_EXCL, "EXCL" }, \
|
{ LOOKUP_EXCL, "EXCL" }, \
|
||||||
|
|
|
@ -67,7 +67,7 @@ xfs_find_handle(
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
inode = file_inode(f.file);
|
inode = file_inode(f.file);
|
||||||
} else {
|
} else {
|
||||||
error = user_lpath((const char __user *)hreq->path, &path);
|
error = user_path_at(AT_FDCWD, hreq->path, 0, &path);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
inode = d_inode(path.dentry);
|
inode = d_inode(path.dentry);
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/ptrace.h>
|
#include <linux/ptrace.h>
|
||||||
#include <linux/namei.h> /* LOOKUP_* */
|
|
||||||
#include <uapi/linux/audit.h>
|
#include <uapi/linux/audit.h>
|
||||||
|
|
||||||
#define AUDIT_INO_UNSET ((unsigned long)-1)
|
#define AUDIT_INO_UNSET ((unsigned long)-1)
|
||||||
|
@ -252,6 +251,10 @@ static inline int audit_signal_info(int sig, struct task_struct *t)
|
||||||
#define audit_is_compat(arch) false
|
#define audit_is_compat(arch) false
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define AUDIT_INODE_PARENT 1 /* dentry represents the parent */
|
||||||
|
#define AUDIT_INODE_HIDDEN 2 /* audit record should be hidden */
|
||||||
|
#define AUDIT_INODE_NOEVAL 4 /* audit record incomplete */
|
||||||
|
|
||||||
#ifdef CONFIG_AUDITSYSCALL
|
#ifdef CONFIG_AUDITSYSCALL
|
||||||
#include <asm/syscall.h> /* for syscall_get_arch() */
|
#include <asm/syscall.h> /* for syscall_get_arch() */
|
||||||
|
|
||||||
|
@ -265,9 +268,6 @@ extern void __audit_syscall_exit(int ret_success, long ret_value);
|
||||||
extern struct filename *__audit_reusename(const __user char *uptr);
|
extern struct filename *__audit_reusename(const __user char *uptr);
|
||||||
extern void __audit_getname(struct filename *name);
|
extern void __audit_getname(struct filename *name);
|
||||||
|
|
||||||
#define AUDIT_INODE_PARENT 1 /* dentry represents the parent */
|
|
||||||
#define AUDIT_INODE_HIDDEN 2 /* audit record should be hidden */
|
|
||||||
#define AUDIT_INODE_NOEVAL 4 /* audit record incomplete */
|
|
||||||
extern void __audit_inode(struct filename *name, const struct dentry *dentry,
|
extern void __audit_inode(struct filename *name, const struct dentry *dentry,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
extern void __audit_file(const struct file *);
|
extern void __audit_file(const struct file *);
|
||||||
|
@ -328,16 +328,9 @@ static inline void audit_getname(struct filename *name)
|
||||||
}
|
}
|
||||||
static inline void audit_inode(struct filename *name,
|
static inline void audit_inode(struct filename *name,
|
||||||
const struct dentry *dentry,
|
const struct dentry *dentry,
|
||||||
unsigned int flags) {
|
unsigned int aflags) {
|
||||||
if (unlikely(!audit_dummy_context())) {
|
if (unlikely(!audit_dummy_context()))
|
||||||
unsigned int aflags = 0;
|
|
||||||
|
|
||||||
if (flags & LOOKUP_PARENT)
|
|
||||||
aflags |= AUDIT_INODE_PARENT;
|
|
||||||
if (flags & LOOKUP_NO_EVAL)
|
|
||||||
aflags |= AUDIT_INODE_NOEVAL;
|
|
||||||
__audit_inode(name, dentry, aflags);
|
__audit_inode(name, dentry, aflags);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
static inline void audit_file(struct file *file)
|
static inline void audit_file(struct file *file)
|
||||||
{
|
{
|
||||||
|
@ -561,7 +554,7 @@ static inline void __audit_inode_child(struct inode *parent,
|
||||||
{ }
|
{ }
|
||||||
static inline void audit_inode(struct filename *name,
|
static inline void audit_inode(struct filename *name,
|
||||||
const struct dentry *dentry,
|
const struct dentry *dentry,
|
||||||
unsigned int parent)
|
unsigned int aflags)
|
||||||
{ }
|
{ }
|
||||||
static inline void audit_file(struct file *file)
|
static inline void audit_file(struct file *file)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,39 +16,28 @@ enum { MAX_NESTED_LINKS = 8 };
|
||||||
*/
|
*/
|
||||||
enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
|
enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
|
||||||
|
|
||||||
/*
|
/* pathwalk mode */
|
||||||
* The bitmask for a lookup event:
|
#define LOOKUP_FOLLOW 0x0001 /* follow links at the end */
|
||||||
* - follow links at the end
|
#define LOOKUP_DIRECTORY 0x0002 /* require a directory */
|
||||||
* - require a directory
|
#define LOOKUP_AUTOMOUNT 0x0004 /* force terminal automount */
|
||||||
* - ending slashes ok even for nonexistent files
|
#define LOOKUP_EMPTY 0x4000 /* accept empty path [user_... only] */
|
||||||
* - internal "there are more path components" flag
|
#define LOOKUP_DOWN 0x8000 /* follow mounts in the starting point */
|
||||||
* - dentry cache is untrusted; force a real lookup
|
|
||||||
* - suppress terminal automount
|
|
||||||
* - skip revalidation
|
|
||||||
* - don't fetch xattrs on audit_inode
|
|
||||||
*/
|
|
||||||
#define LOOKUP_FOLLOW 0x0001
|
|
||||||
#define LOOKUP_DIRECTORY 0x0002
|
|
||||||
#define LOOKUP_AUTOMOUNT 0x0004
|
|
||||||
|
|
||||||
|
#define LOOKUP_REVAL 0x0020 /* tell ->d_revalidate() to trust no cache */
|
||||||
|
#define LOOKUP_RCU 0x0040 /* RCU pathwalk mode; semi-internal */
|
||||||
|
|
||||||
|
/* These tell filesystem methods that we are dealing with the final component... */
|
||||||
|
#define LOOKUP_OPEN 0x0100 /* ... in open */
|
||||||
|
#define LOOKUP_CREATE 0x0200 /* ... in object creation */
|
||||||
|
#define LOOKUP_EXCL 0x0400 /* ... in exclusive creation */
|
||||||
|
#define LOOKUP_RENAME_TARGET 0x0800 /* ... in destination of rename() */
|
||||||
|
|
||||||
|
/* internal use only */
|
||||||
#define LOOKUP_PARENT 0x0010
|
#define LOOKUP_PARENT 0x0010
|
||||||
#define LOOKUP_REVAL 0x0020
|
|
||||||
#define LOOKUP_RCU 0x0040
|
|
||||||
#define LOOKUP_NO_REVAL 0x0080
|
#define LOOKUP_NO_REVAL 0x0080
|
||||||
#define LOOKUP_NO_EVAL 0x0100
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Intent data
|
|
||||||
*/
|
|
||||||
#define LOOKUP_OPEN 0x0100
|
|
||||||
#define LOOKUP_CREATE 0x0200
|
|
||||||
#define LOOKUP_EXCL 0x0400
|
|
||||||
#define LOOKUP_RENAME_TARGET 0x0800
|
|
||||||
|
|
||||||
#define LOOKUP_JUMPED 0x1000
|
#define LOOKUP_JUMPED 0x1000
|
||||||
#define LOOKUP_ROOT 0x2000
|
#define LOOKUP_ROOT 0x2000
|
||||||
#define LOOKUP_EMPTY 0x4000
|
#define LOOKUP_ROOT_GRABBED 0x0008
|
||||||
#define LOOKUP_DOWN 0x8000
|
|
||||||
|
|
||||||
extern int path_pts(struct path *path);
|
extern int path_pts(struct path *path);
|
||||||
|
|
||||||
|
@ -60,22 +49,6 @@ static inline int user_path_at(int dfd, const char __user *name, unsigned flags,
|
||||||
return user_path_at_empty(dfd, name, flags, path, NULL);
|
return user_path_at_empty(dfd, name, flags, path, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int user_path(const char __user *name, struct path *path)
|
|
||||||
{
|
|
||||||
return user_path_at_empty(AT_FDCWD, name, LOOKUP_FOLLOW, path, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int user_lpath(const char __user *name, struct path *path)
|
|
||||||
{
|
|
||||||
return user_path_at_empty(AT_FDCWD, name, 0, path, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int user_path_dir(const char __user *name, struct path *path)
|
|
||||||
{
|
|
||||||
return user_path_at_empty(AT_FDCWD, name,
|
|
||||||
LOOKUP_FOLLOW | LOOKUP_DIRECTORY, path, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int kern_path(const char *, unsigned, struct path *);
|
extern int kern_path(const char *, unsigned, struct path *);
|
||||||
|
|
||||||
extern struct dentry *kern_path_create(int, const char *, struct path *, unsigned int);
|
extern struct dentry *kern_path_create(int, const char *, struct path *, unsigned int);
|
||||||
|
|
Loading…
Reference in New Issue