diff options
| -rw-r--r-- | fs/aio.c | 3 | ||||
| -rw-r--r-- | fs/internal.h | 1 | ||||
| -rw-r--r-- | fs/namei.c | 7 | ||||
| -rw-r--r-- | fs/open.c | 44 |
4 files changed, 34 insertions, 21 deletions
| @@ -634,9 +634,8 @@ static void free_ioctx_users(struct percpu_ref *ref) | |||
| 634 | while (!list_empty(&ctx->active_reqs)) { | 634 | while (!list_empty(&ctx->active_reqs)) { |
| 635 | req = list_first_entry(&ctx->active_reqs, | 635 | req = list_first_entry(&ctx->active_reqs, |
| 636 | struct aio_kiocb, ki_list); | 636 | struct aio_kiocb, ki_list); |
| 637 | |||
| 638 | list_del_init(&req->ki_list); | ||
| 639 | kiocb_cancel(req); | 637 | kiocb_cancel(req); |
| 638 | list_del_init(&req->ki_list); | ||
| 640 | } | 639 | } |
| 641 | 640 | ||
| 642 | spin_unlock_irq(&ctx->ctx_lock); | 641 | spin_unlock_irq(&ctx->ctx_lock); |
diff --git a/fs/internal.h b/fs/internal.h index e08972db0303..980d005b21b4 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
| @@ -125,6 +125,7 @@ int do_fchmodat(int dfd, const char __user *filename, umode_t mode); | |||
| 125 | int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group, | 125 | int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group, |
| 126 | int flag); | 126 | int flag); |
| 127 | 127 | ||
| 128 | extern int open_check_o_direct(struct file *f); | ||
| 128 | extern int vfs_open(const struct path *, struct file *, const struct cred *); | 129 | extern int vfs_open(const struct path *, struct file *, const struct cred *); |
| 129 | extern struct file *filp_clone_open(struct file *); | 130 | extern struct file *filp_clone_open(struct file *); |
| 130 | 131 | ||
diff --git a/fs/namei.c b/fs/namei.c index 186bd2464fd5..4eb916996345 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -3367,7 +3367,9 @@ finish_open_created: | |||
| 3367 | goto out; | 3367 | goto out; |
| 3368 | *opened |= FILE_OPENED; | 3368 | *opened |= FILE_OPENED; |
| 3369 | opened: | 3369 | opened: |
| 3370 | error = ima_file_check(file, op->acc_mode, *opened); | 3370 | error = open_check_o_direct(file); |
| 3371 | if (!error) | ||
| 3372 | error = ima_file_check(file, op->acc_mode, *opened); | ||
| 3371 | if (!error && will_truncate) | 3373 | if (!error && will_truncate) |
| 3372 | error = handle_truncate(file); | 3374 | error = handle_truncate(file); |
| 3373 | out: | 3375 | out: |
| @@ -3447,6 +3449,9 @@ static int do_tmpfile(struct nameidata *nd, unsigned flags, | |||
| 3447 | error = finish_open(file, child, NULL, opened); | 3449 | error = finish_open(file, child, NULL, opened); |
| 3448 | if (error) | 3450 | if (error) |
| 3449 | goto out2; | 3451 | goto out2; |
| 3452 | error = open_check_o_direct(file); | ||
| 3453 | if (error) | ||
| 3454 | fput(file); | ||
| 3450 | out2: | 3455 | out2: |
| 3451 | mnt_drop_write(path.mnt); | 3456 | mnt_drop_write(path.mnt); |
| 3452 | out: | 3457 | out: |
| @@ -724,6 +724,16 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) | |||
| 724 | return ksys_fchown(fd, user, group); | 724 | return ksys_fchown(fd, user, group); |
| 725 | } | 725 | } |
| 726 | 726 | ||
| 727 | int open_check_o_direct(struct file *f) | ||
| 728 | { | ||
| 729 | /* NB: we're sure to have correct a_ops only after f_op->open */ | ||
| 730 | if (f->f_flags & O_DIRECT) { | ||
| 731 | if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO) | ||
| 732 | return -EINVAL; | ||
| 733 | } | ||
| 734 | return 0; | ||
| 735 | } | ||
| 736 | |||
| 727 | static int do_dentry_open(struct file *f, | 737 | static int do_dentry_open(struct file *f, |
| 728 | struct inode *inode, | 738 | struct inode *inode, |
| 729 | int (*open)(struct inode *, struct file *), | 739 | int (*open)(struct inode *, struct file *), |
| @@ -745,7 +755,7 @@ static int do_dentry_open(struct file *f, | |||
| 745 | if (unlikely(f->f_flags & O_PATH)) { | 755 | if (unlikely(f->f_flags & O_PATH)) { |
| 746 | f->f_mode = FMODE_PATH; | 756 | f->f_mode = FMODE_PATH; |
| 747 | f->f_op = &empty_fops; | 757 | f->f_op = &empty_fops; |
| 748 | goto done; | 758 | return 0; |
| 749 | } | 759 | } |
| 750 | 760 | ||
| 751 | if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) { | 761 | if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) { |
| @@ -798,12 +808,7 @@ static int do_dentry_open(struct file *f, | |||
| 798 | f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); | 808 | f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); |
| 799 | 809 | ||
| 800 | file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); | 810 | file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); |
| 801 | done: | 811 | |
| 802 | /* NB: we're sure to have correct a_ops only after f_op->open */ | ||
| 803 | error = -EINVAL; | ||
| 804 | if ((f->f_flags & O_DIRECT) && | ||
| 805 | (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO)) | ||
| 806 | goto out_fput; | ||
| 807 | return 0; | 812 | return 0; |
| 808 | 813 | ||
| 809 | cleanup_all: | 814 | cleanup_all: |
| @@ -818,9 +823,6 @@ cleanup_file: | |||
| 818 | f->f_path.dentry = NULL; | 823 | f->f_path.dentry = NULL; |
| 819 | f->f_inode = NULL; | 824 | f->f_inode = NULL; |
| 820 | return error; | 825 | return error; |
| 821 | out_fput: | ||
| 822 | fput(f); | ||
| 823 | return error; | ||
| 824 | } | 826 | } |
| 825 | 827 | ||
| 826 | /** | 828 | /** |
| @@ -918,14 +920,20 @@ struct file *dentry_open(const struct path *path, int flags, | |||
| 918 | BUG_ON(!path->mnt); | 920 | BUG_ON(!path->mnt); |
| 919 | 921 | ||
| 920 | f = get_empty_filp(); | 922 | f = get_empty_filp(); |
| 921 | if (IS_ERR(f)) | 923 | if (!IS_ERR(f)) { |
| 922 | return f; | 924 | f->f_flags = flags; |
| 923 | 925 | error = vfs_open(path, f, cred); | |
| 924 | f->f_flags = flags; | 926 | if (!error) { |
| 925 | error = vfs_open(path, f, cred); | 927 | /* from now on we need fput() to dispose of f */ |
| 926 | if (error) { | 928 | error = open_check_o_direct(f); |
| 927 | put_filp(f); | 929 | if (error) { |
| 928 | return ERR_PTR(error); | 930 | fput(f); |
| 931 | f = ERR_PTR(error); | ||
| 932 | } | ||
| 933 | } else { | ||
| 934 | put_filp(f); | ||
| 935 | f = ERR_PTR(error); | ||
| 936 | } | ||
| 929 | } | 937 | } |
| 930 | return f; | 938 | return f; |
| 931 | } | 939 | } |
