From patchwork Mon Jan 25 04:44:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Axboe X-Patchwork-Id: 12042907 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.2 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 34A53C4332B for ; Mon, 25 Jan 2021 04:45:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F24DE22CA2 for ; Mon, 25 Jan 2021 04:45:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727176AbhAYEo7 (ORCPT ); Sun, 24 Jan 2021 23:44:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60322 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727167AbhAYEo4 (ORCPT ); Sun, 24 Jan 2021 23:44:56 -0500 Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C179CC0613D6 for ; Sun, 24 Jan 2021 20:44:15 -0800 (PST) Received: by mail-pl1-x633.google.com with SMTP id u11so6807616plg.13 for ; Sun, 24 Jan 2021 20:44:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel-dk.20150623.gappssmtp.com; s=20150623; h=to:cc:from:subject:message-id:date:user-agent:mime-version :content-language:content-transfer-encoding; bh=Cs4J9GskE01nDEYOQ3KQaCkKWwKmXBxrzRzzc8/wsJI=; b=vKDGB28J3loZxpQQsNi0tNE+SmHzbz+XjsHet5K38mYCsN/wRrMJ3w6ilbulurzxlr zk8AlS2RjecXSxSJgrDrDWWoEiQBDcNS0I+9/ko/vKi0Uo+911tqx3a7b+YwIotsAxhm Q/+L0YI5UyS77khX4HdMn5b9itjjqzBZ09yTMGPzA4XfTSeVBJO01nEmFSxUi/KPcfvu s+4g6M9sGLonmuMuaB9Rv5LDbbkDciPtgOO3QaQJoV2LHnK46WR+7Fd+RoYG5plOsc5h JYuslMfgZmChOKNZRvuKjV+8pi0kauS7MxwDIX4M/olD3LiysBq8BnLey0ViiOFPATEG fWtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:cc:from:subject:message-id:date:user-agent :mime-version:content-language:content-transfer-encoding; bh=Cs4J9GskE01nDEYOQ3KQaCkKWwKmXBxrzRzzc8/wsJI=; b=EAqZdx2mSHS1ohNea59W/LoOfwwUq+ayShr0ogXMPJ/T7kp8VaR2yE/L8HaaoTbfDh VqXRbeCaLF25iC1UwaDPRMIqP8rwvIrPn9sevVlN+Ry10CvrGnVnfIzwxSwgYtOw6hZs kFcQn0XhF13YBmv3K0qjMsZFQ3tCiQMCtTGwkdd7tAe4q3oLAmAUfylfe69D8rsFefRT x4MrqFHm2bOmV2UqBXa5S1tTW5T0oXRTFaEI/6VWzuQN+ob8KkJjJyQbg33+GmAiHd5J Jl2WpQLO9aHf5bMwnho9kFZ846mCVwtnWPfFOIR8Xjl/3JqLW7h3u7SveR3ENlrs6H4t RhEg== X-Gm-Message-State: AOAM532roTsJ47RUBFTL4dUEM7KQ9sHhzqvtlK2veEdhcZsn27/+efI4 1IavjdQu+XjGS9zUUZPVn34TlSRWo3vnWA== X-Google-Smtp-Source: ABdhPJzdALFDfkb7y4OVT7WVh3vG/AkOBJGgvUGXL6FDtcp2jkAl9T/cDXJUkTTlcwuAX76Tuy4Tmw== X-Received: by 2002:a17:902:d64d:b029:de:8aaa:d6ba with SMTP id y13-20020a170902d64db02900de8aaad6bamr18034012plh.0.1611549855312; Sun, 24 Jan 2021 20:44:15 -0800 (PST) Received: from [192.168.4.41] (cpe-72-132-29-68.dc.res.rr.com. [72.132.29.68]) by smtp.gmail.com with ESMTPSA id md7sm16622324pjb.52.2021.01.24.20.44.14 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 24 Jan 2021 20:44:14 -0800 (PST) To: Alexander Viro Cc: linux-fsdevel , io-uring From: Jens Axboe Subject: [PATCH] fs: provide locked helper variant of close_fd_get_file() Message-ID: <61657916-6513-1a80-1434-d689ebb18709@kernel.dk> Date: Sun, 24 Jan 2021 21:44:13 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 Content-Language: en-US Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Assumes current->files->file_lock is already held on invocation. Helps the caller check the file before removing the fd, if it needs to. Signed-off-by: Jens Axboe --- Al, I need this to get rid of the two-stage operation that io_uring currently does for close operations. It's proving to be quite a headache in terms of cancelation, since we must complete part 2 if we did part 1. If we provide this locked variant helper, then we can ensure that we the close as one operation, nicely fixing that problem instead of needing to hack around it. fs/file.c | 36 +++++++++++++++++++++++++----------- fs/internal.h | 1 + 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/fs/file.c b/fs/file.c index dab120b71e44..f3a4bac2cbe9 100644 --- a/fs/file.c +++ b/fs/file.c @@ -22,6 +22,8 @@ #include #include +#include "internal.h" + unsigned int sysctl_nr_open __read_mostly = 1024*1024; unsigned int sysctl_nr_open_min = BITS_PER_LONG; /* our min() is unusable in constant expressions ;-/ */ @@ -732,36 +734,48 @@ int __close_range(unsigned fd, unsigned max_fd, unsigned int flags) } /* - * 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(). + * See close_fd_get_file() below, this variant assumes current->files->file_lock + * is held. */ -int close_fd_get_file(unsigned int fd, struct file **res) +int __close_fd_get_file(unsigned int fd, struct file **res) { struct files_struct *files = current->files; struct file *file; struct fdtable *fdt; - spin_lock(&files->file_lock); fdt = files_fdtable(files); if (fd >= fdt->max_fds) - goto out_unlock; + goto out_err; file = fdt->fd[fd]; if (!file) - goto out_unlock; + goto out_err; rcu_assign_pointer(fdt->fd[fd], NULL); __put_unused_fd(files, fd); - spin_unlock(&files->file_lock); get_file(file); *res = file; return 0; - -out_unlock: - spin_unlock(&files->file_lock); +out_err: *res = NULL; return -ENOENT; } +/* + * 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) +{ + struct files_struct *files = current->files; + int ret; + + spin_lock(&files->file_lock); + ret = __close_fd_get_file(fd, res); + spin_unlock(&files->file_lock); + + return ret; +} + void do_close_on_exec(struct files_struct *files) { unsigned i; diff --git a/fs/internal.h b/fs/internal.h index 77c50befbfbe..c6c85f6ad598 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -132,6 +132,7 @@ 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); +extern int __close_fd_get_file(unsigned int fd, struct file **res); long do_sys_ftruncate(unsigned int fd, loff_t length, int small); int chmod_common(const struct path *path, umode_t mode);