aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2006-01-18 20:43:53 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-18 22:20:29 -0500
commit5590ff0d5528b60153c0b4e7b771472b5a95e297 (patch)
tree5fdccf2354269702f71beb8e0a2942e4167fd992 /include/linux
parente2f99018eb7b29954747a2dd78e9fc0c36a60f0f (diff)
[PATCH] vfs: *at functions: core
Here is a series of patches which introduce in total 13 new system calls which take a file descriptor/filename pair instead of a single file name. These functions, openat etc, have been discussed on numerous occasions. They are needed to implement race-free filesystem traversal, they are necessary to implement a virtual per-thread current working directory (think multi-threaded backup software), etc. We have in glibc today implementations of the interfaces which use the /proc/self/fd magic. But this code is rather expensive. Here are some results (similar to what Jim Meyering posted before). The test creates a deep directory hierarchy on a tmpfs filesystem. Then rm -fr is used to remove all directories. Without syscall support I get this: real 0m31.921s user 0m0.688s sys 0m31.234s With syscall support the results are much better: real 0m20.699s user 0m0.536s sys 0m20.149s The interfaces are for obvious reasons currently not much used. But they'll be used. coreutils (and Jeff's posixutils) are already using them. Furthermore, code like ftw/fts in libc (maybe even glob) will also start using them. I expect a patch to make follow soon. Every program which is walking the filesystem tree will benefit. Signed-off-by: Ulrich Drepper <drepper@redhat.com> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Al Viro <viro@ftp.linux.org.uk> Acked-by: Ingo Molnar <mingo@elte.hu> Cc: Michael Kerrisk <mtk-manpages@gmx.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/fcntl.h7
-rw-r--r--include/linux/fs.h7
-rw-r--r--include/linux/namei.h7
-rw-r--r--include/linux/time.h2
4 files changed, 17 insertions, 6 deletions
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index 8a7c82151de9..c52a63755fdd 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -23,6 +23,13 @@
23#define DN_ATTRIB 0x00000020 /* File changed attibutes */ 23#define DN_ATTRIB 0x00000020 /* File changed attibutes */
24#define DN_MULTISHOT 0x80000000 /* Don't remove notifier */ 24#define DN_MULTISHOT 0x80000000 /* Don't remove notifier */
25 25
26#define AT_FDCWD -100 /* Special value used to indicate
27 openat should use the current
28 working directory. */
29#define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic links. */
30#define AT_REMOVEDIR 0x200 /* Remove directory instead of
31 unlinking file. */
32
26#ifdef __KERNEL__ 33#ifdef __KERNEL__
27 34
28#ifndef force_o_largefile 35#ifndef force_o_largefile
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b77f2608eef9..84bb449b9b01 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1340,7 +1340,8 @@ static inline int break_lease(struct inode *inode, unsigned int mode)
1340 1340
1341extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, 1341extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
1342 struct file *filp); 1342 struct file *filp);
1343extern long do_sys_open(const char __user *filename, int flags, int mode); 1343extern long do_sys_open(int fdf, const char __user *filename, int flags,
1344 int mode);
1344extern struct file *filp_open(const char *, int, int); 1345extern struct file *filp_open(const char *, int, int);
1345extern struct file * dentry_open(struct dentry *, struct vfsmount *, int); 1346extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
1346extern int filp_close(struct file *, fl_owner_t id); 1347extern int filp_close(struct file *, fl_owner_t id);
@@ -1479,7 +1480,7 @@ static inline void allow_write_access(struct file *file)
1479} 1480}
1480extern int do_pipe(int *); 1481extern int do_pipe(int *);
1481 1482
1482extern int open_namei(const char *, int, int, struct nameidata *); 1483extern int open_namei(int dfd, const char *, int, int, struct nameidata *);
1483extern int may_open(struct nameidata *, int, int); 1484extern int may_open(struct nameidata *, int, int);
1484 1485
1485extern int kernel_read(struct file *, unsigned long, char *, unsigned long); 1486extern int kernel_read(struct file *, unsigned long, char *, unsigned long);
@@ -1677,6 +1678,8 @@ extern int vfs_readdir(struct file *, filldir_t, void *);
1677 1678
1678extern int vfs_stat(char __user *, struct kstat *); 1679extern int vfs_stat(char __user *, struct kstat *);
1679extern int vfs_lstat(char __user *, struct kstat *); 1680extern int vfs_lstat(char __user *, struct kstat *);
1681extern int vfs_stat_fd(int dfd, char __user *, struct kstat *);
1682extern int vfs_lstat_fd(int dfd, char __user *, struct kstat *);
1680extern int vfs_fstat(unsigned int, struct kstat *); 1683extern int vfs_fstat(unsigned int, struct kstat *);
1681 1684
1682extern int vfs_ioctl(struct file *, unsigned int, unsigned int, unsigned long); 1685extern int vfs_ioctl(struct file *, unsigned int, unsigned int, unsigned long);
diff --git a/include/linux/namei.h b/include/linux/namei.h
index b699e427c00c..e6698013e4d0 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -56,10 +56,11 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
56#define LOOKUP_ACCESS (0x0400) 56#define LOOKUP_ACCESS (0x0400)
57 57
58extern int FASTCALL(__user_walk(const char __user *, unsigned, struct nameidata *)); 58extern int FASTCALL(__user_walk(const char __user *, unsigned, struct nameidata *));
59extern int FASTCALL(__user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *));
59#define user_path_walk(name,nd) \ 60#define user_path_walk(name,nd) \
60 __user_walk(name, LOOKUP_FOLLOW, nd) 61 __user_walk_fd(AT_FDCWD, name, LOOKUP_FOLLOW, nd)
61#define user_path_walk_link(name,nd) \ 62#define user_path_walk_link(name,nd) \
62 __user_walk(name, 0, nd) 63 __user_walk_fd(AT_FDCWD, name, 0, nd)
63extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *)); 64extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
64extern int FASTCALL(path_walk(const char *, struct nameidata *)); 65extern int FASTCALL(path_walk(const char *, struct nameidata *));
65extern int FASTCALL(link_path_walk(const char *, struct nameidata *)); 66extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
@@ -67,7 +68,7 @@ extern void path_release(struct nameidata *);
67extern void path_release_on_umount(struct nameidata *); 68extern void path_release_on_umount(struct nameidata *);
68 69
69extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, struct nameidata *nd, int open_flags); 70extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, struct nameidata *nd, int open_flags);
70extern int path_lookup_open(const char *, unsigned lookup_flags, struct nameidata *, int open_flags); 71extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags);
71extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, 72extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
72 int (*open)(struct inode *, struct file *)); 73 int (*open)(struct inode *, struct file *));
73extern struct file *nameidata_to_filp(struct nameidata *nd, int flags); 74extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
diff --git a/include/linux/time.h b/include/linux/time.h
index f2aca7ec6325..614dd8465839 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -74,7 +74,7 @@ extern void do_gettimeofday(struct timeval *tv);
74extern int do_settimeofday(struct timespec *tv); 74extern int do_settimeofday(struct timespec *tv);
75extern int do_sys_settimeofday(struct timespec *tv, struct timezone *tz); 75extern int do_sys_settimeofday(struct timespec *tv, struct timezone *tz);
76#define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts) 76#define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts)
77extern long do_utimes(char __user *filename, struct timeval *times); 77extern long do_utimes(int dfd, char __user *filename, struct timeval *times);
78struct itimerval; 78struct itimerval;
79extern int do_setitimer(int which, struct itimerval *value, 79extern int do_setitimer(int which, struct itimerval *value,
80 struct itimerval *ovalue); 80 struct itimerval *ovalue);