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

Merge tag 'io_uring-5.10-2020-11-20' of git://git.kernel.dk/linux-block

Pull io_uring fixes from Jens Axboe:
"Mostly regression or stable fodder:

- Disallow async path resolution of /proc/self

- Tighten constraints for segmented async buffered reads

- Fix double completion for a retry error case

- Fix for fixed file life times (Pavel)"

* tag 'io_uring-5.10-2020-11-20' of git://git.kernel.dk/linux-block:
io_uring: order refnode recycling
io_uring: get an active ref_node from files_data
io_uring: don't double complete failed reissue request
mm: never attempt async page lock if we've transferred data already
io_uring: handle -EOPNOTSUPP on path resolution
proc: don't allow async path resolution of /proc/self components

+63 -19
+42 -15
fs/io_uring.c
··· 205 205 struct list_head file_list; 206 206 struct fixed_file_data *file_data; 207 207 struct llist_node llist; 208 + bool done; 208 209 }; 209 210 210 211 struct fixed_file_data { ··· 479 478 struct io_open { 480 479 struct file *file; 481 480 int dfd; 481 + bool ignore_nonblock; 482 482 struct filename *filename; 483 483 struct open_how how; 484 484 unsigned long nofile; ··· 2579 2577 } 2580 2578 end_req: 2581 2579 req_set_fail_links(req); 2582 - io_req_complete(req, ret); 2583 2580 return false; 2584 2581 } 2585 2582 #endif ··· 3796 3795 return ret; 3797 3796 } 3798 3797 req->open.nofile = rlimit(RLIMIT_NOFILE); 3798 + req->open.ignore_nonblock = false; 3799 3799 req->flags |= REQ_F_NEED_CLEANUP; 3800 3800 return 0; 3801 3801 } ··· 3840 3838 struct file *file; 3841 3839 int ret; 3842 3840 3843 - if (force_nonblock) 3841 + if (force_nonblock && !req->open.ignore_nonblock) 3844 3842 return -EAGAIN; 3845 3843 3846 3844 ret = build_open_flags(&req->open.how, &op); ··· 3855 3853 if (IS_ERR(file)) { 3856 3854 put_unused_fd(ret); 3857 3855 ret = PTR_ERR(file); 3856 + /* 3857 + * A work-around to ensure that /proc/self works that way 3858 + * that it should - if we get -EOPNOTSUPP back, then assume 3859 + * that proc_self_get_link() failed us because we're in async 3860 + * context. We should be safe to retry this from the task 3861 + * itself with force_nonblock == false set, as it should not 3862 + * block on lookup. Would be nice to know this upfront and 3863 + * avoid the async dance, but doesn't seem feasible. 3864 + */ 3865 + if (ret == -EOPNOTSUPP && io_wq_current_is_worker()) { 3866 + req->open.ignore_nonblock = true; 3867 + refcount_inc(&req->refs); 3868 + io_req_task_queue(req); 3869 + return 0; 3870 + } 3858 3871 } else { 3859 3872 fsnotify_open(file); 3860 3873 fd_install(ret, file); ··· 6974 6957 return -ENXIO; 6975 6958 6976 6959 spin_lock(&data->lock); 6977 - if (!list_empty(&data->ref_list)) 6978 - ref_node = list_first_entry(&data->ref_list, 6979 - struct fixed_file_ref_node, node); 6960 + ref_node = data->node; 6980 6961 spin_unlock(&data->lock); 6981 6962 if (ref_node) 6982 6963 percpu_ref_kill(&ref_node->refs); ··· 7323 7308 kfree(pfile); 7324 7309 } 7325 7310 7326 - spin_lock(&file_data->lock); 7327 - list_del(&ref_node->node); 7328 - spin_unlock(&file_data->lock); 7329 - 7330 7311 percpu_ref_exit(&ref_node->refs); 7331 7312 kfree(ref_node); 7332 7313 percpu_ref_put(&file_data->refs); ··· 7349 7338 static void io_file_data_ref_zero(struct percpu_ref *ref) 7350 7339 { 7351 7340 struct fixed_file_ref_node *ref_node; 7341 + struct fixed_file_data *data; 7352 7342 struct io_ring_ctx *ctx; 7353 - bool first_add; 7343 + bool first_add = false; 7354 7344 int delay = HZ; 7355 7345 7356 7346 ref_node = container_of(ref, struct fixed_file_ref_node, refs); 7357 - ctx = ref_node->file_data->ctx; 7347 + data = ref_node->file_data; 7348 + ctx = data->ctx; 7358 7349 7359 - if (percpu_ref_is_dying(&ctx->file_data->refs)) 7350 + spin_lock(&data->lock); 7351 + ref_node->done = true; 7352 + 7353 + while (!list_empty(&data->ref_list)) { 7354 + ref_node = list_first_entry(&data->ref_list, 7355 + struct fixed_file_ref_node, node); 7356 + /* recycle ref nodes in order */ 7357 + if (!ref_node->done) 7358 + break; 7359 + list_del(&ref_node->node); 7360 + first_add |= llist_add(&ref_node->llist, &ctx->file_put_llist); 7361 + } 7362 + spin_unlock(&data->lock); 7363 + 7364 + if (percpu_ref_is_dying(&data->refs)) 7360 7365 delay = 0; 7361 7366 7362 - first_add = llist_add(&ref_node->llist, &ctx->file_put_llist); 7363 7367 if (!delay) 7364 7368 mod_delayed_work(system_wq, &ctx->file_put_work, 0); 7365 7369 else if (first_add) ··· 7398 7372 INIT_LIST_HEAD(&ref_node->node); 7399 7373 INIT_LIST_HEAD(&ref_node->file_list); 7400 7374 ref_node->file_data = ctx->file_data; 7375 + ref_node->done = false; 7401 7376 return ref_node; 7402 7377 } 7403 7378 ··· 7494 7467 7495 7468 file_data->node = ref_node; 7496 7469 spin_lock(&file_data->lock); 7497 - list_add(&ref_node->node, &file_data->ref_list); 7470 + list_add_tail(&ref_node->node, &file_data->ref_list); 7498 7471 spin_unlock(&file_data->lock); 7499 7472 percpu_ref_get(&file_data->refs); 7500 7473 return ret; ··· 7653 7626 if (needs_switch) { 7654 7627 percpu_ref_kill(&data->node->refs); 7655 7628 spin_lock(&data->lock); 7656 - list_add(&ref_node->node, &data->ref_list); 7629 + list_add_tail(&ref_node->node, &data->ref_list); 7657 7630 data->node = ref_node; 7658 7631 spin_unlock(&data->lock); 7659 7632 percpu_ref_get(&ctx->file_data->refs);
+7
fs/proc/self.c
··· 16 16 pid_t tgid = task_tgid_nr_ns(current, ns); 17 17 char *name; 18 18 19 + /* 20 + * Not currently supported. Once we can inherit all of struct pid, 21 + * we can allow this. 22 + */ 23 + if (current->flags & PF_KTHREAD) 24 + return ERR_PTR(-EOPNOTSUPP); 25 + 19 26 if (!tgid) 20 27 return ERR_PTR(-ENOENT); 21 28 /* max length of unsigned int in decimal + NULL term */
+14 -4
mm/filemap.c
··· 2347 2347 2348 2348 page_not_up_to_date: 2349 2349 /* Get exclusive access to the page ... */ 2350 - if (iocb->ki_flags & IOCB_WAITQ) 2350 + if (iocb->ki_flags & IOCB_WAITQ) { 2351 + if (written) { 2352 + put_page(page); 2353 + goto out; 2354 + } 2351 2355 error = lock_page_async(page, iocb->ki_waitq); 2352 - else 2356 + } else { 2353 2357 error = lock_page_killable(page); 2358 + } 2354 2359 if (unlikely(error)) 2355 2360 goto readpage_error; 2356 2361 ··· 2398 2393 } 2399 2394 2400 2395 if (!PageUptodate(page)) { 2401 - if (iocb->ki_flags & IOCB_WAITQ) 2396 + if (iocb->ki_flags & IOCB_WAITQ) { 2397 + if (written) { 2398 + put_page(page); 2399 + goto out; 2400 + } 2402 2401 error = lock_page_async(page, iocb->ki_waitq); 2403 - else 2402 + } else { 2404 2403 error = lock_page_killable(page); 2404 + } 2405 2405 2406 2406 if (unlikely(error)) 2407 2407 goto readpage_error;