Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs fixes from Al Viro.

- fix io_destroy()/aio_complete() race

- the vfs_open() change to get rid of open_check_o_direct() boilerplate
was nice, but buggy. Al has a patch avoiding a revert, but that's
definitely not a last-day fodder, so for now revert it is...

* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
Revert "fs: fold open_check_o_direct into do_dentry_open"
fix io_destroy()/aio_complete() race

+34 -21
+1 -2
fs/aio.c
··· 634 634 while (!list_empty(&ctx->active_reqs)) { 635 635 req = list_first_entry(&ctx->active_reqs, 636 636 struct aio_kiocb, ki_list); 637 - 638 - list_del_init(&req->ki_list); 639 637 kiocb_cancel(req); 638 + list_del_init(&req->ki_list); 640 639 } 641 640 642 641 spin_unlock_irq(&ctx->ctx_lock);
+1
fs/internal.h
··· 125 125 int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group, 126 126 int flag); 127 127 128 + extern int open_check_o_direct(struct file *f); 128 129 extern int vfs_open(const struct path *, struct file *, const struct cred *); 129 130 extern struct file *filp_clone_open(struct file *); 130 131
+6 -1
fs/namei.c
··· 3367 3367 goto out; 3368 3368 *opened |= FILE_OPENED; 3369 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 3373 if (!error && will_truncate) 3372 3374 error = handle_truncate(file); 3373 3375 out: ··· 3449 3447 error = finish_open(file, child, NULL, opened); 3450 3448 if (error) 3451 3449 goto out2; 3450 + error = open_check_o_direct(file); 3451 + if (error) 3452 + fput(file); 3452 3453 out2: 3453 3454 mnt_drop_write(path.mnt); 3454 3455 out:
+26 -18
fs/open.c
··· 724 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 737 static int do_dentry_open(struct file *f, 728 738 struct inode *inode, 729 739 int (*open)(struct inode *, struct file *), ··· 755 745 if (unlikely(f->f_flags & O_PATH)) { 756 746 f->f_mode = FMODE_PATH; 757 747 f->f_op = &empty_fops; 758 - goto done; 748 + return 0; 759 749 } 760 750 761 751 if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) { ··· 808 798 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); 809 799 810 800 file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); 811 - done: 812 - /* NB: we're sure to have correct a_ops only after f_op->open */ 813 - error = -EINVAL; 814 - if ((f->f_flags & O_DIRECT) && 815 - (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO)) 816 - goto out_fput; 801 + 817 802 return 0; 818 803 819 804 cleanup_all: ··· 822 817 f->f_path.mnt = NULL; 823 818 f->f_path.dentry = NULL; 824 819 f->f_inode = NULL; 825 - return error; 826 - out_fput: 827 - fput(f); 828 820 return error; 829 821 } 830 822 ··· 920 918 BUG_ON(!path->mnt); 921 919 922 920 f = get_empty_filp(); 923 - if (IS_ERR(f)) 924 - return f; 925 - 926 - f->f_flags = flags; 927 - error = vfs_open(path, f, cred); 928 - if (error) { 929 - put_filp(f); 930 - return ERR_PTR(error); 921 + if (!IS_ERR(f)) { 922 + f->f_flags = flags; 923 + error = vfs_open(path, f, cred); 924 + if (!error) { 925 + /* from now on we need fput() to dispose of f */ 926 + error = open_check_o_direct(f); 927 + if (error) { 928 + fput(f); 929 + f = ERR_PTR(error); 930 + } 931 + } else { 932 + put_filp(f); 933 + f = ERR_PTR(error); 934 + } 931 935 } 932 936 return f; 933 937 }