From patchwork Tue Jan 7 17:00:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Axboe X-Patchwork-Id: 11321467 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C452E921 for ; Tue, 7 Jan 2020 17:08:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A1911214D8 for ; Tue, 7 Jan 2020 17:08:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=kernel-dk.20150623.gappssmtp.com header.i=@kernel-dk.20150623.gappssmtp.com header.b="e4Oe1q5g" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728372AbgAGRIu (ORCPT ); Tue, 7 Jan 2020 12:08:50 -0500 Received: from mail-il1-f193.google.com ([209.85.166.193]:34491 "EHLO mail-il1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728266AbgAGRIt (ORCPT ); Tue, 7 Jan 2020 12:08:49 -0500 Received: by mail-il1-f193.google.com with SMTP id s15so228392iln.1 for ; Tue, 07 Jan 2020 09:08:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel-dk.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CkTeT9dMuqRE2KnIp/DqwjMGpbw3/baJ/fs0la8Y1qc=; b=e4Oe1q5gukYZz4HLHJcP6sglwTrktCOMxAAPST6QfcGz7NxrErwBGE6xIP9lxOebY0 ccgTmPSaUWXBw76LhVNeel+2SlDFxwEQuYa32lJCbnCmG5vK9iZJNfV/HCchSdl5EHKT KGESbl/h9TfwlCmso8yTFdXFqTSREyKPdhU2w4eLhNMYsZ/wEb39x98wWDuc+MMdTG81 QEagAvCa6KByOhucSeGCywEbTz40MqSOv8Yfkre3rrspXlU9EeO34hmfy8/JD8JodC3r pTjpoAVzbh7xLU8K0Mwz+F0XTTolXrsgl8juybiCAWCFdEZvf246r29cZh+1+xvG+bja XhgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=CkTeT9dMuqRE2KnIp/DqwjMGpbw3/baJ/fs0la8Y1qc=; b=H8YOs8ApkRQX1Mt12zN1q+1KKCYJSbs6LBkHDDeajsq2IQ4ANTgHbJfq0kNUdZP2Jp 0nL8r/MjSXruX9lAlTnlh/h55t8VEl2GrWYM4Bfcz4uT6Jmb2cQMmyzLWLDeopVG87Ab Z9iCPV5K+V7m7VDFAKIkoJPWdZDD1BF3Y+RRAQFqmOvx2wyxekTuHjXVGVpwdHE9iVwD M8vmdVwmHwXd5yGvSyhyzCAk1EDbo/8R8efdmDdHSDbuIsXrM/KXp9JKRpY7mCwlj5G6 Lok5s/0p1vpf8LwYQNG1sgHhcD9dsmEMXNqYUP24vcEM1pU1wtWzgQ5uTy246ILFuU+I NB/A== X-Gm-Message-State: APjAAAVkU3PvdjX4rkoMTlCHk4obSP3b0aFgmVf06I7anOOHIs2h66tZ wItLQXELD83NdB8Y89x9mXd/Wg== X-Google-Smtp-Source: APXvYqxMgg8kBG7Lt3o7312cVCkomC/XW4qdyrEWa1cdfvlnQCkx3pqt4i1CW34sGwSd6IAm8MNjZg== X-Received: by 2002:a92:58d7:: with SMTP id z84mr14367ilf.179.1578416437866; Tue, 07 Jan 2020 09:00:37 -0800 (PST) Received: from x1.localdomain ([65.144.74.34]) by smtp.gmail.com with ESMTPSA id g4sm42547iln.81.2020.01.07.09.00.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Jan 2020 09:00:37 -0800 (PST) From: Jens Axboe To: io-uring@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, viro@zeniv.linux.org.uk, Jens Axboe Subject: [PATCH 1/6] fs: add namei support for doing a non-blocking path lookup Date: Tue, 7 Jan 2020 10:00:29 -0700 Message-Id: <20200107170034.16165-2-axboe@kernel.dk> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200107170034.16165-1-axboe@kernel.dk> References: <20200107170034.16165-1-axboe@kernel.dk> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org If the fast lookup fails, then return -EAGAIN to have the caller retry the path lookup. Assume that a dentry having any of: ->d_revalidate() ->d_automount() ->d_manage() could block in those callbacks. Preemptively return -EAGAIN if any of these are present. This is in preparation for supporting non-blocking open. Signed-off-by: Jens Axboe --- fs/namei.c | 21 ++++++++++++++++++++- include/linux/namei.h | 2 ++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/fs/namei.c b/fs/namei.c index b367fdb91682..ed108a41634f 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1641,6 +1641,17 @@ static struct dentry *__lookup_hash(const struct qstr *name, return dentry; } +static inline bool lookup_could_block(struct dentry *dentry, unsigned int flags) +{ + const struct dentry_operations *ops = dentry->d_op; + + if (!ops || !(flags & LOOKUP_NONBLOCK)) + return 0; + + /* assume these dentry ops may block */ + return ops->d_revalidate || ops->d_automount || ops->d_manage; +} + static int lookup_fast(struct nameidata *nd, struct path *path, struct inode **inode, unsigned *seqp) @@ -1665,6 +1676,9 @@ static int lookup_fast(struct nameidata *nd, return 0; } + if (unlikely(lookup_could_block(dentry, nd->flags))) + return -EAGAIN; + /* * This sequence count validates that the inode matches * the dentry name information from lookup. @@ -1707,7 +1721,10 @@ static int lookup_fast(struct nameidata *nd, dentry = __d_lookup(parent, &nd->last); if (unlikely(!dentry)) return 0; - status = d_revalidate(dentry, nd->flags); + if (unlikely(lookup_could_block(dentry, nd->flags))) + status = -EAGAIN; + else + status = d_revalidate(dentry, nd->flags); } if (unlikely(status <= 0)) { if (!status) @@ -1912,6 +1929,8 @@ static int walk_component(struct nameidata *nd, int flags) if (unlikely(err <= 0)) { if (err < 0) return err; + if (nd->flags & LOOKUP_NONBLOCK) + return -EAGAIN; path.dentry = lookup_slow(&nd->last, nd->path.dentry, nd->flags); if (IS_ERR(path.dentry)) diff --git a/include/linux/namei.h b/include/linux/namei.h index 4e77068f7a1a..392eb439f88b 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -49,6 +49,8 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; /* LOOKUP_* flags which do scope-related checks based on the dirfd. */ #define LOOKUP_IS_SCOPED (LOOKUP_BENEATH | LOOKUP_IN_ROOT) +#define LOOKUP_NONBLOCK 0x200000 /* don't block for lookup */ + extern int path_pts(struct path *path); extern int user_path_at_empty(int, const char __user *, unsigned, struct path *, int *empty); From patchwork Tue Jan 7 17:00:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Axboe X-Patchwork-Id: 11321463 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 96A78921 for ; Tue, 7 Jan 2020 17:06:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7417C21744 for ; Tue, 7 Jan 2020 17:06:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=kernel-dk.20150623.gappssmtp.com header.i=@kernel-dk.20150623.gappssmtp.com header.b="s6/KrsEq" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728386AbgAGRGm (ORCPT ); Tue, 7 Jan 2020 12:06:42 -0500 Received: from mail-il1-f193.google.com ([209.85.166.193]:43814 "EHLO mail-il1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728236AbgAGRGl (ORCPT ); Tue, 7 Jan 2020 12:06:41 -0500 Received: by mail-il1-f193.google.com with SMTP id v69so169834ili.10 for ; Tue, 07 Jan 2020 09:06:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel-dk.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=kbiWj3hsFb2raXSepJdHXFBL46D9EdghCDfj9UYmh+s=; b=s6/KrsEqptUnzDAHMDp3iBPuRHoDPMO6AgWgBQVpFET8ySrMo+bmF+LfCnrvzXcifD ndsX3eZ+gDijg/5ejOD0eoGaMsOS7dJUxiKSTU+nhnFgPY8ry9/BnMnk1XKCY2scAUKh +WPwcZY4GRadWa1Rf8mVN714ahobfDdva5HCrB0AEJsCHayIfFbT32Crs7beif3x4+mo HlLIavx4hmx0LmkOfkwEwHcWtDh4H16r2UYpI0vp/rO/k/a4EU1Gqdmf3lKq9aSWXSV/ 2frlk5BNFVD1decBLG57AlO2VITgG0oDBZvH0b7W7s/Ia360k0RpJTAQxjN33cHaUeFf MJ8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=kbiWj3hsFb2raXSepJdHXFBL46D9EdghCDfj9UYmh+s=; b=l7FwDurgJDg6cfZ97HAgTaM5iY/T08gzxCodM1c2x/ptmdDIJGgoEdCn2Rf4wG62Fx ajv9RRcEBjhhte2kSU8TMtUXCLz+NloBNMZy0AdUW3BfDP5/4WoqtM56uxIqNW4S87jE y81pv4I7lWfGfC+FwGSU97LMEmeuTAx6gY7NG55uQXfWTKBMhWrWwYw9Yt5mk9DZ0rBQ voNzyYFMAcLsw/aWwIOmM7HByxiFaIEXNXkVQVNtuz0gZoNxTq7n5Tl/GoFghIqye53V WWg9upn5dxUuuwmOnVvNouzGdoiYRai6O6J45Djzt/FdkbMP3lm4xVyQ6G6t3soyUmzR rwyw== X-Gm-Message-State: APjAAAXGBF5hZMh8RFOqXgxdPuhJcQX/BLMAWVlp/lt1juIDF5BbEkup l7PreLCOFK5jnAZuW89nwuYWMA== X-Google-Smtp-Source: APXvYqwKi7uzbzlg5QYDTKhr37E5E0zuCHxDm7viv4yVLeux3ZkGT/MlIqtBJlDfGkcciXxTT8nHzw== X-Received: by 2002:a92:db4f:: with SMTP id w15mr45365ilq.182.1578416438519; Tue, 07 Jan 2020 09:00:38 -0800 (PST) Received: from x1.localdomain ([65.144.74.34]) by smtp.gmail.com with ESMTPSA id g4sm42547iln.81.2020.01.07.09.00.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Jan 2020 09:00:38 -0800 (PST) From: Jens Axboe To: io-uring@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, viro@zeniv.linux.org.uk, Jens Axboe Subject: [PATCH 2/6] fs: make build_open_flags() available internally Date: Tue, 7 Jan 2020 10:00:30 -0700 Message-Id: <20200107170034.16165-3-axboe@kernel.dk> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200107170034.16165-1-axboe@kernel.dk> References: <20200107170034.16165-1-axboe@kernel.dk> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org This is a prep patch for supporting non-blocking open from io_uring. Signed-off-by: Jens Axboe --- fs/internal.h | 2 ++ fs/open.c | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/internal.h b/fs/internal.h index 4a7da1df573d..d6929425365d 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -124,6 +124,8 @@ extern struct file *do_filp_open(int dfd, struct filename *pathname, const struct open_flags *op); extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, const char *, const struct open_flags *); +extern struct open_how build_open_how(int flags, umode_t mode); +extern int build_open_flags(const struct open_how *how, struct open_flags *op); long do_sys_ftruncate(unsigned int fd, loff_t length, int small); long do_faccessat(int dfd, const char __user *filename, int mode); diff --git a/fs/open.c b/fs/open.c index 50a46501bcc9..c103623d28ca 100644 --- a/fs/open.c +++ b/fs/open.c @@ -958,7 +958,7 @@ EXPORT_SYMBOL(open_with_fake_path); #define WILL_CREATE(flags) (flags & (O_CREAT | __O_TMPFILE)) #define O_PATH_FLAGS (O_DIRECTORY | O_NOFOLLOW | O_PATH | O_CLOEXEC) -static inline struct open_how build_open_how(int flags, umode_t mode) +inline struct open_how build_open_how(int flags, umode_t mode) { struct open_how how = { .flags = flags & VALID_OPEN_FLAGS, @@ -974,8 +974,7 @@ static inline struct open_how build_open_how(int flags, umode_t mode) return how; } -static inline int build_open_flags(const struct open_how *how, - struct open_flags *op) +inline int build_open_flags(const struct open_how *how, struct open_flags *op) { int flags = how->flags; int lookup_flags = 0; From patchwork Tue Jan 7 17:00:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Axboe X-Patchwork-Id: 11321461 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B74CF1398 for ; Tue, 7 Jan 2020 17:06:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8DC4A214D8 for ; Tue, 7 Jan 2020 17:06:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=kernel-dk.20150623.gappssmtp.com header.i=@kernel-dk.20150623.gappssmtp.com header.b="UNWzIE7R" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728437AbgAGRGN (ORCPT ); Tue, 7 Jan 2020 12:06:13 -0500 Received: from mail-pf1-f195.google.com ([209.85.210.195]:38759 "EHLO mail-pf1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728236AbgAGRGM (ORCPT ); Tue, 7 Jan 2020 12:06:12 -0500 Received: by mail-pf1-f195.google.com with SMTP id x185so172239pfc.5 for ; Tue, 07 Jan 2020 09:06:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel-dk.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=kLAa950381IHiWSMUCFQoLvVLA8UvLKXWI1RYKTGU10=; b=UNWzIE7R4TpHwJwLYvaRc60Hg38NY0sj28tsFEcq7DRYWHysxyr6WKZ8nOVmNhop3V jBsvdQLFqXDkfm7wRFBA9asKzJFIX0N4S6tHZ5FqQetJ9QD4sXFyEs/E4/syWD2Vcyy7 pMC9tR9Efzp8EezRKY9sdy4Re+VPJBO1KzAab/DO1Lf0FObmCYOLC/3LLQ9TEFWzCC2/ 8Q3PocJGGtSIOMlYITUQ1yDqLJjZ2gIm4YbBN+JmGiFIH0PPZBLkwUuHHLmMk9kOIKxS FcFPi0AIoazdu3GxlQaWd2ekPrdAqicekrnqWFV7dRg/fsUzdW6cElVDYwE70z/Mhk9I r34A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=kLAa950381IHiWSMUCFQoLvVLA8UvLKXWI1RYKTGU10=; b=PGwhKWYGGpMptG4V8EEaetUGFRpqHCtAvs0AQDk4sGUkTn6iCXYEOv5D0Xp+AU+Lr3 2Yeag76SyHHmXnsnKcVto9AqutgA9MM7ZCZxfSWtefQILfKzKvkHHGAAG/5mhrrERaxB lHg+OXYbygtyDI+nn5Ac1Tx1RGABB1nhnb4ce+wMFAKYZsBc/9eCtTsSbW9YtvMU3jmM lAeRCm4Yar1IxXXDxOBZgSP6Wx8pPzlKPlGBNd1di/3LAiuRvSh5nv9YF6C0YPgMF6H8 PFYS12+YWPVT70Kj2W9AZeYtuyHN+Ezvg6G5iQCJc2RWM5Yagewjg8G9Afl5a2q0IhrV ck/g== X-Gm-Message-State: APjAAAUOL8bScNLmdUSFRxzqvT9Kk4SijSazysZWxCUAlMPziCqY+Q6G 2p8Q13qzLya/gCv/kMtgu0/m6vjrhz8= X-Google-Smtp-Source: APXvYqza5WKNNqZbpiRhQg6I3g6gfQedkb94vmr6kTCTXtmY0g/1fwyuxcjbZ3PiV8z/+KuUG6QxjA== X-Received: by 2002:a5d:844d:: with SMTP id w13mr75321336ior.83.1578416439246; Tue, 07 Jan 2020 09:00:39 -0800 (PST) Received: from x1.localdomain ([65.144.74.34]) by smtp.gmail.com with ESMTPSA id g4sm42547iln.81.2020.01.07.09.00.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Jan 2020 09:00:38 -0800 (PST) From: Jens Axboe To: io-uring@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, viro@zeniv.linux.org.uk, Jens Axboe Subject: [PATCH 3/6] io_uring: add support for IORING_OP_OPENAT Date: Tue, 7 Jan 2020 10:00:31 -0700 Message-Id: <20200107170034.16165-4-axboe@kernel.dk> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200107170034.16165-1-axboe@kernel.dk> References: <20200107170034.16165-1-axboe@kernel.dk> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org This works just like openat(2), except it can be performed async. For the normal case of a non-blocking path lookup this will complete inline. If we have to do IO to perform the open, it'll be done from async context. Signed-off-by: Jens Axboe --- fs/io_uring.c | 107 +++++++++++++++++++++++++++++++++- include/uapi/linux/io_uring.h | 2 + 2 files changed, 107 insertions(+), 2 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 1822bf9aba12..53ff67ab5c4b 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -70,6 +70,8 @@ #include #include #include +#include +#include #define CREATE_TRACE_POINTS #include @@ -353,6 +355,15 @@ struct io_sr_msg { int msg_flags; }; +struct io_open { + struct file *file; + int dfd; + umode_t mode; + const char __user *fname; + struct filename *filename; + int flags; +}; + struct io_async_connect { struct sockaddr_storage address; }; @@ -371,12 +382,17 @@ struct io_async_rw { ssize_t size; }; +struct io_async_open { + struct filename *filename; +}; + struct io_async_ctx { union { struct io_async_rw rw; struct io_async_msghdr msg; struct io_async_connect connect; struct io_timeout_data timeout; + struct io_async_open open; }; }; @@ -397,6 +413,7 @@ struct io_kiocb { struct io_timeout timeout; struct io_connect connect; struct io_sr_msg sr_msg; + struct io_open open; }; struct io_async_ctx *io; @@ -2135,6 +2152,79 @@ static int io_fallocate(struct io_kiocb *req, struct io_kiocb **nxt, return 0; } +static int io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) +{ + int ret; + + if (sqe->ioprio || sqe->buf_index) + return -EINVAL; + + req->open.dfd = READ_ONCE(sqe->fd); + req->open.mode = READ_ONCE(sqe->len); + req->open.fname = u64_to_user_ptr(READ_ONCE(sqe->addr)); + req->open.flags = READ_ONCE(sqe->open_flags); + + req->open.filename = getname(req->open.fname); + if (IS_ERR(req->open.filename)) { + ret = PTR_ERR(req->open.filename); + req->open.filename = NULL; + return ret; + } + + return 0; +} + +static void io_openat_async(struct io_wq_work **workptr) +{ + struct io_kiocb *req = container_of(*workptr, struct io_kiocb, work); + struct filename *filename = req->open.filename; + + io_wq_submit_work(workptr); + putname(filename); +} + +static int io_openat(struct io_kiocb *req, struct io_kiocb **nxt, + bool force_nonblock) +{ + struct open_flags op; + struct open_how how; + struct file *file; + int ret; + + how = build_open_how(req->open.flags, req->open.mode); + ret = build_open_flags(&how, &op); + if (ret) + goto err; + if (force_nonblock) + op.lookup_flags |= LOOKUP_NONBLOCK; + + ret = get_unused_fd_flags(how.flags); + if (ret < 0) + goto err; + + file = do_filp_open(req->open.dfd, req->open.filename, &op); + if (IS_ERR(file)) { + put_unused_fd(ret); + ret = PTR_ERR(file); + if (ret == -EAGAIN) { + req->work.flags |= IO_WQ_WORK_NEEDS_FILES; + req->work.func = io_openat_async; + return -EAGAIN; + } + } else { + fsnotify_open(file); + fd_install(ret, file); + } +err: + if (!io_wq_current_is_worker()) + putname(req->open.filename); + if (ret < 0) + req_set_fail_links(req); + io_cqring_add_event(req, ret); + io_put_req_find_next(req, nxt); + return 0; +} + static int io_prep_sfr(struct io_kiocb *req, const struct io_uring_sqe *sqe) { struct io_ring_ctx *ctx = req->ctx; @@ -3160,6 +3250,9 @@ static int io_req_defer_prep(struct io_kiocb *req, case IORING_OP_FALLOCATE: ret = io_fallocate_prep(req, sqe); break; + case IORING_OP_OPENAT: + ret = io_openat_prep(req, sqe); + break; default: printk_once(KERN_WARNING "io_uring: unhandled opcode %d\n", req->opcode); @@ -3322,6 +3415,14 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, } ret = io_fallocate(req, nxt, force_nonblock); break; + case IORING_OP_OPENAT: + if (sqe) { + ret = io_openat_prep(req, sqe); + if (ret) + break; + } + ret = io_openat(req, nxt, force_nonblock); + break; default: ret = -EINVAL; break; @@ -3403,7 +3504,7 @@ static bool io_req_op_valid(int op) return op >= IORING_OP_NOP && op < IORING_OP_LAST; } -static int io_req_needs_file(struct io_kiocb *req) +static int io_req_needs_file(struct io_kiocb *req, int fd) { switch (req->opcode) { case IORING_OP_NOP: @@ -3413,6 +3514,8 @@ static int io_req_needs_file(struct io_kiocb *req) case IORING_OP_ASYNC_CANCEL: case IORING_OP_LINK_TIMEOUT: return 0; + case IORING_OP_OPENAT: + return fd != -1; default: if (io_req_op_valid(req->opcode)) return 1; @@ -3442,7 +3545,7 @@ static int io_req_set_file(struct io_submit_state *state, struct io_kiocb *req, if (flags & IOSQE_IO_DRAIN) req->flags |= REQ_F_IO_DRAIN; - ret = io_req_needs_file(req); + ret = io_req_needs_file(req, fd); if (ret <= 0) return ret; diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index bdbe2b130179..02af580754ce 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -34,6 +34,7 @@ struct io_uring_sqe { __u32 timeout_flags; __u32 accept_flags; __u32 cancel_flags; + __u32 open_flags; }; __u64 user_data; /* data to be passed back at completion time */ union { @@ -77,6 +78,7 @@ enum { IORING_OP_LINK_TIMEOUT, IORING_OP_CONNECT, IORING_OP_FALLOCATE, + IORING_OP_OPENAT, /* this goes last, obviously */ IORING_OP_LAST, From patchwork Tue Jan 7 17:00:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Axboe X-Patchwork-Id: 11321457 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4B414921 for ; Tue, 7 Jan 2020 17:05:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2A7D5214D8 for ; Tue, 7 Jan 2020 17:05:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=kernel-dk.20150623.gappssmtp.com header.i=@kernel-dk.20150623.gappssmtp.com header.b="HgBxpyIq" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728430AbgAGRFy (ORCPT ); Tue, 7 Jan 2020 12:05:54 -0500 Received: from mail-il1-f194.google.com ([209.85.166.194]:44221 "EHLO mail-il1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728236AbgAGRFy (ORCPT ); Tue, 7 Jan 2020 12:05:54 -0500 Received: by mail-il1-f194.google.com with SMTP id z12so160012iln.11 for ; Tue, 07 Jan 2020 09:05:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel-dk.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=491locdRtuN4Y2mr+mNo2Sj9pBk1+R4oVqrtsXFQitc=; b=HgBxpyIq2SWFCPs9Qyz2F31KtDNhECCO524AsP+l8BIgjIB+shjmJz/GkPBh5z7E4I +8RWN+P8TTH9OmiFlXj/1V3XGZg4GGH1rfkPvFGXXYqZ8QYbK9gFVgoQdKbJl3E1nHDJ DQ+IjQ1Z4OoEVieiesBi72N734T3Gusxomp1SIF6rQ8SQT0LjyhSuuXXmTlPe+DYmrHS RBaliiNabS0yhYeML8RGHBFE8gKNMGCx1ywnkrC+TvcGPQzccGw90vmxm55/JuGMNInn hN3Fo4NQVSqJam7bsDONJ330bqFBJ3YTfT4j/Ftom+lrUXroNai2FMEdTiwOa3U+LwLi hgqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=491locdRtuN4Y2mr+mNo2Sj9pBk1+R4oVqrtsXFQitc=; b=XTbxlPdtiwxXmaAJZv2G1VPn6oJDbufvKQT3QwwOR7OApeO3mqHxWamuXclJgU6lNq aqS+EQIvRveN6bEAwdykg83Mf/Beu9MHLX2wS3EiXdpPREH5LMofrjOyjKy7rGw7Oh9d AWnuDVE5/Y4URNFwPI2D3wiMz/RX77jBJ4bwLiyro0sr83BEyCAVESYhNxlFHXPSt0sp 8cgN91pMtkCqL9gpiptyQmMmsFt58MeXJhl67MKemuUw+EqQE0ND4ejbPHXLPDRDhhXf LM89OnVQ6HhCb2VUwwN44BSckUj/l6hOe6LQ50rYuvmVpiVZhV61AfsmGM/sG6uey45N B1NA== X-Gm-Message-State: APjAAAXglCPimQKB1Tluo3YDBTbm8ZJsSlS40XT/+KVC9gYAFsTJqE6g zcfHn1aP5PJdduE8uojpH9ehlw== X-Google-Smtp-Source: APXvYqx43tluriyQkwFyVvEazUYhP0s2adPkJF1i25kaBmuCIdVHuKZIXhYTGO/K67MqxcNz7cH/4g== X-Received: by 2002:a92:2904:: with SMTP id l4mr51958ilg.166.1578416440079; Tue, 07 Jan 2020 09:00:40 -0800 (PST) Received: from x1.localdomain ([65.144.74.34]) by smtp.gmail.com with ESMTPSA id g4sm42547iln.81.2020.01.07.09.00.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Jan 2020 09:00:39 -0800 (PST) From: Jens Axboe To: io-uring@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, viro@zeniv.linux.org.uk, Jens Axboe Subject: [PATCH 4/6] fs: move filp_close() outside of __close_fd_get_file() Date: Tue, 7 Jan 2020 10:00:32 -0700 Message-Id: <20200107170034.16165-5-axboe@kernel.dk> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200107170034.16165-1-axboe@kernel.dk> References: <20200107170034.16165-1-axboe@kernel.dk> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Just one caller of this, and just use filp_close() there manually. This is important to allow async close/removal of the fd. Signed-off-by: Jens Axboe --- drivers/android/binder.c | 6 ++++-- fs/file.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index b2dad43dbf82..cf72ca250a08 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2249,10 +2249,12 @@ static void binder_deferred_fd_close(int fd) return; init_task_work(&twcb->twork, binder_do_fd_close); __close_fd_get_file(fd, &twcb->file); - if (twcb->file) + if (twcb->file) { + filp_close(twcb->file, current->files); task_work_add(current, &twcb->twork, true); - else + } else { kfree(twcb); + } } static void binder_transaction_buffer_release(struct binder_proc *proc, diff --git a/fs/file.c b/fs/file.c index 3da91a112bab..fb7081bfac2b 100644 --- a/fs/file.c +++ b/fs/file.c @@ -642,7 +642,9 @@ int __close_fd(struct files_struct *files, unsigned fd) EXPORT_SYMBOL(__close_fd); /* for ksys_close() */ /* - * variant of __close_fd that gets a ref on the file for later fput + * variant of __close_fd that gets a ref on the file for later fput. + * The caller must ensure that filp_close() called on the file, and then + * an fput(). */ int __close_fd_get_file(unsigned int fd, struct file **res) { @@ -662,7 +664,7 @@ int __close_fd_get_file(unsigned int fd, struct file **res) spin_unlock(&files->file_lock); get_file(file); *res = file; - return filp_close(file, files); + return 0; out_unlock: spin_unlock(&files->file_lock); From patchwork Tue Jan 7 17:00:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Axboe X-Patchwork-Id: 11321459 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 690F26C1 for ; Tue, 7 Jan 2020 17:06:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 46450214D8 for ; Tue, 7 Jan 2020 17:06:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=kernel-dk.20150623.gappssmtp.com header.i=@kernel-dk.20150623.gappssmtp.com header.b="q5C6VJ0U" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728307AbgAGRGH (ORCPT ); Tue, 7 Jan 2020 12:06:07 -0500 Received: from mail-io1-f66.google.com ([209.85.166.66]:38086 "EHLO mail-io1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728436AbgAGRGH (ORCPT ); Tue, 7 Jan 2020 12:06:07 -0500 Received: by mail-io1-f66.google.com with SMTP id v3so72141ioj.5 for ; Tue, 07 Jan 2020 09:06:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel-dk.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=e2VHGTRGbmT0TWCqccSNO5YDmbgFqBHce+/l36ATDhQ=; b=q5C6VJ0UUVYvINzJQUaoKposktE8cI5jaMr2FFoLsejPr/1muAnvyjLmdD5PNrYHY7 isLu9Ev3pvjG/5jLnw7RG7mQYIJYkinRt1ecHV2NWSInz82JLYoEQW4Oqb0rMRt8KLG/ ZgcVFo/oYRcArUu80xD+AYw4ka9sgs/2nFHsey/A12cEBQk9ZJFO6WwgK80Wwb6Jo2sS I+RTplXRgbFVM9HMm7oiCbYXgUPxERa0LrVSs7d0Zt3HxdKHk7ANVmIDvU+jn9iMrHoh qMJSealaz27Tk048X5pzjsNUTLHvyNJ6sRxySSiLvavEs4jfADwsY0fp9TZm66BDUgN8 csFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=e2VHGTRGbmT0TWCqccSNO5YDmbgFqBHce+/l36ATDhQ=; b=a3hzxsrWkaGrMq9yHhfJoEZhd9924IqegyQ8DkOuRAxdgtjmfC5VGBKro3aAc4pQ/t 6PaFmfdOdbUJDaFbyVBr1U3S0anGL3jkdWlYqEGgvBhS2tcVJo89O76gopCUBQgwBKLI Z9N1NSLImoXVpVHU3ja+kOctwiufa5Na+XXOBCu82R9RRhgVxU5y0s11gxsfZU6IUJLG GE/PPVH4/5yivXuLXT4UNTn4mNGrc8m+5eSwbpwXh89IAQ9ze4uh6jd+BDwS5Yq8bALn laTFOyQ7sd/QY5Ei8gDLTUFq3Loy91OPk7O311U7UVSMd3Z64uPfyghOv/KZHNzkZ9fO 7Azw== X-Gm-Message-State: APjAAAXc8G3KpGpxI14pmWIatmBBV11H6fJBMX/dsyJ8cu6DTrbq2KXE IvXZys3VNbdptHOVXD19qOEQ3nPhNDI= X-Google-Smtp-Source: APXvYqwvejYKHFGGfnbzjK5C2OFjxIavk/sSD4Kj/XXLGpUvMTIDiA95R1oMqudCNzB0lpiPf5XVpQ== X-Received: by 2002:a6b:f214:: with SMTP id q20mr37477624ioh.137.1578416440746; Tue, 07 Jan 2020 09:00:40 -0800 (PST) Received: from x1.localdomain ([65.144.74.34]) by smtp.gmail.com with ESMTPSA id g4sm42547iln.81.2020.01.07.09.00.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Jan 2020 09:00:40 -0800 (PST) From: Jens Axboe To: io-uring@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, viro@zeniv.linux.org.uk, Jens Axboe Subject: [PATCH 5/6] io-wq: add support for uncancellable work Date: Tue, 7 Jan 2020 10:00:33 -0700 Message-Id: <20200107170034.16165-6-axboe@kernel.dk> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200107170034.16165-1-axboe@kernel.dk> References: <20200107170034.16165-1-axboe@kernel.dk> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Not all work can be cancelled, some of it we may need to guarantee that it runs to completion. Allow the caller to set IO_WQ_WORK_NO_CANCEL on work that must not be cancelled. Note that the caller work function must also check for IO_WQ_WORK_NO_CANCEL on work that is marked IO_WQ_WORK_CANCEL. Signed-off-by: Jens Axboe --- fs/io-wq.c | 8 +++++++- fs/io-wq.h | 1 + fs/io_uring.c | 5 ++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/io-wq.c b/fs/io-wq.c index 541c8a3e0bbb..2f94170eeb89 100644 --- a/fs/io-wq.c +++ b/fs/io-wq.c @@ -452,6 +452,10 @@ static void io_worker_handle_work(struct io_worker *worker) } if (!worker->creds) worker->creds = override_creds(wq->creds); + /* + * OK to set IO_WQ_WORK_CANCEL even for uncancellable work, + * the worker function will do the right thing. + */ if (test_bit(IO_WQ_BIT_CANCEL, &wq->state)) work->flags |= IO_WQ_WORK_CANCEL; if (worker->mm) @@ -824,6 +828,7 @@ static bool io_work_cancel(struct io_worker *worker, void *cancel_data) */ spin_lock_irqsave(&worker->lock, flags); if (worker->cur_work && + !(worker->cur_work->flags & IO_WQ_WORK_NO_CANCEL) && data->cancel(worker->cur_work, data->caller_data)) { send_sig(SIGINT, worker->task, 1); ret = true; @@ -898,7 +903,8 @@ static bool io_wq_worker_cancel(struct io_worker *worker, void *data) return false; spin_lock_irqsave(&worker->lock, flags); - if (worker->cur_work == work) { + if (worker->cur_work == work && + !(worker->cur_work->flags & IO_WQ_WORK_NO_CANCEL)) { send_sig(SIGINT, worker->task, 1); ret = true; } diff --git a/fs/io-wq.h b/fs/io-wq.h index 3f5e356de980..04d60ad38dfc 100644 --- a/fs/io-wq.h +++ b/fs/io-wq.h @@ -12,6 +12,7 @@ enum { IO_WQ_WORK_UNBOUND = 32, IO_WQ_WORK_INTERNAL = 64, IO_WQ_WORK_CB = 128, + IO_WQ_WORK_NO_CANCEL = 256, IO_WQ_HASH_SHIFT = 24, /* upper 8 bits are used for hash key */ }; diff --git a/fs/io_uring.c b/fs/io_uring.c index 53ff67ab5c4b..e12b1545468d 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -3457,8 +3457,11 @@ static void io_wq_submit_work(struct io_wq_work **workptr) struct io_kiocb *nxt = NULL; int ret = 0; - if (work->flags & IO_WQ_WORK_CANCEL) + /* if NO_CANCEL is set, we must still run the work */ + if ((work->flags & (IO_WQ_WORK_CANCEL|IO_WQ_WORK_NO_CANCEL)) == + IO_WQ_WORK_CANCEL) { ret = -ECANCELED; + } if (!ret) { req->has_user = (work->flags & IO_WQ_WORK_HAS_MM) != 0; From patchwork Tue Jan 7 17:00:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Axboe X-Patchwork-Id: 11321455 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 48462921 for ; Tue, 7 Jan 2020 17:05:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1C8E3214D8 for ; Tue, 7 Jan 2020 17:05:44 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=kernel-dk.20150623.gappssmtp.com header.i=@kernel-dk.20150623.gappssmtp.com header.b="w4OBuTNp" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728389AbgAGRFn (ORCPT ); Tue, 7 Jan 2020 12:05:43 -0500 Received: from mail-il1-f195.google.com ([209.85.166.195]:37192 "EHLO mail-il1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728236AbgAGRFn (ORCPT ); Tue, 7 Jan 2020 12:05:43 -0500 Received: by mail-il1-f195.google.com with SMTP id t8so201622iln.4 for ; Tue, 07 Jan 2020 09:05:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel-dk.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ePeYHHCrlTvEcFwyclV0yiNhluauNmITK5H/gPcNCZs=; b=w4OBuTNpFkZ4P/FmzBu8dU6b7fw2GPLYj8pleo8iRtZJO3i1KMgKjdE+uc6QlqLF9V 3ndAKwCK+v1K4RYNyrbhwtNaCjkMji+vG0ljRk1JHvn5eVD/OWGPCyDl+MDhh9+xoHin n2Z2zbTUOeKqOB0mi5JFeHcvJ4Rpmys+9bBFSTMSNyWgkdFql9T2uJ8MUMC/Th2Md56D UIc9SFPW3c6zCgwqjjDbPQ8urpXjtzqIfLcvEnb7BbroDc/VA9Hm+lDoCOcSTIltQm+4 7UsgGiQ7y0cNNfYm4j5xejwBme95wzyz3cw7sLMmzwLpPUEndQBkpoXKIaSMnRQCCX0M c6/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ePeYHHCrlTvEcFwyclV0yiNhluauNmITK5H/gPcNCZs=; b=XBX4sOo/Hs4kwxAvK4H9OEMAqQyuilN8LcU0eJ7v2ZUSeepZjzONqjm5PejM9e3r0U WNIFvivBg9494ngBsRW/9lsxYzuzRGXoHHye2I+4jU6Q7aCrBknVEu15gb4hsWK+YVFw uZnZX+Nxl1Ac+Qcos/+QWaBP5L2fe5DO15il1ThJ63VGgV3ErvaCGBMTvNugRh9YSFaq beIksLM9ubgr2Kwo0ak0n0EEt8QCU3GTHI9wY9LS1DPDomH2U7nQzpDnIevnzwLxB2Ra rR83qBg3KFn0H9B0ryGN5OBdiJR1sZ11+Y3LwIuMWItX1wD6C0Wx07xwtWjGIHBUGfyz AyaQ== X-Gm-Message-State: APjAAAX/adBitrKvOPZB1dC2Tz002HV4JKTvGADithNI5P2wq4Dy4vrG qwyKc04+flps9l5Ib/Yz7Q+e/g== X-Google-Smtp-Source: APXvYqyVhoR2MHFjRJJVk9dUkuTnVEahiu9aLULC9GiNl3LJdTYQk5LIkVBuQsAQYQCHSn4ZKU4Z6w== X-Received: by 2002:a92:9cc6:: with SMTP id x67mr30621ill.31.1578416441495; Tue, 07 Jan 2020 09:00:41 -0800 (PST) Received: from x1.localdomain ([65.144.74.34]) by smtp.gmail.com with ESMTPSA id g4sm42547iln.81.2020.01.07.09.00.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Jan 2020 09:00:41 -0800 (PST) From: Jens Axboe To: io-uring@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, viro@zeniv.linux.org.uk, Jens Axboe Subject: [PATCH 6/6] io_uring: add support for IORING_OP_CLOSE Date: Tue, 7 Jan 2020 10:00:34 -0700 Message-Id: <20200107170034.16165-7-axboe@kernel.dk> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200107170034.16165-1-axboe@kernel.dk> References: <20200107170034.16165-1-axboe@kernel.dk> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org This works just like close(2), unsurprisingly. We remove the file descriptor and post the completion inline, then offload the actual (potential) last file put to async context. Mark the async part of this work as uncancellable, as we really must guarantee that the latter part of the close is run. Signed-off-by: Jens Axboe --- fs/io_uring.c | 109 ++++++++++++++++++++++++++++++++++ include/uapi/linux/io_uring.h | 1 + 2 files changed, 110 insertions(+) diff --git a/fs/io_uring.c b/fs/io_uring.c index e12b1545468d..39abe20220d0 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -301,6 +301,12 @@ struct io_poll_iocb { struct wait_queue_entry wait; }; +struct io_close { + struct file *file; + struct file *put_file; + int fd; +}; + struct io_timeout_data { struct io_kiocb *req; struct hrtimer timer; @@ -414,6 +420,7 @@ struct io_kiocb { struct io_connect connect; struct io_sr_msg sr_msg; struct io_open open; + struct io_close close; }; struct io_async_ctx *io; @@ -2225,6 +2232,94 @@ static int io_openat(struct io_kiocb *req, struct io_kiocb **nxt, return 0; } +static int io_close_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) +{ + /* + * If we queue this for async, it must not be cancellable. That would + * leave the 'file' in an undeterminate state. + */ + req->work.flags |= IO_WQ_WORK_NO_CANCEL; + + if (sqe->ioprio || sqe->off || sqe->addr || sqe->len || + sqe->rw_flags || sqe->buf_index) + return -EINVAL; + if (sqe->flags & IOSQE_FIXED_FILE) + return -EINVAL; + + req->close.fd = READ_ONCE(sqe->fd); + if (req->file->f_op == &io_uring_fops || + req->close.fd == req->ring_fd) + return -EBADF; + + return 0; +} + +static void io_close_finish(struct io_wq_work **workptr) +{ + struct io_kiocb *req = container_of(*workptr, struct io_kiocb, work); + struct io_kiocb *nxt = NULL; + + /* Invoked with files, we need to do the close */ + if (req->work.files) { + int ret; + + ret = filp_close(req->close.put_file, req->work.files); + if (ret < 0) { + req_set_fail_links(req); + } + io_cqring_add_event(req, ret); + } + + fput(req->close.put_file); + + /* we bypassed the re-issue, drop the submission reference */ + io_put_req(req); + io_put_req_find_next(req, &nxt); + if (nxt) + *workptr = &nxt->work; +} + +static int io_close(struct io_kiocb *req, struct io_kiocb **nxt, + bool force_nonblock) +{ + int ret; + + req->close.put_file = NULL; + ret = __close_fd_get_file(req->close.fd, &req->close.put_file); + if (ret < 0) + return ret; + + /* if the file has a flush method, be safe and punt to async */ + if (req->close.put_file->f_op->flush && !io_wq_current_is_worker()) { + req->work.flags |= IO_WQ_WORK_NEEDS_FILES; + goto eagain; + } + + /* + * No ->flush(), safely close from here and just punt the + * fput() to async context. + */ + ret = filp_close(req->close.put_file, current->files); + + if (ret < 0) + req_set_fail_links(req); + io_cqring_add_event(req, ret); + + if (io_wq_current_is_worker()) { + struct io_wq_work *old_work, *work; + + old_work = work = &req->work; + io_close_finish(&work); + if (work && work != old_work) + *nxt = container_of(work, struct io_kiocb, work); + return 0; + } + +eagain: + req->work.func = io_close_finish; + return -EAGAIN; +} + static int io_prep_sfr(struct io_kiocb *req, const struct io_uring_sqe *sqe) { struct io_ring_ctx *ctx = req->ctx; @@ -3253,6 +3348,9 @@ static int io_req_defer_prep(struct io_kiocb *req, case IORING_OP_OPENAT: ret = io_openat_prep(req, sqe); break; + case IORING_OP_CLOSE: + ret = io_close_prep(req, sqe); + break; default: printk_once(KERN_WARNING "io_uring: unhandled opcode %d\n", req->opcode); @@ -3423,6 +3521,14 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, } ret = io_openat(req, nxt, force_nonblock); break; + case IORING_OP_CLOSE: + if (sqe) { + ret = io_close_prep(req, sqe); + if (ret) + break; + } + ret = io_close(req, nxt, force_nonblock); + break; default: ret = -EINVAL; break; @@ -3578,6 +3684,9 @@ static int io_grab_files(struct io_kiocb *req) int ret = -EBADF; struct io_ring_ctx *ctx = req->ctx; + if (!req->ring_file) + return -EBADF; + rcu_read_lock(); spin_lock_irq(&ctx->inflight_lock); /* diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index 02af580754ce..42a7f0e8dee3 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -79,6 +79,7 @@ enum { IORING_OP_CONNECT, IORING_OP_FALLOCATE, IORING_OP_OPENAT, + IORING_OP_CLOSE, /* this goes last, obviously */ IORING_OP_LAST,