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 tag 'io_uring-5.7-2020-05-08' of git://git.kernel.dk/linux-block

Pull io_uring fixes from Jens Axboe:

- Fix finish_wait() balancing in file cancelation (Xiaoguang)

- Ensure early cleanup of resources in ring map failure (Xiaoguang)

- Ensure IORING_OP_SLICE does the right file mode checks (Pavel)

- Remove file opening from openat/openat2/statx, it's not needed and
messes with O_PATH

* tag 'io_uring-5.7-2020-05-08' of git://git.kernel.dk/linux-block:
io_uring: don't use 'fd' for openat/openat2/statx
splice: move f_mode checks to do_{splice,tee}()
io_uring: handle -EFAULT properly in io_uring_setup()
io_uring: fix mismatched finish_wait() calls in io_uring_cancel_files()

+40 -70
+22 -43
fs/io_uring.c
··· 680 680 unsigned needs_mm : 1; 681 681 /* needs req->file assigned */ 682 682 unsigned needs_file : 1; 683 - /* needs req->file assigned IFF fd is >= 0 */ 684 - unsigned fd_non_neg : 1; 685 683 /* hash wq insertion if file is a regular file */ 686 684 unsigned hash_reg_file : 1; 687 685 /* unbound wq insertion if file is a non-regular file */ ··· 782 784 .needs_file = 1, 783 785 }, 784 786 [IORING_OP_OPENAT] = { 785 - .needs_file = 1, 786 - .fd_non_neg = 1, 787 787 .file_table = 1, 788 788 .needs_fs = 1, 789 789 }, ··· 795 799 }, 796 800 [IORING_OP_STATX] = { 797 801 .needs_mm = 1, 798 - .needs_file = 1, 799 - .fd_non_neg = 1, 800 802 .needs_fs = 1, 801 803 .file_table = 1, 802 804 }, ··· 831 837 .buffer_select = 1, 832 838 }, 833 839 [IORING_OP_OPENAT2] = { 834 - .needs_file = 1, 835 - .fd_non_neg = 1, 836 840 .file_table = 1, 837 841 .needs_fs = 1, 838 842 }, ··· 5360 5368 io_steal_work(req, workptr); 5361 5369 } 5362 5370 5363 - static int io_req_needs_file(struct io_kiocb *req, int fd) 5364 - { 5365 - if (!io_op_defs[req->opcode].needs_file) 5366 - return 0; 5367 - if ((fd == -1 || fd == AT_FDCWD) && io_op_defs[req->opcode].fd_non_neg) 5368 - return 0; 5369 - return 1; 5370 - } 5371 - 5372 5371 static inline struct file *io_file_from_index(struct io_ring_ctx *ctx, 5373 5372 int index) 5374 5373 { ··· 5397 5414 } 5398 5415 5399 5416 static int io_req_set_file(struct io_submit_state *state, struct io_kiocb *req, 5400 - int fd, unsigned int flags) 5417 + int fd) 5401 5418 { 5402 5419 bool fixed; 5403 5420 5404 - if (!io_req_needs_file(req, fd)) 5405 - return 0; 5406 - 5407 - fixed = (flags & IOSQE_FIXED_FILE); 5421 + fixed = (req->flags & REQ_F_FIXED_FILE) != 0; 5408 5422 if (unlikely(!fixed && req->needs_fixed_file)) 5409 5423 return -EBADF; 5410 5424 ··· 5778 5798 struct io_submit_state *state, bool async) 5779 5799 { 5780 5800 unsigned int sqe_flags; 5781 - int id, fd; 5801 + int id; 5782 5802 5783 5803 /* 5784 5804 * All io need record the previous position, if LINK vs DARIN, ··· 5830 5850 IOSQE_ASYNC | IOSQE_FIXED_FILE | 5831 5851 IOSQE_BUFFER_SELECT | IOSQE_IO_LINK); 5832 5852 5833 - fd = READ_ONCE(sqe->fd); 5834 - return io_req_set_file(state, req, fd, sqe_flags); 5853 + if (!io_op_defs[req->opcode].needs_file) 5854 + return 0; 5855 + 5856 + return io_req_set_file(state, req, READ_ONCE(sqe->fd)); 5835 5857 } 5836 5858 5837 5859 static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr, ··· 7342 7360 static void io_uring_cancel_files(struct io_ring_ctx *ctx, 7343 7361 struct files_struct *files) 7344 7362 { 7345 - struct io_kiocb *req; 7346 - DEFINE_WAIT(wait); 7347 - 7348 7363 while (!list_empty_careful(&ctx->inflight_list)) { 7349 - struct io_kiocb *cancel_req = NULL; 7364 + struct io_kiocb *cancel_req = NULL, *req; 7365 + DEFINE_WAIT(wait); 7350 7366 7351 7367 spin_lock_irq(&ctx->inflight_lock); 7352 7368 list_for_each_entry(req, &ctx->inflight_list, inflight_entry) { ··· 7384 7404 */ 7385 7405 if (refcount_sub_and_test(2, &cancel_req->refs)) { 7386 7406 io_put_req(cancel_req); 7407 + finish_wait(&ctx->inflight_wait, &wait); 7387 7408 continue; 7388 7409 } 7389 7410 } ··· 7392 7411 io_wq_cancel_work(ctx->io_wq, &cancel_req->work); 7393 7412 io_put_req(cancel_req); 7394 7413 schedule(); 7414 + finish_wait(&ctx->inflight_wait, &wait); 7395 7415 } 7396 - finish_wait(&ctx->inflight_wait, &wait); 7397 7416 } 7398 7417 7399 7418 static int io_uring_flush(struct file *file, void *data) ··· 7742 7761 return ret; 7743 7762 } 7744 7763 7745 - static int io_uring_create(unsigned entries, struct io_uring_params *p) 7764 + static int io_uring_create(unsigned entries, struct io_uring_params *p, 7765 + struct io_uring_params __user *params) 7746 7766 { 7747 7767 struct user_struct *user = NULL; 7748 7768 struct io_ring_ctx *ctx; ··· 7835 7853 p->cq_off.overflow = offsetof(struct io_rings, cq_overflow); 7836 7854 p->cq_off.cqes = offsetof(struct io_rings, cqes); 7837 7855 7856 + p->features = IORING_FEAT_SINGLE_MMAP | IORING_FEAT_NODROP | 7857 + IORING_FEAT_SUBMIT_STABLE | IORING_FEAT_RW_CUR_POS | 7858 + IORING_FEAT_CUR_PERSONALITY | IORING_FEAT_FAST_POLL; 7859 + 7860 + if (copy_to_user(params, p, sizeof(*p))) { 7861 + ret = -EFAULT; 7862 + goto err; 7863 + } 7838 7864 /* 7839 7865 * Install ring fd as the very last thing, so we don't risk someone 7840 7866 * having closed it before we finish setup ··· 7851 7861 if (ret < 0) 7852 7862 goto err; 7853 7863 7854 - p->features = IORING_FEAT_SINGLE_MMAP | IORING_FEAT_NODROP | 7855 - IORING_FEAT_SUBMIT_STABLE | IORING_FEAT_RW_CUR_POS | 7856 - IORING_FEAT_CUR_PERSONALITY | IORING_FEAT_FAST_POLL; 7857 7864 trace_io_uring_create(ret, ctx, p->sq_entries, p->cq_entries, p->flags); 7858 7865 return ret; 7859 7866 err: ··· 7866 7879 static long io_uring_setup(u32 entries, struct io_uring_params __user *params) 7867 7880 { 7868 7881 struct io_uring_params p; 7869 - long ret; 7870 7882 int i; 7871 7883 7872 7884 if (copy_from_user(&p, params, sizeof(p))) ··· 7880 7894 IORING_SETUP_CLAMP | IORING_SETUP_ATTACH_WQ)) 7881 7895 return -EINVAL; 7882 7896 7883 - ret = io_uring_create(entries, &p); 7884 - if (ret < 0) 7885 - return ret; 7886 - 7887 - if (copy_to_user(params, &p, sizeof(p))) 7888 - return -EFAULT; 7889 - 7890 - return ret; 7897 + return io_uring_create(entries, &p, params); 7891 7898 } 7892 7899 7893 7900 SYSCALL_DEFINE2(io_uring_setup, u32, entries,
+18 -27
fs/splice.c
··· 1118 1118 loff_t offset; 1119 1119 long ret; 1120 1120 1121 + if (unlikely(!(in->f_mode & FMODE_READ) || 1122 + !(out->f_mode & FMODE_WRITE))) 1123 + return -EBADF; 1124 + 1121 1125 ipipe = get_pipe_info(in); 1122 1126 opipe = get_pipe_info(out); 1123 1127 1124 1128 if (ipipe && opipe) { 1125 1129 if (off_in || off_out) 1126 1130 return -ESPIPE; 1127 - 1128 - if (!(in->f_mode & FMODE_READ)) 1129 - return -EBADF; 1130 - 1131 - if (!(out->f_mode & FMODE_WRITE)) 1132 - return -EBADF; 1133 1131 1134 1132 /* Splicing to self would be fun, but... */ 1135 1133 if (ipipe == opipe) ··· 1150 1152 } else { 1151 1153 offset = out->f_pos; 1152 1154 } 1153 - 1154 - if (unlikely(!(out->f_mode & FMODE_WRITE))) 1155 - return -EBADF; 1156 1155 1157 1156 if (unlikely(out->f_flags & O_APPEND)) 1158 1157 return -EINVAL; ··· 1435 1440 error = -EBADF; 1436 1441 in = fdget(fd_in); 1437 1442 if (in.file) { 1438 - if (in.file->f_mode & FMODE_READ) { 1439 - out = fdget(fd_out); 1440 - if (out.file) { 1441 - if (out.file->f_mode & FMODE_WRITE) 1442 - error = do_splice(in.file, off_in, 1443 - out.file, off_out, 1444 - len, flags); 1445 - fdput(out); 1446 - } 1443 + out = fdget(fd_out); 1444 + if (out.file) { 1445 + error = do_splice(in.file, off_in, out.file, off_out, 1446 + len, flags); 1447 + fdput(out); 1447 1448 } 1448 1449 fdput(in); 1449 1450 } ··· 1761 1770 struct pipe_inode_info *opipe = get_pipe_info(out); 1762 1771 int ret = -EINVAL; 1763 1772 1773 + if (unlikely(!(in->f_mode & FMODE_READ) || 1774 + !(out->f_mode & FMODE_WRITE))) 1775 + return -EBADF; 1776 + 1764 1777 /* 1765 1778 * Duplicate the contents of ipipe to opipe without actually 1766 1779 * copying the data. ··· 1790 1795 1791 1796 SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags) 1792 1797 { 1793 - struct fd in; 1798 + struct fd in, out; 1794 1799 int error; 1795 1800 1796 1801 if (unlikely(flags & ~SPLICE_F_ALL)) ··· 1802 1807 error = -EBADF; 1803 1808 in = fdget(fdin); 1804 1809 if (in.file) { 1805 - if (in.file->f_mode & FMODE_READ) { 1806 - struct fd out = fdget(fdout); 1807 - if (out.file) { 1808 - if (out.file->f_mode & FMODE_WRITE) 1809 - error = do_tee(in.file, out.file, 1810 - len, flags); 1811 - fdput(out); 1812 - } 1810 + out = fdget(fdout); 1811 + if (out.file) { 1812 + error = do_tee(in.file, out.file, len, flags); 1813 + fdput(out); 1813 1814 } 1814 1815 fdput(in); 1815 1816 }