From patchwork Fri Apr 2 12:35:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 12180829 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=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham 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 332B5C43460 for ; Fri, 2 Apr 2021 12:37:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0F1CA61159 for ; Fri, 2 Apr 2021 12:37:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235441AbhDBMhY (ORCPT ); Fri, 2 Apr 2021 08:37:24 -0400 Received: from mail.kernel.org ([198.145.29.99]:53622 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235444AbhDBMhW (ORCPT ); Fri, 2 Apr 2021 08:37:22 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id DBDB561158; Fri, 2 Apr 2021 12:37:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1617367041; bh=H6rhK7YrJlG/TnSxkRrxaV6rrHER++o1pLWVgVT/hFM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mwQQARNS0037UZK89bxhtfJS0qxf3bmbfYK+TSZ2aszVj1R0CFT5JWFSJa+408xbU LduHUJs3023xhEbFZhCn9rWliymuJQihvvlT/k4PyYw/dVN7so8BbUicQxSYGHqjpJ yxPiGwKCz0d0/Eu7M3+QqU+oAwyvEDgvnc/XhMgLJ1uxl69N1AKaXGL40+mNnPjcwQ LFpJJ+nr4QGnfFXH6RhXc0kaeXLdo5IXiKKUNnfRLYZJPmjLDnQe+p7vAdgblMxPj7 TAa8toiH/NVpeHJnh//typ7l7XiZAYoQU6/FgIBSJxxofEGYeleXfhb+bY1MkoiQwA k3MHO07+sRL/w== From: Christian Brauner To: linux-fsdevel@vger.kernel.org Cc: Al Viro , Linus Torvalds , Dmitry Vyukov , Christian Brauner , Christoph Hellwig , Giuseppe Scrivano Subject: [PATCH 2/3] file: let pick_file() tell caller it's done Date: Fri, 2 Apr 2021 14:35:47 +0200 Message-Id: <20210402123548.108372-3-brauner@kernel.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <00000000000069c40405be6bdad4@google.com> References: <00000000000069c40405be6bdad4@google.com> MIME-Version: 1.0 X-Patch-Hashes: v=1; h=sha256; i=u3FypIfYYEuouoQtFnkkSF1BaueP8r/+poOiz25rjy0=; m=XxDs1iQXFGporBJagccdLRPprhMJ0YTgd0CCqHCv/W0=; p=1aFtf2Ns3INd5B6Bg/dGOcnyrKqqA2iROlkVMFoo6vQ=; g=08c35118ac0e088c52bdd2f77bea1f7f51a1a5e2 X-Patch-Sig: m=pgp; i=christian.brauner@ubuntu.com; s=0x0x91C61BC06578DCA2; b=iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCYGcPkgAKCRCRxhvAZXjcojxNAPsGKlX WDUEjrlXQwYn36lKSceQnpjvrryk0HoPfwLIR8AD+JW8wb+JEIELp2e+5u4hkMuWqLAgTWIgHDw4/ akXT3wE= Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org From: Christian Brauner Let pick_file() report back that the fd it was passed exceeded the maximum fd in that fdtable. This allows us to simplify the caller of this helper because it doesn't need to care anymore whether the passed in max_fd is excessive. It can rely on pick_file() telling it that it's past the last valid fd. Cc: Christoph Hellwig Cc: Giuseppe Scrivano Cc: Al Viro Cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner --- fs/file.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/fs/file.c b/fs/file.c index f633348029a5..740040346a98 100644 --- a/fs/file.c +++ b/fs/file.c @@ -596,18 +596,32 @@ void fd_install(unsigned int fd, struct file *file) EXPORT_SYMBOL(fd_install); +/** + * pick_file - return file associatd with fd + * @files: file struct to retrieve file from + * @fd: file descriptor to retrieve file for + * + * If this functions returns an EINVAL error pointer the fd was beyond the + * current maximum number of file descriptors for that fdtable. + * + * Returns: The file associated with @fd, on error returns an error pointer. + */ static struct file *pick_file(struct files_struct *files, unsigned fd) { - struct file *file = NULL; + struct file *file; struct fdtable *fdt; spin_lock(&files->file_lock); fdt = files_fdtable(files); - if (fd >= fdt->max_fds) + if (fd >= fdt->max_fds) { + file = ERR_PTR(-EINVAL); goto out_unlock; + } file = fdt->fd[fd]; - if (!file) + if (!file) { + file = ERR_PTR(-EBADF); goto out_unlock; + } rcu_assign_pointer(fdt->fd[fd], NULL); __put_unused_fd(files, fd); @@ -622,7 +636,7 @@ int close_fd(unsigned fd) struct file *file; file = pick_file(files, fd); - if (!file) + if (IS_ERR(file)) return -EBADF; return filp_close(file, files); @@ -663,11 +677,16 @@ static inline void __range_close(struct files_struct *cur_fds, unsigned int fd, struct file *file; file = pick_file(cur_fds, fd++); - if (!file) + if (!IS_ERR(file)) { + /* found a valid file to close */ + filp_close(file, cur_fds); + cond_resched(); continue; + } - filp_close(file, cur_fds); - cond_resched(); + /* beyond the last fd in that table */ + if (PTR_ERR(file) == -EINVAL) + return; } }