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.9-2020-09-06' of git://git.kernel.dk/linux-block

Pull more io_uring fixes from Jens Axboe:
"Two followup fixes. One is fixing a regression from this merge window,
the other is two commits fixing cancelation of deferred requests.

Both have gone through full testing, and both spawned a few new
regression test additions to liburing.

- Don't play games with const, properly store the output iovec and
assign it as needed.

- Deferred request cancelation fix (Pavel)"

* tag 'io_uring-5.9-2020-09-06' of git://git.kernel.dk/linux-block:
io_uring: fix linked deferred ->files cancellation
io_uring: fix cancel of deferred reqs with ->files
io_uring: fix explicit async read/write mapping for large segments

+52 -3
+52 -3
fs/io_uring.c
··· 2980 2980 bool force_nonblock) 2981 2981 { 2982 2982 struct io_async_rw *iorw = &req->io->rw; 2983 + struct iovec *iov; 2983 2984 ssize_t ret; 2984 2985 2985 - iorw->iter.iov = iorw->fast_iov; 2986 - ret = __io_import_iovec(rw, req, (struct iovec **) &iorw->iter.iov, 2987 - &iorw->iter, !force_nonblock); 2986 + iorw->iter.iov = iov = iorw->fast_iov; 2987 + ret = __io_import_iovec(rw, req, &iov, &iorw->iter, !force_nonblock); 2988 2988 if (unlikely(ret < 0)) 2989 2989 return ret; 2990 2990 2991 + iorw->iter.iov = iov; 2991 2992 io_req_map_rw(req, iorw->iter.iov, iorw->fast_iov, &iorw->iter); 2992 2993 return 0; 2993 2994 } ··· 8024 8023 return false; 8025 8024 } 8026 8025 8026 + static inline bool io_match_files(struct io_kiocb *req, 8027 + struct files_struct *files) 8028 + { 8029 + return (req->flags & REQ_F_WORK_INITIALIZED) && req->work.files == files; 8030 + } 8031 + 8032 + static bool io_match_link_files(struct io_kiocb *req, 8033 + struct files_struct *files) 8034 + { 8035 + struct io_kiocb *link; 8036 + 8037 + if (io_match_files(req, files)) 8038 + return true; 8039 + if (req->flags & REQ_F_LINK_HEAD) { 8040 + list_for_each_entry(link, &req->link_list, link_list) { 8041 + if (io_match_files(link, files)) 8042 + return true; 8043 + } 8044 + } 8045 + return false; 8046 + } 8047 + 8027 8048 /* 8028 8049 * We're looking to cancel 'req' because it's holding on to our files, but 8029 8050 * 'req' could be a link to another request. See if it is, and cancel that ··· 8120 8097 io_timeout_remove_link(ctx, req); 8121 8098 } 8122 8099 8100 + static void io_cancel_defer_files(struct io_ring_ctx *ctx, 8101 + struct files_struct *files) 8102 + { 8103 + struct io_defer_entry *de = NULL; 8104 + LIST_HEAD(list); 8105 + 8106 + spin_lock_irq(&ctx->completion_lock); 8107 + list_for_each_entry_reverse(de, &ctx->defer_list, list) { 8108 + if (io_match_link_files(de->req, files)) { 8109 + list_cut_position(&list, &ctx->defer_list, &de->list); 8110 + break; 8111 + } 8112 + } 8113 + spin_unlock_irq(&ctx->completion_lock); 8114 + 8115 + while (!list_empty(&list)) { 8116 + de = list_first_entry(&list, struct io_defer_entry, list); 8117 + list_del_init(&de->list); 8118 + req_set_fail_links(de->req); 8119 + io_put_req(de->req); 8120 + io_req_complete(de->req, -ECANCELED); 8121 + kfree(de); 8122 + } 8123 + } 8124 + 8123 8125 static void io_uring_cancel_files(struct io_ring_ctx *ctx, 8124 8126 struct files_struct *files) 8125 8127 { 8126 8128 if (list_empty_careful(&ctx->inflight_list)) 8127 8129 return; 8128 8130 8131 + io_cancel_defer_files(ctx, files); 8129 8132 /* cancel all at once, should be faster than doing it one by one*/ 8130 8133 io_wq_cancel_cb(ctx->io_wq, io_wq_files_match, files, true); 8131 8134