diff options
Diffstat (limited to 'fs/open.c')
| -rw-r--r-- | fs/open.c | 58 |
1 files changed, 29 insertions, 29 deletions
| @@ -378,63 +378,63 @@ SYSCALL_ALIAS(sys_ftruncate64, SyS_ftruncate64); | |||
| 378 | #endif | 378 | #endif |
| 379 | #endif /* BITS_PER_LONG == 32 */ | 379 | #endif /* BITS_PER_LONG == 32 */ |
| 380 | 380 | ||
| 381 | SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len) | 381 | |
| 382 | int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) | ||
| 382 | { | 383 | { |
| 383 | struct file *file; | 384 | struct inode *inode = file->f_path.dentry->d_inode; |
| 384 | struct inode *inode; | 385 | long ret; |
| 385 | long ret = -EINVAL; | ||
| 386 | 386 | ||
| 387 | if (offset < 0 || len <= 0) | 387 | if (offset < 0 || len <= 0) |
| 388 | goto out; | 388 | return -EINVAL; |
| 389 | 389 | ||
| 390 | /* Return error if mode is not supported */ | 390 | /* Return error if mode is not supported */ |
| 391 | ret = -EOPNOTSUPP; | ||
| 392 | if (mode && !(mode & FALLOC_FL_KEEP_SIZE)) | 391 | if (mode && !(mode & FALLOC_FL_KEEP_SIZE)) |
| 393 | goto out; | 392 | return -EOPNOTSUPP; |
| 394 | 393 | ||
| 395 | ret = -EBADF; | ||
| 396 | file = fget(fd); | ||
| 397 | if (!file) | ||
| 398 | goto out; | ||
| 399 | if (!(file->f_mode & FMODE_WRITE)) | 394 | if (!(file->f_mode & FMODE_WRITE)) |
| 400 | goto out_fput; | 395 | return -EBADF; |
| 401 | /* | 396 | /* |
| 402 | * Revalidate the write permissions, in case security policy has | 397 | * Revalidate the write permissions, in case security policy has |
| 403 | * changed since the files were opened. | 398 | * changed since the files were opened. |
| 404 | */ | 399 | */ |
| 405 | ret = security_file_permission(file, MAY_WRITE); | 400 | ret = security_file_permission(file, MAY_WRITE); |
| 406 | if (ret) | 401 | if (ret) |
| 407 | goto out_fput; | 402 | return ret; |
| 408 | 403 | ||
| 409 | inode = file->f_path.dentry->d_inode; | ||
| 410 | |||
| 411 | ret = -ESPIPE; | ||
| 412 | if (S_ISFIFO(inode->i_mode)) | 404 | if (S_ISFIFO(inode->i_mode)) |
| 413 | goto out_fput; | 405 | return -ESPIPE; |
| 414 | 406 | ||
| 415 | ret = -ENODEV; | ||
| 416 | /* | 407 | /* |
| 417 | * Let individual file system decide if it supports preallocation | 408 | * Let individual file system decide if it supports preallocation |
| 418 | * for directories or not. | 409 | * for directories or not. |
| 419 | */ | 410 | */ |
| 420 | if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) | 411 | if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) |
| 421 | goto out_fput; | 412 | return -ENODEV; |
| 422 | 413 | ||
| 423 | ret = -EFBIG; | ||
| 424 | /* Check for wrap through zero too */ | 414 | /* Check for wrap through zero too */ |
| 425 | if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0)) | 415 | if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0)) |
| 426 | goto out_fput; | 416 | return -EFBIG; |
| 427 | 417 | ||
| 428 | if (inode->i_op->fallocate) | 418 | if (!inode->i_op->fallocate) |
| 429 | ret = inode->i_op->fallocate(inode, mode, offset, len); | 419 | return -EOPNOTSUPP; |
| 430 | else | ||
| 431 | ret = -EOPNOTSUPP; | ||
| 432 | 420 | ||
| 433 | out_fput: | 421 | return inode->i_op->fallocate(inode, mode, offset, len); |
| 434 | fput(file); | ||
| 435 | out: | ||
| 436 | return ret; | ||
| 437 | } | 422 | } |
| 423 | |||
| 424 | SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len) | ||
| 425 | { | ||
| 426 | struct file *file; | ||
| 427 | int error = -EBADF; | ||
| 428 | |||
| 429 | file = fget(fd); | ||
| 430 | if (file) { | ||
| 431 | error = do_fallocate(file, mode, offset, len); | ||
| 432 | fput(file); | ||
| 433 | } | ||
| 434 | |||
| 435 | return error; | ||
| 436 | } | ||
| 437 | |||
| 438 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS | 438 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS |
| 439 | asmlinkage long SyS_fallocate(long fd, long mode, loff_t offset, loff_t len) | 439 | asmlinkage long SyS_fallocate(long fd, long mode, loff_t offset, loff_t len) |
| 440 | { | 440 | { |
