diff options
Diffstat (limited to 'fs/stat.c')
-rw-r--r-- | fs/stat.c | 105 |
1 files changed, 42 insertions, 63 deletions
@@ -55,46 +55,6 @@ int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
55 | 55 | ||
56 | EXPORT_SYMBOL(vfs_getattr); | 56 | EXPORT_SYMBOL(vfs_getattr); |
57 | 57 | ||
58 | int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat) | ||
59 | { | ||
60 | struct path path; | ||
61 | int error; | ||
62 | |||
63 | error = user_path_at(dfd, name, LOOKUP_FOLLOW, &path); | ||
64 | if (!error) { | ||
65 | error = vfs_getattr(path.mnt, path.dentry, stat); | ||
66 | path_put(&path); | ||
67 | } | ||
68 | return error; | ||
69 | } | ||
70 | |||
71 | int vfs_stat(char __user *name, struct kstat *stat) | ||
72 | { | ||
73 | return vfs_stat_fd(AT_FDCWD, name, stat); | ||
74 | } | ||
75 | |||
76 | EXPORT_SYMBOL(vfs_stat); | ||
77 | |||
78 | int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat) | ||
79 | { | ||
80 | struct path path; | ||
81 | int error; | ||
82 | |||
83 | error = user_path_at(dfd, name, 0, &path); | ||
84 | if (!error) { | ||
85 | error = vfs_getattr(path.mnt, path.dentry, stat); | ||
86 | path_put(&path); | ||
87 | } | ||
88 | return error; | ||
89 | } | ||
90 | |||
91 | int vfs_lstat(char __user *name, struct kstat *stat) | ||
92 | { | ||
93 | return vfs_lstat_fd(AT_FDCWD, name, stat); | ||
94 | } | ||
95 | |||
96 | EXPORT_SYMBOL(vfs_lstat); | ||
97 | |||
98 | int vfs_fstat(unsigned int fd, struct kstat *stat) | 58 | int vfs_fstat(unsigned int fd, struct kstat *stat) |
99 | { | 59 | { |
100 | struct file *f = fget(fd); | 60 | struct file *f = fget(fd); |
@@ -106,26 +66,43 @@ int vfs_fstat(unsigned int fd, struct kstat *stat) | |||
106 | } | 66 | } |
107 | return error; | 67 | return error; |
108 | } | 68 | } |
109 | |||
110 | EXPORT_SYMBOL(vfs_fstat); | 69 | EXPORT_SYMBOL(vfs_fstat); |
111 | 70 | ||
112 | int vfs_fstatat(int dfd, char __user *filename, struct kstat *stat, int flag) | 71 | int vfs_fstatat(int dfd, char __user *filename, struct kstat *stat, int flag) |
113 | { | 72 | { |
73 | struct path path; | ||
114 | int error = -EINVAL; | 74 | int error = -EINVAL; |
75 | int lookup_flags = 0; | ||
115 | 76 | ||
116 | if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0) | 77 | if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0) |
117 | goto out; | 78 | goto out; |
118 | 79 | ||
119 | if (flag & AT_SYMLINK_NOFOLLOW) | 80 | if (!(flag & AT_SYMLINK_NOFOLLOW)) |
120 | error = vfs_lstat_fd(dfd, filename, stat); | 81 | lookup_flags |= LOOKUP_FOLLOW; |
121 | else | 82 | |
122 | error = vfs_stat_fd(dfd, filename, stat); | 83 | error = user_path_at(dfd, filename, lookup_flags, &path); |
84 | if (error) | ||
85 | goto out; | ||
86 | |||
87 | error = vfs_getattr(path.mnt, path.dentry, stat); | ||
88 | path_put(&path); | ||
123 | out: | 89 | out: |
124 | return error; | 90 | return error; |
125 | } | 91 | } |
126 | |||
127 | EXPORT_SYMBOL(vfs_fstatat); | 92 | EXPORT_SYMBOL(vfs_fstatat); |
128 | 93 | ||
94 | int vfs_stat(char __user *name, struct kstat *stat) | ||
95 | { | ||
96 | return vfs_fstatat(AT_FDCWD, name, stat, 0); | ||
97 | } | ||
98 | EXPORT_SYMBOL(vfs_stat); | ||
99 | |||
100 | int vfs_lstat(char __user *name, struct kstat *stat) | ||
101 | { | ||
102 | return vfs_fstatat(AT_FDCWD, name, stat, AT_SYMLINK_NOFOLLOW); | ||
103 | } | ||
104 | EXPORT_SYMBOL(vfs_lstat); | ||
105 | |||
129 | 106 | ||
130 | #ifdef __ARCH_WANT_OLD_STAT | 107 | #ifdef __ARCH_WANT_OLD_STAT |
131 | 108 | ||
@@ -173,23 +150,25 @@ static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * sta | |||
173 | SYSCALL_DEFINE2(stat, char __user *, filename, struct __old_kernel_stat __user *, statbuf) | 150 | SYSCALL_DEFINE2(stat, char __user *, filename, struct __old_kernel_stat __user *, statbuf) |
174 | { | 151 | { |
175 | struct kstat stat; | 152 | struct kstat stat; |
176 | int error = vfs_stat_fd(AT_FDCWD, filename, &stat); | 153 | int error; |
177 | 154 | ||
178 | if (!error) | 155 | error = vfs_stat(filename, &stat); |
179 | error = cp_old_stat(&stat, statbuf); | 156 | if (error) |
157 | return error; | ||
180 | 158 | ||
181 | return error; | 159 | return cp_old_stat(&stat, statbuf); |
182 | } | 160 | } |
183 | 161 | ||
184 | SYSCALL_DEFINE2(lstat, char __user *, filename, struct __old_kernel_stat __user *, statbuf) | 162 | SYSCALL_DEFINE2(lstat, char __user *, filename, struct __old_kernel_stat __user *, statbuf) |
185 | { | 163 | { |
186 | struct kstat stat; | 164 | struct kstat stat; |
187 | int error = vfs_lstat_fd(AT_FDCWD, filename, &stat); | 165 | int error; |
188 | 166 | ||
189 | if (!error) | 167 | error = vfs_lstat(filename, &stat); |
190 | error = cp_old_stat(&stat, statbuf); | 168 | if (error) |
169 | return error; | ||
191 | 170 | ||
192 | return error; | 171 | return cp_old_stat(&stat, statbuf); |
193 | } | 172 | } |
194 | 173 | ||
195 | SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf) | 174 | SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf) |
@@ -258,23 +237,23 @@ static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf) | |||
258 | SYSCALL_DEFINE2(newstat, char __user *, filename, struct stat __user *, statbuf) | 237 | SYSCALL_DEFINE2(newstat, char __user *, filename, struct stat __user *, statbuf) |
259 | { | 238 | { |
260 | struct kstat stat; | 239 | struct kstat stat; |
261 | int error = vfs_stat_fd(AT_FDCWD, filename, &stat); | 240 | int error = vfs_stat(filename, &stat); |
262 | |||
263 | if (!error) | ||
264 | error = cp_new_stat(&stat, statbuf); | ||
265 | 241 | ||
266 | return error; | 242 | if (error) |
243 | return error; | ||
244 | return cp_new_stat(&stat, statbuf); | ||
267 | } | 245 | } |
268 | 246 | ||
269 | SYSCALL_DEFINE2(newlstat, char __user *, filename, struct stat __user *, statbuf) | 247 | SYSCALL_DEFINE2(newlstat, char __user *, filename, struct stat __user *, statbuf) |
270 | { | 248 | { |
271 | struct kstat stat; | 249 | struct kstat stat; |
272 | int error = vfs_lstat_fd(AT_FDCWD, filename, &stat); | 250 | int error; |
273 | 251 | ||
274 | if (!error) | 252 | error = vfs_lstat(filename, &stat); |
275 | error = cp_new_stat(&stat, statbuf); | 253 | if (error) |
254 | return error; | ||
276 | 255 | ||
277 | return error; | 256 | return cp_new_stat(&stat, statbuf); |
278 | } | 257 | } |
279 | 258 | ||
280 | #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT) | 259 | #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT) |