diff options
Diffstat (limited to 'fs/compat.c')
-rw-r--r-- | fs/compat.c | 69 |
1 files changed, 29 insertions, 40 deletions
diff --git a/fs/compat.c b/fs/compat.c index f6fd0a00e6cc..c6d31a3bab88 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -262,35 +262,19 @@ static int put_compat_statfs(struct compat_statfs __user *ubuf, struct kstatfs * | |||
262 | */ | 262 | */ |
263 | asmlinkage long compat_sys_statfs(const char __user *pathname, struct compat_statfs __user *buf) | 263 | asmlinkage long compat_sys_statfs(const char __user *pathname, struct compat_statfs __user *buf) |
264 | { | 264 | { |
265 | struct path path; | 265 | struct kstatfs tmp; |
266 | int error; | 266 | int error = user_statfs(pathname, &tmp); |
267 | 267 | if (!error) | |
268 | error = user_path(pathname, &path); | 268 | error = put_compat_statfs(buf, &tmp); |
269 | if (!error) { | ||
270 | struct kstatfs tmp; | ||
271 | error = vfs_statfs(&path, &tmp); | ||
272 | if (!error) | ||
273 | error = put_compat_statfs(buf, &tmp); | ||
274 | path_put(&path); | ||
275 | } | ||
276 | return error; | 269 | return error; |
277 | } | 270 | } |
278 | 271 | ||
279 | asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs __user *buf) | 272 | asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs __user *buf) |
280 | { | 273 | { |
281 | struct file * file; | ||
282 | struct kstatfs tmp; | 274 | struct kstatfs tmp; |
283 | int error; | 275 | int error = fd_statfs(fd, &tmp); |
284 | |||
285 | error = -EBADF; | ||
286 | file = fget(fd); | ||
287 | if (!file) | ||
288 | goto out; | ||
289 | error = vfs_statfs(&file->f_path, &tmp); | ||
290 | if (!error) | 276 | if (!error) |
291 | error = put_compat_statfs(buf, &tmp); | 277 | error = put_compat_statfs(buf, &tmp); |
292 | fput(file); | ||
293 | out: | ||
294 | return error; | 278 | return error; |
295 | } | 279 | } |
296 | 280 | ||
@@ -329,41 +313,29 @@ static int put_compat_statfs64(struct compat_statfs64 __user *ubuf, struct kstat | |||
329 | 313 | ||
330 | asmlinkage long compat_sys_statfs64(const char __user *pathname, compat_size_t sz, struct compat_statfs64 __user *buf) | 314 | asmlinkage long compat_sys_statfs64(const char __user *pathname, compat_size_t sz, struct compat_statfs64 __user *buf) |
331 | { | 315 | { |
332 | struct path path; | 316 | struct kstatfs tmp; |
333 | int error; | 317 | int error; |
334 | 318 | ||
335 | if (sz != sizeof(*buf)) | 319 | if (sz != sizeof(*buf)) |
336 | return -EINVAL; | 320 | return -EINVAL; |
337 | 321 | ||
338 | error = user_path(pathname, &path); | 322 | error = user_statfs(pathname, &tmp); |
339 | if (!error) { | 323 | if (!error) |
340 | struct kstatfs tmp; | 324 | error = put_compat_statfs64(buf, &tmp); |
341 | error = vfs_statfs(&path, &tmp); | ||
342 | if (!error) | ||
343 | error = put_compat_statfs64(buf, &tmp); | ||
344 | path_put(&path); | ||
345 | } | ||
346 | return error; | 325 | return error; |
347 | } | 326 | } |
348 | 327 | ||
349 | asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct compat_statfs64 __user *buf) | 328 | asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct compat_statfs64 __user *buf) |
350 | { | 329 | { |
351 | struct file * file; | ||
352 | struct kstatfs tmp; | 330 | struct kstatfs tmp; |
353 | int error; | 331 | int error; |
354 | 332 | ||
355 | if (sz != sizeof(*buf)) | 333 | if (sz != sizeof(*buf)) |
356 | return -EINVAL; | 334 | return -EINVAL; |
357 | 335 | ||
358 | error = -EBADF; | 336 | error = fd_statfs(fd, &tmp); |
359 | file = fget(fd); | ||
360 | if (!file) | ||
361 | goto out; | ||
362 | error = vfs_statfs(&file->f_path, &tmp); | ||
363 | if (!error) | 337 | if (!error) |
364 | error = put_compat_statfs64(buf, &tmp); | 338 | error = put_compat_statfs64(buf, &tmp); |
365 | fput(file); | ||
366 | out: | ||
367 | return error; | 339 | return error; |
368 | } | 340 | } |
369 | 341 | ||
@@ -1228,7 +1200,9 @@ compat_sys_preadv(unsigned long fd, const struct compat_iovec __user *vec, | |||
1228 | file = fget_light(fd, &fput_needed); | 1200 | file = fget_light(fd, &fput_needed); |
1229 | if (!file) | 1201 | if (!file) |
1230 | return -EBADF; | 1202 | return -EBADF; |
1231 | ret = compat_readv(file, vec, vlen, &pos); | 1203 | ret = -ESPIPE; |
1204 | if (file->f_mode & FMODE_PREAD) | ||
1205 | ret = compat_readv(file, vec, vlen, &pos); | ||
1232 | fput_light(file, fput_needed); | 1206 | fput_light(file, fput_needed); |
1233 | return ret; | 1207 | return ret; |
1234 | } | 1208 | } |
@@ -1285,7 +1259,9 @@ compat_sys_pwritev(unsigned long fd, const struct compat_iovec __user *vec, | |||
1285 | file = fget_light(fd, &fput_needed); | 1259 | file = fget_light(fd, &fput_needed); |
1286 | if (!file) | 1260 | if (!file) |
1287 | return -EBADF; | 1261 | return -EBADF; |
1288 | ret = compat_writev(file, vec, vlen, &pos); | 1262 | ret = -ESPIPE; |
1263 | if (file->f_mode & FMODE_PWRITE) | ||
1264 | ret = compat_writev(file, vec, vlen, &pos); | ||
1289 | fput_light(file, fput_needed); | 1265 | fput_light(file, fput_needed); |
1290 | return ret; | 1266 | return ret; |
1291 | } | 1267 | } |
@@ -2308,3 +2284,16 @@ asmlinkage long compat_sys_timerfd_gettime(int ufd, | |||
2308 | } | 2284 | } |
2309 | 2285 | ||
2310 | #endif /* CONFIG_TIMERFD */ | 2286 | #endif /* CONFIG_TIMERFD */ |
2287 | |||
2288 | #ifdef CONFIG_FHANDLE | ||
2289 | /* | ||
2290 | * Exactly like fs/open.c:sys_open_by_handle_at(), except that it | ||
2291 | * doesn't set the O_LARGEFILE flag. | ||
2292 | */ | ||
2293 | asmlinkage long | ||
2294 | compat_sys_open_by_handle_at(int mountdirfd, | ||
2295 | struct file_handle __user *handle, int flags) | ||
2296 | { | ||
2297 | return do_handle_open(mountdirfd, handle, flags); | ||
2298 | } | ||
2299 | #endif | ||