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 f6fd0a00e6c..c6d31a3bab8 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 | ||
