From patchwork Mon Apr 3 14:45:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Aleksandr Mikhalitsyn X-Patchwork-Id: 13198272 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 033ECC76188 for ; Mon, 3 Apr 2023 14:46:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234082AbjDCOqv (ORCPT ); Mon, 3 Apr 2023 10:46:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36718 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233996AbjDCOqg (ORCPT ); Mon, 3 Apr 2023 10:46:36 -0400 Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 07134D4F85 for ; Mon, 3 Apr 2023 07:46:18 -0700 (PDT) Received: from mail-ed1-f70.google.com (mail-ed1-f70.google.com [209.85.208.70]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 7127B3F241 for ; Mon, 3 Apr 2023 14:45:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1680533138; bh=jf893Mr1zYfCNeUs9dWOENLdN29rryafRcjFVjzmYec=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=eCq3NwXmcQ+rj3YxAF9NeovFVyRLHMHqpEwk36O58poscmOSDnBbURKIf+96sPeff kDuOo7eUWZdyXlTjvHSo6J4wY1rwo7mcQSSagaLGorLHPve2WnS5CPgjbXVaAVjce5 xpf/jqDrU9hWtZ3gGQhrYH/83Upx69ppL08wI4h0MMcTiPWNKNWafKfMh2CLiTc9ft hqDJKUdUxqG+Id6EZxJVUiKEWFgID+Yg3LazRmuhDXykI2NfVnPktuUTGae4X0ZCC7 ne8Cnxh/adgZqP/bxcEtHxvDmxTuCfs6qmpXfQZrhFcqxLm+BMYsh213/pyjQGtYJK 9yXDVahlDta7g== Received: by mail-ed1-f70.google.com with SMTP id c11-20020a509f8b000000b00501e2facf47so41750537edf.16 for ; Mon, 03 Apr 2023 07:45:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680533137; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jf893Mr1zYfCNeUs9dWOENLdN29rryafRcjFVjzmYec=; b=5IcF7l68AtYtUJHajVJgsGdidbP13EN+7rsDaj+05hXnc7uY0qma2Vqd0I+D1LpmXf WMi0Ou4mgmc9t27Dw/M7pis4fQCmQj2+a8zXYPuBLlBs6FdlLPoYHCbUE+r5uwxIE1BR qGCmNgIUitimCASniHQplMP4PTQs7vTowCrOosmp+j0AbLprCne7qWUQlbl14HJTHeYM fFs6YCrqV8jhpMZqXVJalwxMARabIrbPfNWn9ojGO3TEmHIgOCmfc1XOlioCY010qhZI iZuAFfFUs0CYjViTa5ntjk6Q8oYfcypjMlHmYqnodXpY2o18hUo7pxipwmB4LHKbuz9V guww== X-Gm-Message-State: AAQBX9dZ/wRwCduTtOR5OFnXZdS3KXm2w7tV7pEqRFf/kv8tKHT7Qoea pKZ1gFzSqMCm1aNVeSCpGjZJC2ncdtrWZ/6O67jJeGICH4+qkwW5W6azHF9nu4E8NMKsqB+PNr8 Kvrzv1ZEDw1BMNVP9+nl0DpJr7zaKnPzwz2Lh7ToTJSY= X-Received: by 2002:a05:6402:411:b0:502:251b:3a4c with SMTP id q17-20020a056402041100b00502251b3a4cmr30174836edv.20.1680533137391; Mon, 03 Apr 2023 07:45:37 -0700 (PDT) X-Google-Smtp-Source: AKy350Y2rjRNMEkLgRsNMhCzFqQP4n3HXkdsPLW/Km+pP6VRt/Ch2WbGOlygJD5M5eF9DG+YVUx8kw== X-Received: by 2002:a05:6402:411:b0:502:251b:3a4c with SMTP id q17-20020a056402041100b00502251b3a4cmr30174814edv.20.1680533137108; Mon, 03 Apr 2023 07:45:37 -0700 (PDT) Received: from amikhalitsyn.. (ip5f5bd076.dynamic.kabel-deutschland.de. [95.91.208.118]) by smtp.gmail.com with ESMTPSA id i5-20020a50d745000000b004fa19f5ba99sm4735804edj.79.2023.04.03.07.45.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Apr 2023 07:45:36 -0700 (PDT) From: Alexander Mikhalitsyn To: mszeredi@redhat.com Cc: flyingpeng@tencent.com, Alexander Mikhalitsyn , Al Viro , Amir Goldstein , =?utf-8?q?St=C3=A9phane_Graber?= , Seth Forshee , Christian Brauner , Andrei Vagin , Pavel Tikhomirov , Bernd Schubert , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, criu@openvz.org Subject: [RFC PATCH v2 1/9] fuse: move FUSE_DEFAULT_* defines to fuse common header Date: Mon, 3 Apr 2023 16:45:09 +0200 Message-Id: <20230403144517.347517-2-aleksandr.mikhalitsyn@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> References: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Cc: Miklos Szeredi Cc: Al Viro Cc: Amir Goldstein Cc: Stéphane Graber Cc: Seth Forshee Cc: Christian Brauner Cc: Andrei Vagin Cc: Pavel Tikhomirov Cc: Bernd Schubert Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: criu@openvz.org Signed-off-by: Alexander Mikhalitsyn --- fs/fuse/fuse_i.h | 6 ++++++ fs/fuse/inode.c | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 9b7fc7d3c7f1..69af0acecb69 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -47,6 +47,12 @@ /** Number of dentries for each connection in the control filesystem */ #define FUSE_CTL_NUM_DENTRIES 5 +/** Maximum number of outstanding background requests */ +#define FUSE_DEFAULT_MAX_BACKGROUND 12 + +/** Congestion starts at 75% of maximum */ +#define FUSE_DEFAULT_CONGESTION_THRESHOLD (FUSE_DEFAULT_MAX_BACKGROUND * 3 / 4) + /** List of active connections */ extern struct list_head fuse_conn_list; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 660be31aaabc..3de950104f15 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -53,12 +53,6 @@ MODULE_PARM_DESC(max_user_congthresh, #define FUSE_DEFAULT_BLKSIZE 512 -/** Maximum number of outstanding background requests */ -#define FUSE_DEFAULT_MAX_BACKGROUND 12 - -/** Congestion starts at 75% of maximum */ -#define FUSE_DEFAULT_CONGESTION_THRESHOLD (FUSE_DEFAULT_MAX_BACKGROUND * 3 / 4) - #ifdef CONFIG_BLOCK static struct file_system_type fuseblk_fs_type; #endif From patchwork Mon Apr 3 14:45:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Aleksandr Mikhalitsyn X-Patchwork-Id: 13198268 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DC424C761AF for ; Mon, 3 Apr 2023 14:46:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233979AbjDCOqc (ORCPT ); Mon, 3 Apr 2023 10:46:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36742 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233981AbjDCOq1 (ORCPT ); Mon, 3 Apr 2023 10:46:27 -0400 Received: from smtp-relay-internal-0.canonical.com (smtp-relay-internal-0.canonical.com [185.125.188.122]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BE16016967 for ; Mon, 3 Apr 2023 07:46:05 -0700 (PDT) Received: from mail-ed1-f69.google.com (mail-ed1-f69.google.com [209.85.208.69]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 2DE0C3F23C for ; Mon, 3 Apr 2023 14:45:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1680533139; bh=bVeWuEcFFA9BOaey9u9VyyM5TuRxdAhm6TBxfMNpyiQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=ShYw+yvJL3g/L8PFFXuhOLMPSmHDcwKtiig9o+g++ghQw5cyNK5YLs1v/t0eeO+5M pVi+aMy3pt6lzrIFAnqeA9YKnyiXRRjjfmeHJc2+hqUc2mrSKz5AlO/HMyWmuvzWYe kEWpW4V9lU1nJuTfbaGCyBvv5guwZ3xPpCLSAhQ0bepQEysnDWYE+bIJ9mxuEVgXAV VAVDj70o5s5AtOk22X04GNoQGCjSzqmCOq6W//FZV9XzeYFGvGnsM0pUMwGkCRQuwk fMfbtHQq3yC2JwgP/g0fBi+VknXyPgkGB3xJeGDjYwTZOS0gOg7Sr0gYNZn28wJ/EE pIlrdoSwLaAUA== Received: by mail-ed1-f69.google.com with SMTP id u30-20020a50c05e000000b0050299de3f82so5792556edd.10 for ; Mon, 03 Apr 2023 07:45:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680533139; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=bVeWuEcFFA9BOaey9u9VyyM5TuRxdAhm6TBxfMNpyiQ=; b=O8tZ2L5udIPLSL4zgNgHDJYoGYjLS1PSqWp3BuCU5Si+iAWoBvZjq4mLJHRp/a4W+u xHlP/vcLc+axFu2Yo+X0afta8FvIrt52WIPRZNk5umyVijnTIDu/bCD6nJ5XLqeQmDkA tOJxs5z3+2Tjly/Xt0rfpanb5JtxoDx5IFNZY2tqbzxF3zOIvOOqjRx7ntk4fsNE4L4s pHw+3MDZCxkFOfhwBnhe3JqLHve/ehlXmt+qUh/HRppfc9fkmZR+3Q1mHbWV5nA4OcIV 2M9IM/6ImlhY0TWRiK6UTa9u+/wzsVqhCN626zbaR+ueC/CXhQsUNSVn1pdzA9pGYT66 paLw== X-Gm-Message-State: AAQBX9eVfYU6RIcFa6vKj4dc5YtaTJwyDJ3KVVl+frUg/ROPgnk443vq HRlUeBlIxh6PvtZaGvzz7LUpktoLZnsyIr83GG6mbuaQGdlRirdpyI0oKyw9qERFOUW0QSkfIGa 0rhufpG4PF/ItjYOuoJswNQwTduJVE+Sx8zKIJ58ALCI= X-Received: by 2002:a05:6402:8d9:b0:4fe:19cb:4788 with SMTP id d25-20020a05640208d900b004fe19cb4788mr32810321edz.42.1680533138915; Mon, 03 Apr 2023 07:45:38 -0700 (PDT) X-Google-Smtp-Source: AKy350bS7ivnPsfOURPfqkG6FOqAtwZfDP530jIkSKpQXVUZ0EH3RYfr+0dokF69qX0VO76OHuKjPA== X-Received: by 2002:a05:6402:8d9:b0:4fe:19cb:4788 with SMTP id d25-20020a05640208d900b004fe19cb4788mr32810305edz.42.1680533138636; Mon, 03 Apr 2023 07:45:38 -0700 (PDT) Received: from amikhalitsyn.. (ip5f5bd076.dynamic.kabel-deutschland.de. [95.91.208.118]) by smtp.gmail.com with ESMTPSA id i5-20020a50d745000000b004fa19f5ba99sm4735804edj.79.2023.04.03.07.45.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Apr 2023 07:45:38 -0700 (PDT) From: Alexander Mikhalitsyn To: mszeredi@redhat.com Cc: flyingpeng@tencent.com, Alexander Mikhalitsyn , Al Viro , Amir Goldstein , =?utf-8?q?St=C3=A9phane_Graber?= , Seth Forshee , Christian Brauner , Andrei Vagin , Pavel Tikhomirov , Bernd Schubert , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, criu@openvz.org Subject: [RFC PATCH v2 2/9] fuse: add const qualifiers to common fuse helpers Date: Mon, 3 Apr 2023 16:45:10 +0200 Message-Id: <20230403144517.347517-3-aleksandr.mikhalitsyn@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> References: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Cc: Miklos Szeredi Cc: Al Viro Cc: Amir Goldstein Cc: Stéphane Graber Cc: Seth Forshee Cc: Christian Brauner Cc: Andrei Vagin Cc: Pavel Tikhomirov Cc: Bernd Schubert Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: criu@openvz.org Signed-off-by: Alexander Mikhalitsyn --- fs/fuse/fuse_i.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 69af0acecb69..6d3d3ca4f136 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -870,32 +870,32 @@ struct fuse_mount { struct list_head fc_entry; }; -static inline struct fuse_mount *get_fuse_mount_super(struct super_block *sb) +static inline struct fuse_mount *get_fuse_mount_super(const struct super_block *sb) { return sb->s_fs_info; } -static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) +static inline struct fuse_conn *get_fuse_conn_super(const struct super_block *sb) { return get_fuse_mount_super(sb)->fc; } -static inline struct fuse_mount *get_fuse_mount(struct inode *inode) +static inline struct fuse_mount *get_fuse_mount(const struct inode *inode) { return get_fuse_mount_super(inode->i_sb); } -static inline struct fuse_conn *get_fuse_conn(struct inode *inode) +static inline struct fuse_conn *get_fuse_conn(const struct inode *inode) { return get_fuse_mount_super(inode->i_sb)->fc; } -static inline struct fuse_inode *get_fuse_inode(struct inode *inode) +static inline struct fuse_inode *get_fuse_inode(const struct inode *inode) { return container_of(inode, struct fuse_inode, inode); } -static inline u64 get_node_id(struct inode *inode) +static inline u64 get_node_id(const struct inode *inode) { return get_fuse_inode(inode)->nodeid; } @@ -905,7 +905,7 @@ static inline int invalid_nodeid(u64 nodeid) return !nodeid || nodeid == FUSE_ROOT_ID; } -static inline u64 fuse_get_attr_version(struct fuse_conn *fc) +static inline u64 fuse_get_attr_version(const struct fuse_conn *fc) { return atomic64_read(&fc->attr_version); } @@ -923,7 +923,7 @@ static inline void fuse_make_bad(struct inode *inode) set_bit(FUSE_I_BAD, &get_fuse_inode(inode)->state); } -static inline bool fuse_is_bad(struct inode *inode) +static inline bool fuse_is_bad(const struct inode *inode) { return unlikely(test_bit(FUSE_I_BAD, &get_fuse_inode(inode)->state)); } From patchwork Mon Apr 3 14:45:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Aleksandr Mikhalitsyn X-Patchwork-Id: 13198270 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 27F86C76196 for ; Mon, 3 Apr 2023 14:46:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233932AbjDCOqq (ORCPT ); Mon, 3 Apr 2023 10:46:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36844 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233992AbjDCOqc (ORCPT ); Mon, 3 Apr 2023 10:46:32 -0400 Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6CC932C9F5 for ; Mon, 3 Apr 2023 07:46:16 -0700 (PDT) Received: from mail-ed1-f70.google.com (mail-ed1-f70.google.com [209.85.208.70]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 7BF863F466 for ; Mon, 3 Apr 2023 14:45:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1680533140; bh=mIRd3G7EmqzBYzec9Xklmi0CbHz6DDwl1OuXrzwAvTA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=LD8Nador3qU+xSd9cAkAo8ptLaJxNMIjqaXM0bx1qfypx/nYKKElRZJ9Lrc/Rq45q C+oheFz3hZXcJTn94Q/QSTj2L4SEjNN9J6UceCZgcZ0SIglCsUeZRJs4aXevLj/sfV 6vH1Lckm+LYOxo4+dSrOIrmanAjDwqD1wmzuXnomY7/X088z6w46sbHn1QFczG4xYr zXvB9dWEp54prs9LRFJ8ZmfH7eLQxcwneNc/KLyI/HgZW+iv1ZAO6Ph/ZZb1kxYqiJ HFl6kfKkxZeZZieZRI0PbOHcTPn+Uzs2w0ALTLEytb+84cG1rKmxcrhe3rLksNrsm6 GPI5+ojsD6wQQ== Received: by mail-ed1-f70.google.com with SMTP id m18-20020a50d7d2000000b00501dfd867a4so41939744edj.20 for ; Mon, 03 Apr 2023 07:45:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680533140; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mIRd3G7EmqzBYzec9Xklmi0CbHz6DDwl1OuXrzwAvTA=; b=1Hiis4dVi9pOp3V4odq5Gys0Ua3oXAeip9WZhd5qCqZBD5pWzjAzJ0OORRSoDhq/LE j150AG4NwAM5J7iytanajGkkttvS7bBxeBxxReNyKbLvjTFWyTZiSmYl77uHkhMEnPhD ILV2/bUfO0ODjoS8Dd5tmZbRfO4PPazr2LUcDAa7jz60aTDLsd7YP+pNKbRqAFfi0WYh AqASZUzGC8XWgjPc3NEJvf1JL3Q2zSGFXCKBzKDl/utVKQJXLr9PcZRZCp/T6rYV13Jt qP0Kxbe+bNqwBVn5zSRzUcNJvkQnSxUmP6Jmug6ggf5v+XJKfXuF+Qp46jM6IOS7pXHV 9UvQ== X-Gm-Message-State: AAQBX9dI9CMmAL1Qkd1xoDizOhWkaArCBpiWilQffeI2ouaF693WAVEA saUw9m6F/uKnnew8oraD8P/buRSmMck+iqLyG8+9PRm8KWXZgeNos1Z2NtFsptflurbx5QDo9YX YXw+rnk5gOtea5bugzPLYUi10yFtB1hkt0p93bYL9n7U= X-Received: by 2002:a17:906:8a41:b0:930:18f5:d016 with SMTP id gx1-20020a1709068a4100b0093018f5d016mr35370797ejc.15.1680533140352; Mon, 03 Apr 2023 07:45:40 -0700 (PDT) X-Google-Smtp-Source: AKy350bW1EY67CnMn+SBmXdtOOQwiMe+PQQAcAXChGCQUsD08TkK73YGtH/fhfZKhNQS0qprBkqadA== X-Received: by 2002:a17:906:8a41:b0:930:18f5:d016 with SMTP id gx1-20020a1709068a4100b0093018f5d016mr35370775ejc.15.1680533140205; Mon, 03 Apr 2023 07:45:40 -0700 (PDT) Received: from amikhalitsyn.. (ip5f5bd076.dynamic.kabel-deutschland.de. [95.91.208.118]) by smtp.gmail.com with ESMTPSA id i5-20020a50d745000000b004fa19f5ba99sm4735804edj.79.2023.04.03.07.45.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Apr 2023 07:45:39 -0700 (PDT) From: Alexander Mikhalitsyn To: mszeredi@redhat.com Cc: flyingpeng@tencent.com, Alexander Mikhalitsyn , Al Viro , Amir Goldstein , =?utf-8?q?St=C3=A9phane_Graber?= , Seth Forshee , Christian Brauner , Andrei Vagin , Pavel Tikhomirov , Bernd Schubert , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, criu@openvz.org Subject: [RFC PATCH v2 3/9] fuse: add fuse connection generation Date: Mon, 3 Apr 2023 16:45:11 +0200 Message-Id: <20230403144517.347517-4-aleksandr.mikhalitsyn@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> References: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org We will use connection generation to detect stale inodes from the "old" fuse daemon and invalidate/revalidate them. There is no functional changes. Cc: Miklos Szeredi Cc: Al Viro Cc: Amir Goldstein Cc: Stéphane Graber Cc: Seth Forshee Cc: Christian Brauner Cc: Andrei Vagin Cc: Pavel Tikhomirov Cc: Bernd Schubert Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: criu@openvz.org Signed-off-by: Alexander Mikhalitsyn --- fs/fuse/file.c | 1 + fs/fuse/fuse_i.h | 29 +++++++++++++++++++++++++++++ fs/fuse/inode.c | 2 ++ 3 files changed, 32 insertions(+) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index de37a3a06a71..1e36cd9490c6 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -79,6 +79,7 @@ struct fuse_file *fuse_file_alloc(struct fuse_mount *fm) init_waitqueue_head(&ff->poll_wait); ff->kh = atomic64_inc_return(&fm->fc->khctr); + ff->conn_gen = READ_ONCE(fm->fc->conn_gen); return ff; } diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 6d3d3ca4f136..8d4276d7ab1e 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -161,6 +161,9 @@ struct fuse_inode { */ struct fuse_inode_dax *dax; #endif + + /** Fuse connection (fuse_conn) generation when inode was allocated */ + u32 conn_gen; }; /** FUSE inode state bits */ @@ -232,6 +235,9 @@ struct fuse_file { /** Has flock been performed on this file? */ bool flock:1; + + /** Fuse connection (fuse_conn) generation when file was allocated */ + u32 conn_gen; }; /** One input argument of a request */ @@ -847,6 +853,18 @@ struct fuse_conn { /* New writepages go into this bucket */ struct fuse_sync_bucket __rcu *curr_bucket; + + /** + * Connection generation. + * Used to determine if inodes/files were created with an "old" + * fuse connection and have to be invalidated. So, all requests + * related to these inodes should fail with -EIO. + * + * CHECKME: do we really need conn_gen for struct fuse_file? + * Right now it's only needed for fuse_file_put(), where we have + * no access to the inode in some cases. + */ + u32 conn_gen; }; /* @@ -910,6 +928,17 @@ static inline u64 fuse_get_attr_version(const struct fuse_conn *fc) return atomic64_read(&fc->attr_version); } +static inline bool fuse_stale_ff(const struct fuse_file *ff) +{ + return unlikely(READ_ONCE(ff->fm->fc->conn_gen) != ff->conn_gen); +} + +static inline bool fuse_stale_inode_conn(const struct inode *inode) +{ + return unlikely(READ_ONCE(get_fuse_conn(inode)->conn_gen) != + get_fuse_inode(inode)->conn_gen); +} + static inline bool fuse_stale_inode(const struct inode *inode, int generation, struct fuse_attr *attr) { diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 3de950104f15..009fe5bbb855 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -77,6 +77,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) fi->attr_version = 0; fi->orig_ino = 0; fi->state = 0; + fi->conn_gen = READ_ONCE(get_fuse_conn_super(sb)->conn_gen); mutex_init(&fi->mutex); spin_lock_init(&fi->lock); fi->forget = fuse_alloc_forget(); @@ -848,6 +849,7 @@ void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm, fc->user_ns = get_user_ns(user_ns); fc->max_pages = FUSE_DEFAULT_MAX_PAGES_PER_REQ; fc->max_pages_limit = FUSE_MAX_MAX_PAGES; + fc->conn_gen = 1; INIT_LIST_HEAD(&fc->mounts); list_add(&fm->fc_entry, &fc->mounts); From patchwork Mon Apr 3 14:45:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Aleksandr Mikhalitsyn X-Patchwork-Id: 13198269 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B166DC76188 for ; Mon, 3 Apr 2023 14:46:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234003AbjDCOqg (ORCPT ); Mon, 3 Apr 2023 10:46:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36718 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234000AbjDCOq3 (ORCPT ); Mon, 3 Apr 2023 10:46:29 -0400 Received: from smtp-relay-internal-0.canonical.com (smtp-relay-internal-0.canonical.com [185.125.188.122]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 68B7C1697D for ; Mon, 3 Apr 2023 07:46:09 -0700 (PDT) Received: from mail-ed1-f71.google.com (mail-ed1-f71.google.com [209.85.208.71]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 241213F193 for ; Mon, 3 Apr 2023 14:45:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1680533142; bh=sfvJPZXm6cJkfP1IztZnpclfjk/5sorCwMJVKfMiws4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=U9GExCUxVL4aqiP/iHc+BJRhTm8TrUB2KDBYxu1qdLCgoojWxKETBTue1x90eS1Kt /WMM8WepVmBX6Iii0OmUWBt2/QajqMpHy8Gk0Jj97Ti459I00xf10rV2b5+IJjLAV9 +G+odC1NXPyo4/8btLds77u6naz22/nVHRi+x/UOcm5iDnw25LZv/WudfnDs2OKHzK mTKULpZc1+INR+z0z1Xl/C7mn/gKXu5/z1RjE/+q7f1emWio918ldj9TY6lxTk4UfZ rjqLqJctSSI4G9KHR74ZVg+bMbO2dQmkZ5Su6db+VCpkA9i+Uc/itK+Si+DiDF6z6Q xJTcNg9qemkzg== Received: by mail-ed1-f71.google.com with SMTP id x35-20020a50baa6000000b005021d1b1e9eso41907740ede.13 for ; Mon, 03 Apr 2023 07:45:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680533142; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=sfvJPZXm6cJkfP1IztZnpclfjk/5sorCwMJVKfMiws4=; b=6LK2+1K1yOkeLTGpG1mknkwbtznayCRXJXMqUpf+OdFOeSfwF6/tiQWOXUsMjb0ypd z5vLn7SUTCQkJaC8ZdTnoC3Z+lDBAF5eBhRHc2M7psgcErH15Teb/9lHGfGhkLNDRxa9 DY3O2g9onq91voX/iy+Q++SYN3m61XFAZ0MwUftFWlKjmdLV2CrBXru8dtrfaxUu+7rs 1DqimtWMDpKY0xr7aMfAyy6BEeteh7JHhwmfU/+Qipb3OwhTChFbMe68qQ75sr286ygs 8W8zXnSlQsghPRTL7lqC6XQ5M15Fbfr54hU3LA7H6Pt6EVbCJGRSySkO8VDCUhNKVZ8D /1Fw== X-Gm-Message-State: AAQBX9fE63tBRVVRdrLXsd47Td+TxqFeqT36x1jzLwcUAwMQBB5DxPj4 u4ixNpnR64hig0+evjqkmzHPvq1Vgrxr8SJRM8BjdNaAqKXUln9smZ8lCq+B4x9iW7gf7OFdspL n3Ryp1xJXFFkGC7h8Pj8j/71vZu3nwGVsmvUw2/6CNvw= X-Received: by 2002:aa7:d7d3:0:b0:501:d542:4d0c with SMTP id e19-20020aa7d7d3000000b00501d5424d0cmr34895167eds.22.1680533142014; Mon, 03 Apr 2023 07:45:42 -0700 (PDT) X-Google-Smtp-Source: AKy350bWGwBvS+zemjywNUWSkjvaOtu2sVDQj8OVEVo6nanlpJoWa5G14nm9QBdMW9vWHb78BkoBAQ== X-Received: by 2002:aa7:d7d3:0:b0:501:d542:4d0c with SMTP id e19-20020aa7d7d3000000b00501d5424d0cmr34895154eds.22.1680533141811; Mon, 03 Apr 2023 07:45:41 -0700 (PDT) Received: from amikhalitsyn.. (ip5f5bd076.dynamic.kabel-deutschland.de. [95.91.208.118]) by smtp.gmail.com with ESMTPSA id i5-20020a50d745000000b004fa19f5ba99sm4735804edj.79.2023.04.03.07.45.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Apr 2023 07:45:41 -0700 (PDT) From: Alexander Mikhalitsyn To: mszeredi@redhat.com Cc: flyingpeng@tencent.com, Alexander Mikhalitsyn , Al Viro , Amir Goldstein , =?utf-8?q?St=C3=A9phane_Graber?= , Seth Forshee , Christian Brauner , Andrei Vagin , Pavel Tikhomirov , Bernd Schubert , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, criu@openvz.org Subject: [RFC PATCH v2 4/9] fuse: handle stale inode connection in fuse_queue_forget Date: Mon, 3 Apr 2023 16:45:12 +0200 Message-Id: <20230403144517.347517-5-aleksandr.mikhalitsyn@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> References: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org We don't want to send FUSE_FORGET request to the new fuse daemon if inode was lookuped by the old fuse daemon because it can confuse and break userspace (libfuse). For now, just add a new argument to fuse_queue_forget and handle it. Adjust all callers to match the old behaviour. Cc: Miklos Szeredi Cc: Al Viro Cc: Amir Goldstein Cc: Stéphane Graber Cc: Seth Forshee Cc: Christian Brauner Cc: Andrei Vagin Cc: Pavel Tikhomirov Cc: Bernd Schubert Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: criu@openvz.org Signed-off-by: Alexander Mikhalitsyn --- fs/fuse/dev.c | 4 ++-- fs/fuse/dir.c | 8 ++++---- fs/fuse/fuse_i.h | 2 +- fs/fuse/inode.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index eb4f88e3dc97..2e7cd60b685e 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -234,7 +234,7 @@ __releases(fiq->lock) } void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, - u64 nodeid, u64 nlookup) + u64 nodeid, u64 nlookup, bool stale_inode_conn) { struct fuse_iqueue *fiq = &fc->iq; @@ -242,7 +242,7 @@ void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, forget->forget_one.nlookup = nlookup; spin_lock(&fiq->lock); - if (fiq->connected) { + if (fiq->connected && likely(!stale_inode_conn)) { fiq->forget_list_tail->next = forget; fiq->forget_list_tail = forget; fiq->ops->wake_forget_and_unlock(fiq); diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 5a4a7155cf1c..7e308a655191 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -250,7 +250,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) if (outarg.nodeid != get_node_id(inode) || (bool) IS_AUTOMOUNT(inode) != (bool) (outarg.attr.flags & FUSE_ATTR_SUBMOUNT)) { fuse_queue_forget(fm->fc, forget, - outarg.nodeid, 1); + outarg.nodeid, 1, false); goto invalid; } spin_lock(&fi->lock); @@ -403,7 +403,7 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name attr_version); err = -ENOMEM; if (!*inode) { - fuse_queue_forget(fm->fc, forget, outarg->nodeid, 1); + fuse_queue_forget(fm->fc, forget, outarg->nodeid, 1, false); goto out; } err = 0; @@ -690,7 +690,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, if (!inode) { flags &= ~(O_CREAT | O_EXCL | O_TRUNC); fuse_sync_release(NULL, ff, flags); - fuse_queue_forget(fm->fc, forget, outentry.nodeid, 1); + fuse_queue_forget(fm->fc, forget, outentry.nodeid, 1, false); err = -ENOMEM; goto out_err; } @@ -815,7 +815,7 @@ static int create_new_entry(struct fuse_mount *fm, struct fuse_args *args, inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, &outarg.attr, entry_attr_timeout(&outarg), 0); if (!inode) { - fuse_queue_forget(fm->fc, forget, outarg.nodeid, 1); + fuse_queue_forget(fm->fc, forget, outarg.nodeid, 1, false); return -ENOMEM; } kfree(forget); diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 8d4276d7ab1e..be5d5d3fe6f5 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -1008,7 +1008,7 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name * Send FORGET command */ void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, - u64 nodeid, u64 nlookup); + u64 nodeid, u64 nlookup, bool stale_inode_conn); struct fuse_forget_link *fuse_alloc_forget(void); diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 009fe5bbb855..e5ad5d4c215a 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -124,7 +124,7 @@ static void fuse_evict_inode(struct inode *inode) fuse_dax_inode_cleanup(inode); if (fi->nlookup) { fuse_queue_forget(fc, fi->forget, fi->nodeid, - fi->nlookup); + fi->nlookup, false); fi->forget = NULL; } } From patchwork Mon Apr 3 14:45:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Aleksandr Mikhalitsyn X-Patchwork-Id: 13198274 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 99A08C76188 for ; Mon, 3 Apr 2023 14:47:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234073AbjDCOrv (ORCPT ); Mon, 3 Apr 2023 10:47:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36948 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234076AbjDCOrY (ORCPT ); Mon, 3 Apr 2023 10:47:24 -0400 Received: from smtp-relay-internal-0.canonical.com (smtp-relay-internal-0.canonical.com [185.125.188.122]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7B76729BEB for ; Mon, 3 Apr 2023 07:46:44 -0700 (PDT) Received: from mail-ed1-f72.google.com (mail-ed1-f72.google.com [209.85.208.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 23BBF3F242 for ; Mon, 3 Apr 2023 14:45:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1680533144; bh=x5RnUDjgYT8e/ziRn/O8mcriKdksyC0pPXgew4XaumM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=mgR4qhPohZ0/rMm+w4p6fTDQZ5j99kJ1JRspxRoPhPup+y8Aa6EFbBOe6ucVjCcPz ZyxQT5Pc0YzbtGAVxRtvWJnozAHsskXuo1BzPvnJlKIYKF2avu3FDCdeblMMFGNO2W ZJjd5A0xadzA4bulb+/dAJj8Ueo7rJ9FCe1WKlA9noDBIS7LHFrAaido6qXjr7p07M b3gkVx+8k0tDQJTscUr2p/AC5bktmSW0nN7ag2fEjXKT+WyqY/iWMPjYxxS3z4LcyX 1A5QJKPeY2weIuXgj/5WTql4QnQ3s0Wag1d0jUOC+kR/rGNBTtWoDXE+iPYel/NQIc u+z78FrDaDstQ== Received: by mail-ed1-f72.google.com with SMTP id t26-20020a50d71a000000b005003c5087caso41189052edi.1 for ; Mon, 03 Apr 2023 07:45:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680533144; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=x5RnUDjgYT8e/ziRn/O8mcriKdksyC0pPXgew4XaumM=; b=oVpOE54fgP29ytPfbs27YsFNswKzERpUZRZMxLK112CFfeK68nRGLMvnfOnZse78nC b2iUnUkQdCIfhRoLyHwogfhp7EqLkYS3iBrC9j4XPL5Afm+m366ndA+JARlrcLWrAdOB u5iPimvjHygsD4e2VuiFf5SYQzNuOeUOAeLDJZ6UTUU/RKDVwLnWGWWE4ZgS1OBNeLcm l7SrORXt3vRjuRDSaDwQ/jtqSqcqaO4pewPdBeMm8n2KAfbAWQRzz8Pbzi/p9Bk3vefI 8oN9iIcTwaHc1yTzJulymZUFrW1TSV0EYcP/UKnOoEtrdUUgjfFOjxY/t/2btj1dlheh 1XwA== X-Gm-Message-State: AAQBX9dWGbsiwnYSRV1htnAa/PIQVdg3WFxKGn2EzogMHNZbx7b0ZC3o U0eXvkoIbQOelWpQXwMvM+g0+Aw0T/4rKVqgLhn3sObwzSEl9I19OJg1T1daIl4AsSOHpzoV1oR 6MDSZ7ZLjaDp2v6YeYedvBtSC4h4+9S2vlGKT771uaUk= X-Received: by 2002:a05:6402:18c:b0:502:9885:f359 with SMTP id r12-20020a056402018c00b005029885f359mr4502651edv.39.1680533143815; Mon, 03 Apr 2023 07:45:43 -0700 (PDT) X-Google-Smtp-Source: AKy350bVIYHTcZgmKyms1HoHJGM63luRhnQIywc30+8HU38tcrh9VJWQkVD8YoCa8LcX9C++jNY1tA== X-Received: by 2002:a05:6402:18c:b0:502:9885:f359 with SMTP id r12-20020a056402018c00b005029885f359mr4502622edv.39.1680533143426; Mon, 03 Apr 2023 07:45:43 -0700 (PDT) Received: from amikhalitsyn.. (ip5f5bd076.dynamic.kabel-deutschland.de. [95.91.208.118]) by smtp.gmail.com with ESMTPSA id i5-20020a50d745000000b004fa19f5ba99sm4735804edj.79.2023.04.03.07.45.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Apr 2023 07:45:43 -0700 (PDT) From: Alexander Mikhalitsyn To: mszeredi@redhat.com Cc: flyingpeng@tencent.com, Alexander Mikhalitsyn , Al Viro , Amir Goldstein , =?utf-8?q?St=C3=A9phane_Graber?= , Seth Forshee , Christian Brauner , Andrei Vagin , Pavel Tikhomirov , Bernd Schubert , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, criu@openvz.org Subject: [RFC PATCH v2 5/9] fuse: move fuse connection flags to the separate structure Date: Mon, 3 Apr 2023 16:45:13 +0200 Message-Id: <20230403144517.347517-6-aleksandr.mikhalitsyn@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> References: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Let's move all the fuse connection flags that can be safely zeroed after connection reinitialization to the separate structure fuse_conn_flags. All of these flags values are calculated dynamically basing on the userspace daemon capabilities (like no_open, no_flush) or on the response for FUSE_INIT request. Cc: Miklos Szeredi Cc: Al Viro Cc: Amir Goldstein Cc: Stéphane Graber Cc: Seth Forshee Cc: Christian Brauner Cc: Andrei Vagin Cc: Pavel Tikhomirov Cc: Bernd Schubert Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: criu@openvz.org Signed-off-by: Alexander Mikhalitsyn --- fs/fuse/acl.c | 6 +- fs/fuse/dev.c | 4 +- fs/fuse/dir.c | 26 +++--- fs/fuse/file.c | 80 ++++++++-------- fs/fuse/fuse_i.h | 228 ++++++++++++++++++++++++---------------------- fs/fuse/inode.c | 52 +++++------ fs/fuse/readdir.c | 8 +- fs/fuse/xattr.c | 18 ++-- 8 files changed, 218 insertions(+), 204 deletions(-) diff --git a/fs/fuse/acl.c b/fs/fuse/acl.c index 3d192b80a561..549b5a1da7ff 100644 --- a/fs/fuse/acl.c +++ b/fs/fuse/acl.c @@ -26,7 +26,7 @@ static struct posix_acl *__fuse_get_acl(struct fuse_conn *fc, if (fuse_is_bad(inode)) return ERR_PTR(-EIO); - if (fc->no_getxattr) + if (fc->flags.no_getxattr) return NULL; if (type == ACL_TYPE_ACCESS) @@ -43,7 +43,7 @@ static struct posix_acl *__fuse_get_acl(struct fuse_conn *fc, if (size > 0) acl = posix_acl_from_xattr(fc->user_ns, value, size); else if ((size == 0) || (size == -ENODATA) || - (size == -EOPNOTSUPP && fc->no_getxattr)) + (size == -EOPNOTSUPP && fc->flags.no_getxattr)) acl = NULL; else if (size == -ERANGE) acl = ERR_PTR(-E2BIG); @@ -105,7 +105,7 @@ int fuse_set_acl(struct mnt_idmap *idmap, struct dentry *dentry, if (fuse_is_bad(inode)) return -EIO; - if (fc->no_setxattr || fuse_no_acl(fc, inode)) + if (fc->flags.no_setxattr || fuse_no_acl(fc, inode)) return -EOPNOTSUPP; if (type == ACL_TYPE_ACCESS) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 2e7cd60b685e..b4501a10c379 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -367,7 +367,7 @@ static void request_wait_answer(struct fuse_req *req) struct fuse_iqueue *fiq = &fc->iq; int err; - if (!fc->no_interrupt) { + if (!fc->flags.no_interrupt) { /* Any signal may interrupt this */ err = wait_event_interruptible(req->waitq, test_bit(FR_FINISHED, &req->flags)); @@ -1901,7 +1901,7 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud, if (nbytes != sizeof(struct fuse_out_header)) err = -EINVAL; else if (oh.error == -ENOSYS) - fc->no_interrupt = 1; + fc->flags.no_interrupt = 1; else if (oh.error == -EAGAIN) err = queue_interrupt(req); diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 7e308a655191..bfbe59e8fce2 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -705,7 +705,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, } else { file->private_data = ff; fuse_finish_open(inode, file); - if (fm->fc->atomic_o_trunc && trunc) + if (fm->fc->flags.atomic_o_trunc && trunc) truncate_pagecache(inode, 0); else if (!(ff->open_flags & FOPEN_KEEP_CACHE)) invalidate_inode_pages2(inode->i_mapping); @@ -748,12 +748,12 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry, /* Only creates */ file->f_mode |= FMODE_CREATED; - if (fc->no_create) + if (fc->flags.no_create) goto mknod; err = fuse_create_open(dir, entry, file, flags, mode, FUSE_CREATE); if (err == -ENOSYS) { - fc->no_create = 1; + fc->flags.no_create = 1; goto mknod; } out_dput: @@ -1078,14 +1078,14 @@ static int fuse_rename2(struct mnt_idmap *idmap, struct inode *olddir, return -EINVAL; if (flags) { - if (fc->no_rename2 || fc->minor < 23) + if (fc->flags.no_rename2 || fc->minor < 23) return -EINVAL; err = fuse_rename_common(olddir, oldent, newdir, newent, flags, FUSE_RENAME2, sizeof(struct fuse_rename2_in)); if (err == -ENOSYS) { - fc->no_rename2 = 1; + fc->flags.no_rename2 = 1; err = -EINVAL; } } else { @@ -1352,7 +1352,7 @@ static int fuse_access(struct inode *inode, int mask) BUG_ON(mask & MAY_NOT_BLOCK); - if (fm->fc->no_access) + if (fm->fc->flags.no_access) return 0; memset(&inarg, 0, sizeof(inarg)); @@ -1364,7 +1364,7 @@ static int fuse_access(struct inode *inode, int mask) args.in_args[0].value = &inarg; err = fuse_simple_request(fm, &args); if (err == -ENOSYS) { - fm->fc->no_access = 1; + fm->fc->flags.no_access = 1; err = 0; } return err; @@ -1501,7 +1501,7 @@ static const char *fuse_get_link(struct dentry *dentry, struct inode *inode, if (fuse_is_bad(inode)) goto out_err; - if (fc->cache_symlinks) + if (fc->flags.cache_symlinks) return page_get_link(dentry, inode, callback); err = -ECHILD; @@ -1549,13 +1549,13 @@ static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end, if (fuse_is_bad(inode)) return -EIO; - if (fc->no_fsyncdir) + if (fc->flags.no_fsyncdir) return 0; inode_lock(inode); err = fuse_fsync_common(file, start, end, datasync, FUSE_FSYNCDIR); if (err == -ENOSYS) { - fc->no_fsyncdir = 1; + fc->flags.no_fsyncdir = 1; err = 0; } inode_unlock(inode); @@ -1747,7 +1747,7 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr, struct fuse_setattr_in inarg; struct fuse_attr_out outarg; bool is_truncate = false; - bool is_wb = fc->writeback_cache && S_ISREG(inode->i_mode); + bool is_wb = fc->flags.writeback_cache && S_ISREG(inode->i_mode); loff_t oldsize; int err; bool trust_local_cmtime = is_wb; @@ -1780,7 +1780,7 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr, /* This is coming from open(..., ... | O_TRUNC); */ WARN_ON(!(attr->ia_valid & ATTR_SIZE)); WARN_ON(attr->ia_size != 0); - if (fc->atomic_o_trunc) { + if (fc->flags.atomic_o_trunc) { /* * No need to send request to userspace, since actual * truncation has already been done by OPEN. But still @@ -1927,7 +1927,7 @@ static int fuse_setattr(struct mnt_idmap *idmap, struct dentry *entry, * * This should be done on write(), truncate() and chown(). */ - if (!fc->handle_killpriv && !fc->handle_killpriv_v2) { + if (!fc->flags.handle_killpriv && !fc->handle_killpriv_v2) { /* * ia_mode calculation may have used stale i_mode. * Refresh and recalculate. diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 1e36cd9490c6..742f90b4e638 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -30,7 +30,7 @@ static int fuse_send_open(struct fuse_mount *fm, u64 nodeid, memset(&inarg, 0, sizeof(inarg)); inarg.flags = open_flags & ~(O_CREAT | O_EXCL | O_NOCTTY); - if (!fm->fc->atomic_o_trunc) + if (!fm->fc->flags.atomic_o_trunc) inarg.flags &= ~O_TRUNC; if (fm->fc->handle_killpriv_v2 && @@ -111,7 +111,7 @@ static void fuse_file_put(struct fuse_file *ff, bool sync, bool isdir) if (refcount_dec_and_test(&ff->count)) { struct fuse_args *args = &ff->release_args->args; - if (isdir ? ff->fm->fc->no_opendir : ff->fm->fc->no_open) { + if (isdir ? ff->fm->fc->flags.no_opendir : ff->fm->fc->flags.no_open) { /* Do nothing when client does not implement 'open' */ fuse_release_end(ff->fm, args, 0); } else if (sync) { @@ -141,7 +141,7 @@ struct fuse_file *fuse_file_open(struct fuse_mount *fm, u64 nodeid, ff->fh = 0; /* Default for no-open */ ff->open_flags = FOPEN_KEEP_CACHE | (isdir ? FOPEN_CACHE_DIR : 0); - if (isdir ? !fc->no_opendir : !fc->no_open) { + if (isdir ? !fc->flags.no_opendir : !fc->flags.no_open) { struct fuse_open_out outarg; int err; @@ -155,9 +155,9 @@ struct fuse_file *fuse_file_open(struct fuse_mount *fm, u64 nodeid, return ERR_PTR(err); } else { if (isdir) - fc->no_opendir = 1; + fc->flags.no_opendir = 1; else - fc->no_open = 1; + fc->flags.no_open = 1; } } @@ -206,7 +206,7 @@ void fuse_finish_open(struct inode *inode, struct file *file) else if (ff->open_flags & FOPEN_NONSEEKABLE) nonseekable_open(inode, file); - if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC)) { + if (fc->flags.atomic_o_trunc && (file->f_flags & O_TRUNC)) { struct fuse_inode *fi = get_fuse_inode(inode); spin_lock(&fi->lock); @@ -216,7 +216,7 @@ void fuse_finish_open(struct inode *inode, struct file *file) file_update_time(file); fuse_invalidate_attr_mask(inode, FUSE_STATX_MODSIZE); } - if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache) + if ((file->f_mode & FMODE_WRITE) && fc->flags.writeback_cache) fuse_link_write_file(file); } @@ -226,10 +226,10 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir) struct fuse_conn *fc = fm->fc; int err; bool is_wb_truncate = (file->f_flags & O_TRUNC) && - fc->atomic_o_trunc && - fc->writeback_cache; + fc->flags.atomic_o_trunc && + fc->flags.writeback_cache; bool dax_truncate = (file->f_flags & O_TRUNC) && - fc->atomic_o_trunc && FUSE_IS_DAX(inode); + fc->flags.atomic_o_trunc && FUSE_IS_DAX(inode); if (fuse_is_bad(inode)) return -EIO; @@ -260,7 +260,7 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir) if (!err) { struct fuse_file *ff = file->private_data; - if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC)) + if (fc->flags.atomic_o_trunc && (file->f_flags & O_TRUNC)) truncate_pagecache(inode, 0); else if (!(ff->open_flags & FOPEN_KEEP_CACHE)) invalidate_inode_pages2(inode->i_mapping); @@ -351,7 +351,7 @@ static int fuse_release(struct inode *inode, struct file *file) * Dirty pages might remain despite write_inode_now() call from * fuse_flush() due to writes racing with the close. */ - if (fc->writeback_cache) + if (fc->flags.writeback_cache) write_inode_now(inode, 1); fuse_release_common(file, false); @@ -506,12 +506,12 @@ static int fuse_do_flush(struct fuse_flush_args *fa) goto out; err = 0; - if (fm->fc->no_flush) + if (fm->fc->flags.no_flush) goto inval_attr_out; err = fuse_simple_request(fm, &fa->args); if (err == -ENOSYS) { - fm->fc->no_flush = 1; + fm->fc->flags.no_flush = 1; err = 0; } @@ -520,7 +520,7 @@ static int fuse_do_flush(struct fuse_flush_args *fa) * In memory i_blocks is not maintained by fuse, if writeback cache is * enabled, i_blocks from cached attr may not be accurate. */ - if (!err && fm->fc->writeback_cache) + if (!err && fm->fc->flags.writeback_cache) fuse_invalidate_attr_mask(inode, STATX_BLOCKS); out: @@ -546,7 +546,7 @@ static int fuse_flush(struct file *file, fl_owner_t id) if (fuse_is_bad(inode)) return -EIO; - if (ff->open_flags & FOPEN_NOFLUSH && !fm->fc->writeback_cache) + if (ff->open_flags & FOPEN_NOFLUSH && !fm->fc->flags.writeback_cache) return 0; fa = kzalloc(sizeof(*fa), GFP_KERNEL); @@ -629,12 +629,12 @@ static int fuse_fsync(struct file *file, loff_t start, loff_t end, if (err) goto out; - if (fc->no_fsync) + if (fc->flags.no_fsync) goto out; err = fuse_fsync_common(file, start, end, datasync, FUSE_FSYNC); if (err == -ENOSYS) { - fc->no_fsync = 1; + fc->flags.no_fsync = 1; err = 0; } out: @@ -859,7 +859,7 @@ static void fuse_short_read(struct inode *inode, u64 attr_ver, size_t num_read, * the file. Some data after the hole is in page cache, but has not * reached the client fs yet. So the hole is not present there. */ - if (!fc->writeback_cache) { + if (!fc->flags.writeback_cache) { loff_t pos = page_offset(ap->pages[0]) + num_read; fuse_read_update_size(inode, pos, attr_ver); } @@ -990,7 +990,7 @@ static void fuse_send_readpages(struct fuse_io_args *ia, struct file *file) fuse_read_args_fill(ia, file, pos, count, FUSE_READ); ia->read.attr_ver = fuse_get_attr_version(fm->fc); - if (fm->fc->async_read) { + if (fm->fc->flags.async_read) { ia->ff = fuse_file_get(ff); ap->args.end = fuse_readpages_end; err = fuse_simple_background(fm, &ap->args, GFP_KERNEL); @@ -1057,7 +1057,7 @@ static ssize_t fuse_cache_read_iter(struct kiocb *iocb, struct iov_iter *to) * Otherwise, only update if we attempt to read past EOF (to ensure * i_size is up to date). */ - if (fc->auto_inval_data || + if (fc->flags.auto_inval_data || (iocb->ki_pos + iov_iter_count(to) > i_size_read(inode))) { int err; err = fuse_update_attributes(inode, iocb->ki_filp, STATX_SIZE); @@ -1264,7 +1264,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_io_args *ia, ia->write.page_locked = true; break; } - if (!fc->big_writes) + if (!fc->flags.big_writes) break; } while (iov_iter_count(ii) && count < fc->max_write && ap->num_pages < max_pages && offset == 0); @@ -1344,7 +1344,7 @@ static ssize_t fuse_cache_write_iter(struct kiocb *iocb, struct iov_iter *from) struct fuse_conn *fc = get_fuse_conn(inode); loff_t endbyte = 0; - if (fc->writeback_cache) { + if (fc->flags.writeback_cache) { /* Update size (EOF optimization) and mode (SUID clearing) */ err = fuse_update_attributes(mapping->host, file, STATX_SIZE | STATX_MODE); @@ -1866,7 +1866,7 @@ static void fuse_writepage_end(struct fuse_mount *fm, struct fuse_args *args, * Do this only if writeback_cache is not enabled. If writeback_cache * is enabled, we trust local ctime/mtime. */ - if (!fc->writeback_cache) + if (!fc->flags.writeback_cache) fuse_invalidate_attr_mask(inode, FUSE_STATX_MODIFY); spin_lock(&fi->lock); rb_erase(&wpa->writepages_entry, &fi->writepages); @@ -2370,7 +2370,7 @@ static int fuse_write_begin(struct file *file, struct address_space *mapping, loff_t fsize; int err = -ENOMEM; - WARN_ON(!fc->writeback_cache); + WARN_ON(!fc->flags.writeback_cache); page = grab_cache_page_write_begin(mapping, index); if (!page) @@ -2643,13 +2643,13 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl) if (cmd == F_CANCELLK) { err = 0; } else if (cmd == F_GETLK) { - if (fc->no_lock) { + if (fc->flags.no_lock) { posix_test_lock(file, fl); err = 0; } else err = fuse_getlk(file, fl); } else { - if (fc->no_lock) + if (fc->flags.no_lock) err = posix_lock_file(file, fl, NULL); else err = fuse_setlk(file, fl, 0); @@ -2663,7 +2663,7 @@ static int fuse_file_flock(struct file *file, int cmd, struct file_lock *fl) struct fuse_conn *fc = get_fuse_conn(inode); int err; - if (fc->no_flock) { + if (fc->flags.no_flock) { err = locks_lock_file_wait(file, fl); } else { struct fuse_file *ff = file->private_data; @@ -2685,7 +2685,7 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block) struct fuse_bmap_out outarg; int err; - if (!inode->i_sb->s_bdev || fm->fc->no_bmap) + if (!inode->i_sb->s_bdev || fm->fc->flags.no_bmap) return 0; memset(&inarg, 0, sizeof(inarg)); @@ -2701,7 +2701,7 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block) args.out_args[0].value = &outarg; err = fuse_simple_request(fm, &args); if (err == -ENOSYS) - fm->fc->no_bmap = 1; + fm->fc->flags.no_bmap = 1; return err ? 0 : outarg.block; } @@ -2720,7 +2720,7 @@ static loff_t fuse_lseek(struct file *file, loff_t offset, int whence) struct fuse_lseek_out outarg; int err; - if (fm->fc->no_lseek) + if (fm->fc->flags.no_lseek) goto fallback; args.opcode = FUSE_LSEEK; @@ -2734,7 +2734,7 @@ static loff_t fuse_lseek(struct file *file, loff_t offset, int whence) err = fuse_simple_request(fm, &args); if (err) { if (err == -ENOSYS) { - fm->fc->no_lseek = 1; + fm->fc->flags.no_lseek = 1; goto fallback; } return err; @@ -2841,7 +2841,7 @@ __poll_t fuse_file_poll(struct file *file, poll_table *wait) FUSE_ARGS(args); int err; - if (fm->fc->no_poll) + if (fm->fc->flags.no_poll) return DEFAULT_POLLMASK; poll_wait(file, &ff->poll_wait, wait); @@ -2869,7 +2869,7 @@ __poll_t fuse_file_poll(struct file *file, poll_table *wait) if (!err) return demangle_poll(outarg.revents); if (err == -ENOSYS) { - fm->fc->no_poll = 1; + fm->fc->flags.no_poll = 1; return DEFAULT_POLLMASK; } return EPOLLERR; @@ -2955,7 +2955,7 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter) * By default, we want to optimize all I/Os with async request * submission to the client filesystem if supported. */ - io->async = ff->fm->fc->async_dio; + io->async = ff->fm->fc->flags.async_dio; io->iocb = iocb; io->blocking = is_sync_kiocb(iocb); @@ -3048,7 +3048,7 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, FALLOC_FL_ZERO_RANGE)) return -EOPNOTSUPP; - if (fm->fc->no_fallocate) + if (fm->fc->flags.no_fallocate) return -EOPNOTSUPP; inode_lock(inode); @@ -3088,7 +3088,7 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, args.in_args[0].value = &inarg; err = fuse_simple_request(fm, &args); if (err == -ENOSYS) { - fm->fc->no_fallocate = 1; + fm->fc->flags.no_fallocate = 1; err = -EOPNOTSUPP; } if (err) @@ -3144,10 +3144,10 @@ static ssize_t __fuse_copy_file_range(struct file *file_in, loff_t pos_in, ssize_t err; /* mark unstable when write-back is not used, and file_out gets * extended */ - bool is_unstable = (!fc->writeback_cache) && + bool is_unstable = (!fc->flags.writeback_cache) && ((pos_out + len) > inode_out->i_size); - if (fc->no_copy_file_range) + if (fc->flags.no_copy_file_range) return -EOPNOTSUPP; if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb) @@ -3200,7 +3200,7 @@ static ssize_t __fuse_copy_file_range(struct file *file_in, loff_t pos_in, args.out_args[0].value = &outarg; err = fuse_simple_request(fm, &args); if (err == -ENOSYS) { - fc->no_copy_file_range = 1; + fc->flags.no_copy_file_range = 1; err = -EOPNOTSUPP; } if (err) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index be5d5d3fe6f5..943d5011dfa0 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -543,6 +543,125 @@ struct fuse_sync_bucket { struct rcu_head rcu; }; +/** + * A Fuse connection flags. + * + * This structure describes fuse connection capabilities, depending on the + * userspace daemon implementation. + * Most of this flags are calculated during the processing of reply to FUSE_INIT request, + * but some flags values are determined after connection initialization, for example, + * no_flush, no_setxattr, etc. These flags are safe to clear, because they always can be + * restored with a proper values in runtime. + */ +struct fuse_conn_flags { + /** Do readahead asynchronously? Only set in INIT */ + unsigned async_read:1; + + /** Do not send separate SETATTR request before open(O_TRUNC) */ + unsigned atomic_o_trunc:1; + + /** Filesystem supports NFS exporting. Only set in INIT */ + unsigned export_support:1; + + /** write-back cache policy (default is write-through) */ + unsigned writeback_cache:1; + + /** allow parallel lookups and readdir (default is serialized) */ + unsigned parallel_dirops:1; + + /** handle fs handles killing suid/sgid/cap on write/chown/trunc */ + unsigned handle_killpriv:1; + + /** cache READLINK responses in page cache */ + unsigned cache_symlinks:1; + + /* + * The following bitfields are only for optimization purposes + * and hence races in setting them will not cause malfunction + */ + + /** Is open/release not implemented by fs? */ + unsigned no_open:1; + + /** Is opendir/releasedir not implemented by fs? */ + unsigned no_opendir:1; + + /** Is fsync not implemented by fs? */ + unsigned no_fsync:1; + + /** Is fsyncdir not implemented by fs? */ + unsigned no_fsyncdir:1; + + /** Is flush not implemented by fs? */ + unsigned no_flush:1; + + /** Is setxattr not implemented by fs? */ + unsigned no_setxattr:1; + + /** Does file server support extended setxattr */ + unsigned setxattr_ext:1; + + /** Is getxattr not implemented by fs? */ + unsigned no_getxattr:1; + + /** Is listxattr not implemented by fs? */ + unsigned no_listxattr:1; + + /** Is removexattr not implemented by fs? */ + unsigned no_removexattr:1; + + /** Are posix file locking primitives not implemented by fs? */ + unsigned no_lock:1; + + /** Is access not implemented by fs? */ + unsigned no_access:1; + + /** Is create not implemented by fs? */ + unsigned no_create:1; + + /** Is interrupt not implemented by fs? */ + unsigned no_interrupt:1; + + /** Is bmap not implemented by fs? */ + unsigned no_bmap:1; + + /** Is poll not implemented by fs? */ + unsigned no_poll:1; + + /** Do multi-page cached writes */ + unsigned big_writes:1; + + /** Are BSD file locking primitives not implemented by fs? */ + unsigned no_flock:1; + + /** Is fallocate not implemented by fs? */ + unsigned no_fallocate:1; + + /** Is rename with flags implemented by fs? */ + unsigned no_rename2:1; + + /** Use enhanced/automatic page cache invalidation. */ + unsigned auto_inval_data:1; + + /** Filesystem is fully responsible for page cache invalidation. */ + unsigned explicit_inval_data:1; + + /** Does the filesystem support readdirplus? */ + unsigned do_readdirplus:1; + + /** Does the filesystem want adaptive readdirplus? */ + unsigned readdirplus_auto:1; + + /** Does the filesystem support asynchronous direct-IO submission? */ + unsigned async_dio:1; + + /** Is lseek not implemented by fs? */ + unsigned no_lseek:1; + + /** Does the filesystem support copy_file_range? */ + unsigned no_copy_file_range:1; +}; + /** * A Fuse connection. * @@ -641,30 +760,9 @@ struct fuse_conn { /** Connection successful. Only set in INIT */ unsigned conn_init:1; - /** Do readahead asynchronously? Only set in INIT */ - unsigned async_read:1; - /** Return an unique read error after abort. Only set in INIT */ unsigned abort_err:1; - /** Do not send separate SETATTR request before open(O_TRUNC) */ - unsigned atomic_o_trunc:1; - - /** Filesystem supports NFS exporting. Only set in INIT */ - unsigned export_support:1; - - /** write-back cache policy (default is write-through) */ - unsigned writeback_cache:1; - - /** allow parallel lookups and readdir (default is serialized) */ - unsigned parallel_dirops:1; - - /** handle fs handles killing suid/sgid/cap on write/chown/trunc */ - unsigned handle_killpriv:1; - - /** cache READLINK responses in page cache */ - unsigned cache_symlinks:1; - /* show legacy mount options */ unsigned int legacy_opts_show:1; @@ -676,92 +774,9 @@ struct fuse_conn { */ unsigned handle_killpriv_v2:1; - /* - * The following bitfields are only for optimization purposes - * and hence races in setting them will not cause malfunction - */ - - /** Is open/release not implemented by fs? */ - unsigned no_open:1; - - /** Is opendir/releasedir not implemented by fs? */ - unsigned no_opendir:1; - - /** Is fsync not implemented by fs? */ - unsigned no_fsync:1; - - /** Is fsyncdir not implemented by fs? */ - unsigned no_fsyncdir:1; - - /** Is flush not implemented by fs? */ - unsigned no_flush:1; - - /** Is setxattr not implemented by fs? */ - unsigned no_setxattr:1; - - /** Does file server support extended setxattr */ - unsigned setxattr_ext:1; - - /** Is getxattr not implemented by fs? */ - unsigned no_getxattr:1; - - /** Is listxattr not implemented by fs? */ - unsigned no_listxattr:1; - - /** Is removexattr not implemented by fs? */ - unsigned no_removexattr:1; - - /** Are posix file locking primitives not implemented by fs? */ - unsigned no_lock:1; - - /** Is access not implemented by fs? */ - unsigned no_access:1; - - /** Is create not implemented by fs? */ - unsigned no_create:1; - - /** Is interrupt not implemented by fs? */ - unsigned no_interrupt:1; - - /** Is bmap not implemented by fs? */ - unsigned no_bmap:1; - - /** Is poll not implemented by fs? */ - unsigned no_poll:1; - - /** Do multi-page cached writes */ - unsigned big_writes:1; - /** Don't apply umask to creation modes */ unsigned dont_mask:1; - /** Are BSD file locking primitives not implemented by fs? */ - unsigned no_flock:1; - - /** Is fallocate not implemented by fs? */ - unsigned no_fallocate:1; - - /** Is rename with flags implemented by fs? */ - unsigned no_rename2:1; - - /** Use enhanced/automatic page cache invalidation. */ - unsigned auto_inval_data:1; - - /** Filesystem is fully responsible for page cache invalidation. */ - unsigned explicit_inval_data:1; - - /** Does the filesystem support readdirplus? */ - unsigned do_readdirplus:1; - - /** Does the filesystem want adaptive readdirplus? */ - unsigned readdirplus_auto:1; - - /** Does the filesystem support asynchronous direct-IO submission? */ - unsigned async_dio:1; - - /** Is lseek not implemented by fs? */ - unsigned no_lseek:1; - /** Does the filesystem support posix acls? */ unsigned posix_acl:1; @@ -771,9 +786,6 @@ struct fuse_conn { /** Allow other than the mounter user to access the filesystem ? */ unsigned allow_other:1; - /** Does the filesystem support copy_file_range? */ - unsigned no_copy_file_range:1; - /* Send DESTROY request */ unsigned int destroy:1; @@ -804,6 +816,8 @@ struct fuse_conn { /* Is tmpfile not implemented by fs? */ unsigned int no_tmpfile:1; + struct fuse_conn_flags flags; + /** The number of requests waiting for completion */ atomic_t num_waiting; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index e5ad5d4c215a..389bea6e4a69 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -224,7 +224,7 @@ u32 fuse_get_cache_mask(struct inode *inode) { struct fuse_conn *fc = get_fuse_conn(inode); - if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) + if (!fc->flags.writeback_cache || !S_ISREG(inode->i_mode)) return 0; return STATX_MTIME | STATX_CTIME | STATX_SIZE; @@ -282,9 +282,9 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, if (oldsize != attr->size) { truncate_pagecache(inode, attr->size); - if (!fc->explicit_inval_data) + if (!fc->flags.explicit_inval_data) inval = true; - } else if (fc->auto_inval_data) { + } else if (fc->flags.auto_inval_data) { struct timespec64 new_mtime = { .tv_sec = attr->mtime, .tv_nsec = attr->mtimensec, @@ -387,7 +387,7 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid, if ((inode->i_state & I_NEW)) { inode->i_flags |= S_NOATIME; - if (!fc->writeback_cache || !S_ISREG(attr->mode)) + if (!fc->flags.writeback_cache || !S_ISREG(attr->mode)) inode->i_flags |= S_NOCMTIME; inode->i_generation = generation; fuse_init_inode(inode, attr, fc); @@ -466,7 +466,7 @@ bool fuse_lock_inode(struct inode *inode) { bool locked = false; - if (!get_fuse_conn(inode)->parallel_dirops) { + if (!get_fuse_conn(inode)->flags.parallel_dirops) { mutex_lock(&get_fuse_inode(inode)->mutex); locked = true; } @@ -918,7 +918,7 @@ static struct dentry *fuse_get_dentry(struct super_block *sb, struct fuse_entry_out outarg; const struct qstr name = QSTR_INIT(".", 1); - if (!fc->export_support) + if (!fc->flags.export_support) goto out_err; err = fuse_lookup_name(sb, handle->nodeid, &name, &outarg, @@ -1018,7 +1018,7 @@ static struct dentry *fuse_get_parent(struct dentry *child) struct fuse_entry_out outarg; int err; - if (!fc->export_support) + if (!fc->flags.export_support) return ERR_PTR(-ESTALE); err = fuse_lookup_name(child_inode->i_sb, get_node_id(child_inode), @@ -1134,44 +1134,44 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args, ra_pages = arg->max_readahead / PAGE_SIZE; if (flags & FUSE_ASYNC_READ) - fc->async_read = 1; + fc->flags.async_read = 1; if (!(flags & FUSE_POSIX_LOCKS)) - fc->no_lock = 1; + fc->flags.no_lock = 1; if (arg->minor >= 17) { if (!(flags & FUSE_FLOCK_LOCKS)) - fc->no_flock = 1; + fc->flags.no_flock = 1; } else { if (!(flags & FUSE_POSIX_LOCKS)) - fc->no_flock = 1; + fc->flags.no_flock = 1; } if (flags & FUSE_ATOMIC_O_TRUNC) - fc->atomic_o_trunc = 1; + fc->flags.atomic_o_trunc = 1; if (arg->minor >= 9) { /* LOOKUP has dependency on proto version */ if (flags & FUSE_EXPORT_SUPPORT) - fc->export_support = 1; + fc->flags.export_support = 1; } if (flags & FUSE_BIG_WRITES) - fc->big_writes = 1; + fc->flags.big_writes = 1; if (flags & FUSE_DONT_MASK) fc->dont_mask = 1; if (flags & FUSE_AUTO_INVAL_DATA) - fc->auto_inval_data = 1; + fc->flags.auto_inval_data = 1; else if (flags & FUSE_EXPLICIT_INVAL_DATA) - fc->explicit_inval_data = 1; + fc->flags.explicit_inval_data = 1; if (flags & FUSE_DO_READDIRPLUS) { - fc->do_readdirplus = 1; + fc->flags.do_readdirplus = 1; if (flags & FUSE_READDIRPLUS_AUTO) - fc->readdirplus_auto = 1; + fc->flags.readdirplus_auto = 1; } if (flags & FUSE_ASYNC_DIO) - fc->async_dio = 1; + fc->flags.async_dio = 1; if (flags & FUSE_WRITEBACK_CACHE) - fc->writeback_cache = 1; + fc->flags.writeback_cache = 1; if (flags & FUSE_PARALLEL_DIROPS) - fc->parallel_dirops = 1; + fc->flags.parallel_dirops = 1; if (flags & FUSE_HANDLE_KILLPRIV) - fc->handle_killpriv = 1; + fc->flags.handle_killpriv = 1; if (arg->time_gran && arg->time_gran <= 1000000000) fm->sb->s_time_gran = arg->time_gran; if ((flags & FUSE_POSIX_ACL)) { @@ -1179,7 +1179,7 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args, fc->posix_acl = 1; } if (flags & FUSE_CACHE_SYMLINKS) - fc->cache_symlinks = 1; + fc->flags.cache_symlinks = 1; if (flags & FUSE_ABORT_ERROR) fc->abort_err = 1; if (flags & FUSE_MAX_PAGES) { @@ -1200,15 +1200,15 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args, fm->sb->s_flags |= SB_NOSEC; } if (flags & FUSE_SETXATTR_EXT) - fc->setxattr_ext = 1; + fc->flags.setxattr_ext = 1; if (flags & FUSE_SECURITY_CTX) fc->init_security = 1; if (flags & FUSE_CREATE_SUPP_GROUP) fc->create_supp_group = 1; } else { ra_pages = fc->max_read / PAGE_SIZE; - fc->no_lock = 1; - fc->no_flock = 1; + fc->flags.no_lock = 1; + fc->flags.no_flock = 1; } fm->sb->s_bdi->ra_pages = diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c index dc603479b30e..2a5bfb52ebf3 100644 --- a/fs/fuse/readdir.c +++ b/fs/fuse/readdir.c @@ -18,9 +18,9 @@ static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx) struct fuse_conn *fc = get_fuse_conn(dir); struct fuse_inode *fi = get_fuse_inode(dir); - if (!fc->do_readdirplus) + if (!fc->flags.do_readdirplus) return false; - if (!fc->readdirplus_auto) + if (!fc->flags.readdirplus_auto) return true; if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state)) return true; @@ -246,7 +246,7 @@ static int fuse_direntplus_link(struct file *file, if (IS_ERR(dentry)) return PTR_ERR(dentry); } - if (fc->readdirplus_auto) + if (fc->flags.readdirplus_auto) set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state); fuse_change_entry_timeout(dentry, o); @@ -455,7 +455,7 @@ static int fuse_readdir_cached(struct file *file, struct dir_context *ctx) * We're just about to start reading into the cache or reading the * cache; both cases require an up-to-date mtime value. */ - if (!ctx->pos && fc->auto_inval_data) { + if (!ctx->pos && fc->flags.auto_inval_data) { int err = fuse_update_attributes(inode, file, STATX_MTIME); if (err) diff --git a/fs/fuse/xattr.c b/fs/fuse/xattr.c index 49c01559580f..5d8603f9c355 100644 --- a/fs/fuse/xattr.c +++ b/fs/fuse/xattr.c @@ -19,7 +19,7 @@ int fuse_setxattr(struct inode *inode, const char *name, const void *value, struct fuse_setxattr_in inarg; int err; - if (fm->fc->no_setxattr) + if (fm->fc->flags.no_setxattr) return -EOPNOTSUPP; memset(&inarg, 0, sizeof(inarg)); @@ -30,7 +30,7 @@ int fuse_setxattr(struct inode *inode, const char *name, const void *value, args.opcode = FUSE_SETXATTR; args.nodeid = get_node_id(inode); args.in_numargs = 3; - args.in_args[0].size = fm->fc->setxattr_ext ? + args.in_args[0].size = fm->fc->flags.setxattr_ext ? sizeof(inarg) : FUSE_COMPAT_SETXATTR_IN_SIZE; args.in_args[0].value = &inarg; args.in_args[1].size = strlen(name) + 1; @@ -39,7 +39,7 @@ int fuse_setxattr(struct inode *inode, const char *name, const void *value, args.in_args[2].value = value; err = fuse_simple_request(fm, &args); if (err == -ENOSYS) { - fm->fc->no_setxattr = 1; + fm->fc->flags.no_setxattr = 1; err = -EOPNOTSUPP; } if (!err) @@ -57,7 +57,7 @@ ssize_t fuse_getxattr(struct inode *inode, const char *name, void *value, struct fuse_getxattr_out outarg; ssize_t ret; - if (fm->fc->no_getxattr) + if (fm->fc->flags.no_getxattr) return -EOPNOTSUPP; memset(&inarg, 0, sizeof(inarg)); @@ -83,7 +83,7 @@ ssize_t fuse_getxattr(struct inode *inode, const char *name, void *value, if (!ret && !size) ret = min_t(ssize_t, outarg.size, XATTR_SIZE_MAX); if (ret == -ENOSYS) { - fm->fc->no_getxattr = 1; + fm->fc->flags.no_getxattr = 1; ret = -EOPNOTSUPP; } return ret; @@ -121,7 +121,7 @@ ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size) if (!fuse_allow_current_process(fm->fc)) return -EACCES; - if (fm->fc->no_listxattr) + if (fm->fc->flags.no_listxattr) return -EOPNOTSUPP; memset(&inarg, 0, sizeof(inarg)); @@ -147,7 +147,7 @@ ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size) if (ret > 0 && size) ret = fuse_verify_xattr_list(list, ret); if (ret == -ENOSYS) { - fm->fc->no_listxattr = 1; + fm->fc->flags.no_listxattr = 1; ret = -EOPNOTSUPP; } return ret; @@ -159,7 +159,7 @@ int fuse_removexattr(struct inode *inode, const char *name) FUSE_ARGS(args); int err; - if (fm->fc->no_removexattr) + if (fm->fc->flags.no_removexattr) return -EOPNOTSUPP; args.opcode = FUSE_REMOVEXATTR; @@ -169,7 +169,7 @@ int fuse_removexattr(struct inode *inode, const char *name) args.in_args[0].value = name; err = fuse_simple_request(fm, &args); if (err == -ENOSYS) { - fm->fc->no_removexattr = 1; + fm->fc->flags.no_removexattr = 1; err = -EOPNOTSUPP; } if (!err) From patchwork Mon Apr 3 14:45:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Aleksandr Mikhalitsyn X-Patchwork-Id: 13198275 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6109EC76196 for ; Mon, 3 Apr 2023 14:47:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234084AbjDCOrx (ORCPT ); Mon, 3 Apr 2023 10:47:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37662 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234083AbjDCOr0 (ORCPT ); Mon, 3 Apr 2023 10:47:26 -0400 Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 62B04280FB for ; Mon, 3 Apr 2023 07:46:45 -0700 (PDT) Received: from mail-ed1-f72.google.com (mail-ed1-f72.google.com [209.85.208.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 299193F239 for ; Mon, 3 Apr 2023 14:45:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1680533146; bh=Lg0DTuk088FU5MRineNk5kP+9dFQFrGExo9YX6St3wI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=BjLhyWdfkTnKmj4xx6BMdQOoHSC4VoqMjE9pmJlJo97uLN6jMV5VWNym5onCmyYNj z4obQI+pOUGrykDDlI7FTcOaVl3caXHf8ZgjpXLz4cC+cqt20AIrUhxQmfpYQoxuxZ e5MAum6xh2KVwCNIlYBHELNYt1OD1bQrsjr+/XyPBgc+zYMMmvp4FBFXjNWUGJGj6I pDi6b8pt+B7BMS8yVWmX2WwtW3JDB1TpfU0I367N1ukHxDD40ECL79KjQv1V9m0p5K cb1Q0Od14RaJp9w6qqPvtEqkojFRFLBnqgZbb9M1zR/NK3x9QIkLY7X6ivnLwQDItg tuvym8chooCjQ== Received: by mail-ed1-f72.google.com with SMTP id a40-20020a509eab000000b005024c025bf4so29334008edf.14 for ; Mon, 03 Apr 2023 07:45:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680533145; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Lg0DTuk088FU5MRineNk5kP+9dFQFrGExo9YX6St3wI=; b=o3lI5/eEu0G4VQqRtIghyB/Ytkq7UVyb0wOY22WzJTqLee8BWeWWVJLQq9hAwfv89p WAB6nVTf242ZrchmjsVW3xaftuJtSYfLdhbsYVaNte0ci7LWG344zhUQ/3qTERYp4NPF ZWP6lcKbf+x7HA8Sr2OOVi439FEXXh4tKd2eL5U5lhpnzlPyaK5+fGduKY/+Q7yP9R/r 0Py8Ry9JilxCYb71EGwk/MHHhYEzI3suZwrMYN0Iz70iV1nSqNk4S/NnBcMqfeFkrtBj mkRb+gX72j8DhLEk7bdi7vd3o7hWnYjGJFLi/SvbsVzxVudXD6KSTfw3l9hPNzohlwy7 ZHeg== X-Gm-Message-State: AAQBX9dQf0CLZzjRhTc8qCWp7oQ3MsB+DIpRTf0jf9T5FT5YRCzeECUJ iitUwdaDW3LhpvVFNKSj/ibef/4JY81BmaoZtvYbQtFfHMhUIv2GZjxAimSsXo3NesGQXHEK7IA po69qgRrokDLFKq0CpRWmgFT+gCDGsQwME2Ey2mj8zMebiN7Oo5Y= X-Received: by 2002:a05:6402:1356:b0:4fb:1c02:8750 with SMTP id y22-20020a056402135600b004fb1c028750mr36144456edw.23.1680533145465; Mon, 03 Apr 2023 07:45:45 -0700 (PDT) X-Google-Smtp-Source: AKy350Zq9NOfsIGTkMXthV8xuxQjLZrHkEdhyDX0z3mfVu+XCOoBZ37ngbNJ94dYxEkf7R02tDRqxg== X-Received: by 2002:a05:6402:1356:b0:4fb:1c02:8750 with SMTP id y22-20020a056402135600b004fb1c028750mr36144442edw.23.1680533145306; Mon, 03 Apr 2023 07:45:45 -0700 (PDT) Received: from amikhalitsyn.. (ip5f5bd076.dynamic.kabel-deutschland.de. [95.91.208.118]) by smtp.gmail.com with ESMTPSA id i5-20020a50d745000000b004fa19f5ba99sm4735804edj.79.2023.04.03.07.45.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Apr 2023 07:45:44 -0700 (PDT) From: Alexander Mikhalitsyn To: mszeredi@redhat.com Cc: flyingpeng@tencent.com, Alexander Mikhalitsyn , Al Viro , Amir Goldstein , =?utf-8?q?St=C3=A9phane_Graber?= , Seth Forshee , Christian Brauner , Andrei Vagin , Pavel Tikhomirov , Bernd Schubert , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, criu@openvz.org Subject: [RFC PATCH v2 6/9] fuse: take fuse connection generation into account Date: Mon, 3 Apr 2023 16:45:14 +0200 Message-Id: <20230403144517.347517-7-aleksandr.mikhalitsyn@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> References: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org - modify dentry revalidation algorithm to check inode/connection generations. If them are not equal then perform revalidation. remark: during forced dentry revalidation we are sending FUSE_LOOKUP request to the userspace daemon and if it return the same inode after lookup then we can "upgrade" inode connection generation without invalidating it. - don't send FUSE_FSYNC, FUSE_RELEASE, etc requests to the userspace daemon about stale inodes (this can confuse libfuse) Cc: Miklos Szeredi Cc: Al Viro Cc: Amir Goldstein Cc: Stéphane Graber Cc: Seth Forshee Cc: Christian Brauner Cc: Andrei Vagin Cc: Pavel Tikhomirov Cc: Bernd Schubert Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: criu@openvz.org Signed-off-by: Alexander Mikhalitsyn --- fs/fuse/dir.c | 4 +++- fs/fuse/file.c | 13 ++++++++++--- fs/fuse/fuse_i.h | 3 ++- fs/fuse/inode.c | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index bfbe59e8fce2..d0fdf7289d56 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -213,7 +213,8 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) inode = d_inode_rcu(entry); if (inode && fuse_is_bad(inode)) goto invalid; - else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) || + else if ((inode && fuse_stale_inode_conn(inode)) || + time_before64(fuse_dentry_time(entry), get_jiffies_64()) || (flags & (LOOKUP_EXCL | LOOKUP_REVAL | LOOKUP_RENAME_TARGET))) { struct fuse_entry_out outarg; FUSE_ARGS(args); @@ -255,6 +256,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) } spin_lock(&fi->lock); fi->nlookup++; + fi->conn_gen = READ_ONCE(get_fuse_conn(inode)->conn_gen); spin_unlock(&fi->lock); } kfree(forget); diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 742f90b4e638..b977d087b925 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -111,8 +111,14 @@ static void fuse_file_put(struct fuse_file *ff, bool sync, bool isdir) if (refcount_dec_and_test(&ff->count)) { struct fuse_args *args = &ff->release_args->args; - if (isdir ? ff->fm->fc->flags.no_opendir : ff->fm->fc->flags.no_open) { - /* Do nothing when client does not implement 'open' */ + if (fuse_stale_ff(ff) || + (isdir ? ff->fm->fc->flags.no_opendir : ff->fm->fc->flags.no_open)) { + /* + * Do nothing when client does not implement 'open' OR + * file descriptor was opened in the previous connection generation, + * so, current daemon likely not aware of this FD, let's just skip + * FUSE_RELEASE(DIR) request. + */ fuse_release_end(ff->fm, args, 0); } else if (sync) { fuse_simple_request(ff->fm, args); @@ -598,9 +604,10 @@ static int fuse_fsync(struct file *file, loff_t start, loff_t end, { struct inode *inode = file->f_mapping->host; struct fuse_conn *fc = get_fuse_conn(inode); + struct fuse_file *ff = file->private_data; int err; - if (fuse_is_bad(inode)) + if (fuse_stale_ff(ff) || fuse_is_bad(inode)) return -EIO; inode_lock(inode); diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 943d5011dfa0..90c5b3459864 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -957,7 +957,8 @@ static inline bool fuse_stale_inode(const struct inode *inode, int generation, struct fuse_attr *attr) { return inode->i_generation != generation || - inode_wrong_type(inode, attr->mode); + inode_wrong_type(inode, attr->mode) || + fuse_stale_inode_conn(inode); } static inline void fuse_make_bad(struct inode *inode) diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 389bea6e4a69..26a4149f6db7 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -124,7 +124,7 @@ static void fuse_evict_inode(struct inode *inode) fuse_dax_inode_cleanup(inode); if (fi->nlookup) { fuse_queue_forget(fc, fi->forget, fi->nodeid, - fi->nlookup, false); + fi->nlookup, fuse_stale_inode_conn(inode)); fi->forget = NULL; } } From patchwork Mon Apr 3 14:45:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Aleksandr Mikhalitsyn X-Patchwork-Id: 13198277 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7D0DFC76188 for ; Mon, 3 Apr 2023 14:48:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234029AbjDCOsO (ORCPT ); Mon, 3 Apr 2023 10:48:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38108 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234088AbjDCOra (ORCPT ); Mon, 3 Apr 2023 10:47:30 -0400 Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E977628EA4 for ; Mon, 3 Apr 2023 07:46:47 -0700 (PDT) Received: from mail-ed1-f71.google.com (mail-ed1-f71.google.com [209.85.208.71]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id B97AB3F858 for ; Mon, 3 Apr 2023 14:45:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1680533147; bh=N1lNLcfnab/Xak3vE1BXdEngtUghqVUaWAQgAOaQ90I=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=uUMWMBDZx58VKlTxjaA0MiHajAjIifwVyGwQ+GhfBSNwqIa2tREtUaK5l4L2ZLXWb 0r7d8LcT085bQHGfsPYzgc9p3iB/52TKqALysFvhC3kpziM3PvO9+v0Is68KVKkRHR 8MH6KXwrxuAKIe+QZQmL53XCZEFunP+gy7hi7lU8o+v+666a/MAGF9lDHnywkT3pdN +vl0ybx9ukSKQqL4LShkvnWX2S4UPnmZy6eVtwo4dho0DKHA4lAinAV3dMGvkN2SfW /oxuZ+s33OTR3/6lkK/CdOpiH8WxlrZqSLeTYjk6oXaUSe/lucHKRB17dVU2awuXli KGsmQjA8VOyfQ== Received: by mail-ed1-f71.google.com with SMTP id b6-20020a509f06000000b005029d95390aso5090074edf.2 for ; Mon, 03 Apr 2023 07:45:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680533147; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=N1lNLcfnab/Xak3vE1BXdEngtUghqVUaWAQgAOaQ90I=; b=5ysmgUULo1eQxhQpofjVvUcbBitUwXOT2Y+OHHYzLC9n+zQGGxsDhL6n+U1lfgHeIv Sv/vgdr8Y+7hsbhvDhVc/13CClkOZIDqoMc2NbnvZN5FKF9qlAJkgF9aDSuERqBrQX/W R+Gc7tl5bjioW4ArSFrDHYgxBf2i9KehEGwoQwj2NJdpR3TNxUCaxQHrYRSPGTutugbp MJfSM8hYZyBRnXUpjeqzyOmIjaYyzbDBGnyHySV1FtRDdvIsR/xzjzrnTZjPEqgjFNyX Ynu/A4QOjCYLpR4l58CHj+2AZwTKst96Uf6EtzvENFkfOLYkI3eMqRuctNBs2Fk0JRpz rJ1A== X-Gm-Message-State: AAQBX9eFAzhzd7jmtFhwxLoLKzK+FMUEAtbWhH1R498Dnvy5wtA8z2M6 2YF3s+7LnLg9f/Kf+AmtdL4JGQah9MsO1hx/lWhnLiHbjS+QZDZHD8XTb/Zq13Jx5BKW0VSOaoL seOWm2wqCOeQNXQpecgbtmG10QpZrfGzVNPR6kVE6vZE= X-Received: by 2002:a17:907:d487:b0:93f:fbe:c388 with SMTP id vj7-20020a170907d48700b0093f0fbec388mr34735183ejc.27.1680533147537; Mon, 03 Apr 2023 07:45:47 -0700 (PDT) X-Google-Smtp-Source: AKy350bcO0nfWshaXRLgIpS2eZis0PuIuWt4U+aoRv7PYgiFEjJZmPa6l00ijPySY3vFOAzJmjYOZQ== X-Received: by 2002:a17:907:d487:b0:93f:fbe:c388 with SMTP id vj7-20020a170907d48700b0093f0fbec388mr34735154ejc.27.1680533147248; Mon, 03 Apr 2023 07:45:47 -0700 (PDT) Received: from amikhalitsyn.. (ip5f5bd076.dynamic.kabel-deutschland.de. [95.91.208.118]) by smtp.gmail.com with ESMTPSA id i5-20020a50d745000000b004fa19f5ba99sm4735804edj.79.2023.04.03.07.45.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Apr 2023 07:45:46 -0700 (PDT) From: Alexander Mikhalitsyn To: mszeredi@redhat.com Cc: flyingpeng@tencent.com, Alexander Mikhalitsyn , Al Viro , Amir Goldstein , =?utf-8?q?St=C3=A9phane_Graber?= , Seth Forshee , Christian Brauner , Andrei Vagin , Pavel Tikhomirov , Bernd Schubert , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, criu@openvz.org Subject: [RFC PATCH v2 7/9] fuse: add fuse device ioctl(FUSE_DEV_IOC_REINIT) Date: Mon, 3 Apr 2023 16:45:15 +0200 Message-Id: <20230403144517.347517-8-aleksandr.mikhalitsyn@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> References: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org This ioctl aborts fuse connection and then reinitializes it, sends FUSE_INIT request to allow a new userspace daemon to pick up the fuse connection. Cc: Miklos Szeredi Cc: Al Viro Cc: Amir Goldstein Cc: Stéphane Graber Cc: Seth Forshee Cc: Christian Brauner Cc: Andrei Vagin Cc: Pavel Tikhomirov Cc: Bernd Schubert Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: criu@openvz.org Signed-off-by: Alexander Mikhalitsyn --- fs/fuse/dev.c | 152 ++++++++++++++++++++++++++++++++++++++ fs/fuse/fuse_i.h | 3 + include/uapi/linux/fuse.h | 1 + 3 files changed, 156 insertions(+) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index b4501a10c379..93a457c90b49 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -2187,6 +2187,132 @@ void fuse_abort_conn(struct fuse_conn *fc) } EXPORT_SYMBOL_GPL(fuse_abort_conn); +static int fuse_reinit_conn(struct fuse_conn *fc) +{ + struct fuse_iqueue *fiq = &fc->iq; + struct fuse_dev *fud; + unsigned int i; + + spin_lock(&fc->lock); + if (fc->reinit_in_progress) { + spin_unlock(&fc->lock); + return -EBUSY; + } + + if (fc->conn_gen + 1 < fc->conn_gen) { + spin_unlock(&fc->lock); + return -EOVERFLOW; + } + + fc->reinit_in_progress = true; + spin_unlock(&fc->lock); + + /* + * Unsets fc->connected and fiq->connected and + * ensures that no new requests can be queued + */ + fuse_abort_conn(fc); + fuse_wait_aborted(fc); + + spin_lock(&fc->lock); + if (fc->connected) { + fc->reinit_in_progress = false; + spin_unlock(&fc->lock); + return -EINVAL; + } + + fc->conn_gen++; + + spin_lock(&fiq->lock); + if (request_pending(fiq) || fiq->forget_list_tail != &fiq->forget_list_head) { + spin_unlock(&fiq->lock); + fc->reinit_in_progress = false; + spin_unlock(&fc->lock); + return -EINVAL; + } + + if (&fuse_dev_fiq_ops != fiq->ops) { + spin_unlock(&fiq->lock); + fc->reinit_in_progress = false; + spin_unlock(&fc->lock); + return -EOPNOTSUPP; + } + + fiq->connected = 1; + spin_unlock(&fiq->lock); + + spin_lock(&fc->bg_lock); + if (!list_empty(&fc->bg_queue)) { + spin_unlock(&fc->bg_lock); + fc->reinit_in_progress = false; + spin_unlock(&fc->lock); + return -EINVAL; + } + + fc->blocked = 0; + fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND; + spin_unlock(&fc->bg_lock); + + list_for_each_entry(fud, &fc->devices, entry) { + struct fuse_pqueue *fpq = &fud->pq; + + spin_lock(&fpq->lock); + if (!list_empty(&fpq->io)) { + spin_unlock(&fpq->lock); + fc->reinit_in_progress = false; + spin_unlock(&fc->lock); + return -EINVAL; + } + + for (i = 0; i < FUSE_PQ_HASH_SIZE; i++) { + if (!list_empty(&fpq->processing[i])) { + spin_unlock(&fpq->lock); + fc->reinit_in_progress = false; + spin_unlock(&fc->lock); + return -EINVAL; + } + } + + fpq->connected = 1; + spin_unlock(&fpq->lock); + } + + fuse_set_initialized(fc); + + /* Background queuing checks fc->connected under bg_lock */ + spin_lock(&fc->bg_lock); + fc->connected = 1; + spin_unlock(&fc->bg_lock); + + fc->aborted = false; + fc->abort_err = 0; + + /* nullify all the flags */ + memset(&fc->flags, 0, sizeof(struct fuse_conn_flags)); + + spin_unlock(&fc->lock); + + down_read(&fc->killsb); + if (!list_empty(&fc->mounts)) { + struct fuse_mount *fm; + + fm = list_first_entry(&fc->mounts, struct fuse_mount, fc_entry); + if (!fm->sb) { + up_read(&fc->killsb); + return -EINVAL; + } + + fuse_send_init(fm); + } + up_read(&fc->killsb); + + spin_lock(&fc->lock); + fc->reinit_in_progress = false; + spin_unlock(&fc->lock); + + return 0; +} + void fuse_wait_aborted(struct fuse_conn *fc) { /* matches implicit memory barrier in fuse_drop_waiting() */ @@ -2282,6 +2408,32 @@ static long fuse_dev_ioctl(struct file *file, unsigned int cmd, } } break; + case FUSE_DEV_IOC_REINIT: + struct fuse_conn *fc; + + if (!checkpoint_restore_ns_capable(file->f_cred->user_ns)) + return -EPERM; + + res = -EINVAL; + fud = fuse_get_dev(file); + + /* + * Only fuse mounts with an already initialized fuse + * connection are supported + */ + if (file->f_op == &fuse_dev_operations && fud) { + mutex_lock(&fuse_mutex); + fc = fud->fc; + if (fc) + fc = fuse_conn_get(fc); + mutex_unlock(&fuse_mutex); + + if (fc) { + res = fuse_reinit_conn(fc); + fuse_conn_put(fc); + } + } + break; default: res = -ENOTTY; break; diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 90c5b3459864..8f2c0f969f6f 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -752,6 +752,9 @@ struct fuse_conn { /** Connection aborted via sysfs */ bool aborted; + /** Connection reinit in progress */ + bool reinit_in_progress; + /** Connection failed (version mismatch). Cannot race with setting other bitfields since it is only set once in INIT reply, before any other request, and never cleared */ diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h index b3fcab13fcd3..325da23431ef 100644 --- a/include/uapi/linux/fuse.h +++ b/include/uapi/linux/fuse.h @@ -992,6 +992,7 @@ struct fuse_notify_retrieve_in { /* Device ioctls: */ #define FUSE_DEV_IOC_MAGIC 229 #define FUSE_DEV_IOC_CLONE _IOR(FUSE_DEV_IOC_MAGIC, 0, uint32_t) +#define FUSE_DEV_IOC_REINIT _IO(FUSE_DEV_IOC_MAGIC, 0) struct fuse_lseek_in { uint64_t fh; From patchwork Mon Apr 3 14:45:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Aleksandr Mikhalitsyn X-Patchwork-Id: 13198273 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E04B6C76188 for ; Mon, 3 Apr 2023 14:47:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234126AbjDCOro (ORCPT ); Mon, 3 Apr 2023 10:47:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38410 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234017AbjDCOrX (ORCPT ); Mon, 3 Apr 2023 10:47:23 -0400 Received: from smtp-relay-internal-0.canonical.com (smtp-relay-internal-0.canonical.com [185.125.188.122]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2314A29BE3 for ; Mon, 3 Apr 2023 07:46:44 -0700 (PDT) Received: from mail-ed1-f72.google.com (mail-ed1-f72.google.com [209.85.208.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 2B07D3F4B8 for ; Mon, 3 Apr 2023 14:45:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1680533149; bh=CML0MX+E6RHRMEZDuKLkjuHXCZn0KNZeg1m8eYp9u4Q=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=KJU2wC70YTqhIkJ0oKQyOvBT0X6f/kwgBN+qDmjR4/bU0G4U3HE1nJZ77E8t2dP/x IuzVQRZMR+pROW0o2q004VdkvBkY4risPmwSag0J39tKHZM/0Z8J9KqlNXnU1/Ir6C ry12NDLpB0QRecf0dDwYqb7Ooev7LyBRJmUZdkUt/+80FSagWRdj1ipNMWpeig3rjr J1WeE/45oRMUNENwmLu2KsGRY+s6W3kf2hcjHefb6h1o+KEhhFkeWAG1UfFYtyQpc6 yRPZfZw/S9/CxFJ+rBS3BpdJ+ByNV9Dv9Io9PQGCBAlgrd9WtALrDO8RcNvAD6Mxmr s/E4Kpsw7QQTw== Received: by mail-ed1-f72.google.com with SMTP id t26-20020a50d71a000000b005003c5087caso41189327edi.1 for ; Mon, 03 Apr 2023 07:45:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680533149; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CML0MX+E6RHRMEZDuKLkjuHXCZn0KNZeg1m8eYp9u4Q=; b=udX92e7aYIf7uRs3D9MfGvGJa4eBEpJy6u3nnCM5Y/281KbJxY/jtzMfi4Dv1WfWUX NjoUCXvrxyY8lx9f5dhPTmJhOn4mNa4uknO1j+81Ul4x1Mp2KzKH2tX9BZS3qGFWV8D8 cHzn5sQlIn7LuxM/HmLCmFtEDrgdKvIrTj44ipU9iG664DA/gtWtP2Sp7KV1ZHaOJqWN V+K9Fo2OzqWBObguZCrajV5w/B8z02kcx9+aAKGeKQnEqJoMttg4Hr3IFduSBZvZqfvv Vmro97F9iuhKHy++uE8kUixkoeBIQ2VNtwPommCBKeMCv7UQsRlbK46uxIbfeQ9I/Cuv SatQ== X-Gm-Message-State: AAQBX9ckvweqnXSbM2qE8ma6MVaz3fohueaVplQIN6dg5frmT/efrslq Pz3wvtwPja97dOUR3XXCsLpwIb2kXlnNOo9dQXyndmSjesPYOmNXLbUv0UXMLXBo/eCqEz9awQm TS3lYxa3jsgkBDdclelRygpDqlFG1fhB8VFCeAheIJsc= X-Received: by 2002:a05:6402:215:b0:502:9c52:447f with SMTP id t21-20020a056402021500b005029c52447fmr4105697edv.17.1680533148977; Mon, 03 Apr 2023 07:45:48 -0700 (PDT) X-Google-Smtp-Source: AKy350btyKXZRMoX7/M0+6dUdIKd3K9ydJ1W9baKVdPNFK7DJGhr7naoKrIONWiKDmdxp0+zXVLfPg== X-Received: by 2002:a05:6402:215:b0:502:9c52:447f with SMTP id t21-20020a056402021500b005029c52447fmr4105680edv.17.1680533148816; Mon, 03 Apr 2023 07:45:48 -0700 (PDT) Received: from amikhalitsyn.. (ip5f5bd076.dynamic.kabel-deutschland.de. [95.91.208.118]) by smtp.gmail.com with ESMTPSA id i5-20020a50d745000000b004fa19f5ba99sm4735804edj.79.2023.04.03.07.45.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Apr 2023 07:45:48 -0700 (PDT) From: Alexander Mikhalitsyn To: mszeredi@redhat.com Cc: flyingpeng@tencent.com, Alexander Mikhalitsyn , Al Viro , Amir Goldstein , =?utf-8?q?St=C3=A9phane_Graber?= , Seth Forshee , Christian Brauner , Andrei Vagin , Pavel Tikhomirov , Bernd Schubert , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, criu@openvz.org Subject: [RFC PATCH v2 8/9] namespace: add sb_revalidate_bindmounts helper Date: Mon, 3 Apr 2023 16:45:16 +0200 Message-Id: <20230403144517.347517-9-aleksandr.mikhalitsyn@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> References: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Useful if for some reason bindmounts root dentries get invalidated but it's needed to revalidate existing bindmounts without remounting. Cc: Miklos Szeredi Cc: Al Viro Cc: Amir Goldstein Cc: Stéphane Graber Cc: Seth Forshee Cc: Christian Brauner Cc: Andrei Vagin Cc: Pavel Tikhomirov Cc: Bernd Schubert Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: criu@openvz.org Signed-off-by: Alexander Mikhalitsyn --- fs/namespace.c | 90 +++++++++++++++++++++++++++++++++++ include/linux/mnt_namespace.h | 3 ++ 2 files changed, 93 insertions(+) diff --git a/fs/namespace.c b/fs/namespace.c index bc0f15257b49..b74d00d6abb0 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -568,6 +568,96 @@ static int mnt_make_readonly(struct mount *mnt) return ret; } +struct bind_mount_list_item { + struct list_head list; + struct vfsmount *mnt; +}; + +/* + * sb_revalidate_bindmounts - Relookup/reset bindmounts root dentries + * + * Useful if for some reason bindmount root dentries get invalidated + * but it's needed to revalidate existing bindmounts without remounting. + */ +int sb_revalidate_bindmounts(struct super_block *sb) +{ + struct mount *mnt; + struct bind_mount_list_item *bmnt, *next; + int err = 0; + struct vfsmount *root_mnt = NULL; + LIST_HEAD(mnt_to_update); + char *buf; + + buf = (char *) __get_free_page(GFP_KERNEL); + if (!buf) + return -ENOMEM; + + lock_mount_hash(); + list_for_each_entry(mnt, &sb->s_mounts, mnt_instance) { + /* we only want to touch bindmounts */ + if (mnt->mnt.mnt_root == sb->s_root) { + if (!root_mnt) + root_mnt = mntget(&mnt->mnt); + + continue; + } + + bmnt = kzalloc(sizeof(struct bind_mount_list_item), GFP_NOWAIT | __GFP_NOWARN); + if (!bmnt) { + err = -ENOMEM; + goto exit; + } + + bmnt->mnt = mntget(&mnt->mnt); + list_add_tail(&bmnt->list, &mnt_to_update); + } + unlock_mount_hash(); + + /* TODO: get rid of this limitation */ + if (!root_mnt) { + err = -ENOENT; + goto exit; + } + + list_for_each_entry_safe(bmnt, next, &mnt_to_update, list) { + struct vfsmount *cur_mnt = bmnt->mnt; + struct path path; + struct dentry *old_root; + char *p; + + p = dentry_path(cur_mnt->mnt_root, buf, PAGE_SIZE); + if (IS_ERR(p)) + goto exit; + + /* TODO: are these lookup flags fully safe and correct? */ + err = vfs_path_lookup(root_mnt->mnt_root, root_mnt, + p, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT|LOOKUP_REVAL, &path); + if (err) + goto exit; + + /* replace bindmount root dentry */ + lock_mount_hash(); + old_root = cur_mnt->mnt_root; + cur_mnt->mnt_root = dget(path.dentry); + dput(old_root); + unlock_mount_hash(); + + path_put(&path); + } + +exit: + free_page((unsigned long) buf); + mntput(root_mnt); + list_for_each_entry_safe(bmnt, next, &mnt_to_update, list) { + list_del(&bmnt->list); + mntput(bmnt->mnt); + kfree(bmnt); + } + + return err; +} +EXPORT_SYMBOL_GPL(sb_revalidate_bindmounts); + int sb_prepare_remount_readonly(struct super_block *sb) { struct mount *mnt; diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h index 8f882f5881e8..20ac29e702f5 100644 --- a/include/linux/mnt_namespace.h +++ b/include/linux/mnt_namespace.h @@ -3,6 +3,7 @@ #define _NAMESPACE_H_ #ifdef __KERNEL__ +struct super_block; struct mnt_namespace; struct fs_struct; struct user_namespace; @@ -13,6 +14,8 @@ extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *, extern void put_mnt_ns(struct mnt_namespace *ns); extern struct ns_common *from_mnt_ns(struct mnt_namespace *); +extern int sb_revalidate_bindmounts(struct super_block *sb); + extern const struct file_operations proc_mounts_operations; extern const struct file_operations proc_mountinfo_operations; extern const struct file_operations proc_mountstats_operations; From patchwork Mon Apr 3 14:45:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Aleksandr Mikhalitsyn X-Patchwork-Id: 13198276 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7C580C76196 for ; Mon, 3 Apr 2023 14:48:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234156AbjDCOsN (ORCPT ); Mon, 3 Apr 2023 10:48:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39028 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234091AbjDCOra (ORCPT ); Mon, 3 Apr 2023 10:47:30 -0400 Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F1C3529BE6 for ; Mon, 3 Apr 2023 07:46:47 -0700 (PDT) Received: from mail-ed1-f71.google.com (mail-ed1-f71.google.com [209.85.208.71]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id B9B853F860 for ; Mon, 3 Apr 2023 14:45:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1680533150; bh=EXiQokygEgtdFby6V0DaIlICChGvv1djpoKsAB/p2vA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=AB7oqhJJEk/EGurhNt2yIxzjHn5eyb7aPxGFZLyNh/JJ5TIJ/o4Mpn+GYyFayH+Is 2MQvo/CTcf8628ZHsqquNTtIKyIVfLb7oOKL+e38ZY5/6QHfLQKJVFfoijidG+DJoU TFt6JwHlUlUBgU71s4lkJm8IqcmjQ6oiVtk81r1EQ9TIa9c+Ap11O/cVvSUSxuvTB4 45jn7CaCNzsH/m7uiKDgQKkQEsXAAsavselvXNs+Ld8YTdnybHcd/E/gADXam4xus/ yasVU2oqKseuwYqN8ZRdtuDP7JN9steHnWLS5OmrjOSnFSqu7UYq3Nwcw0LOzlTPJR GWa/1DZaIW4Xw== Received: by mail-ed1-f71.google.com with SMTP id b1-20020aa7dc01000000b004ad062fee5eso41221405edu.17 for ; Mon, 03 Apr 2023 07:45:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680533150; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=EXiQokygEgtdFby6V0DaIlICChGvv1djpoKsAB/p2vA=; b=MTZatYrKJhHpctlFuN78J+/754fURjruVMHcV5v0ce/FUzNF/H8qnLQ4vsfGsQDYHg fqsFwUzDpXinDSXXqOK3iJd+6Spm+6vnSBTzr+pW9lEvi35N3yLQ7Qsjt6w3NUgRa0Bj lQPGfFGizXrx3pbZRq+Q7sTIAQjk7iDR/7W4eGFy2hBTBfVzMNrmCcZz+LmIVu1b6x9/ AflC6vMDw0yFUSgntvGS89YBL4u8jKoYwATen/Ze3aspwPWHsAWYjjrCc1U5H2cyAR60 OTtRqp5I7V4sPNbQyZ4EBGVQPc+V4mVEoJ9kH79PO81enBhn8Sb4CtGyTG5tc3g9QZfj Nb5w== X-Gm-Message-State: AAQBX9fstqaHJg/93G0kVbfif4KlAOGWuq9r3aemCIynd4n6hRzs3wvn XwX7Y7P5mJJC66SFlwGGEiNYTKnNuLDuJ6qYMR11A7y/gJNn1qS36Kpnlu28TqSEkwy5Zwn55Ob +svIl8t9HGhyL6LrvMlFgVWDZloLQZrlzBzXb6fA5J+k= X-Received: by 2002:a05:6402:12cc:b0:4f9:f07d:a978 with SMTP id k12-20020a05640212cc00b004f9f07da978mr32552811edx.5.1680533150585; Mon, 03 Apr 2023 07:45:50 -0700 (PDT) X-Google-Smtp-Source: AKy350YEqQM+ipb2my4c7+y9TG7BmdCKAdA3pSBQm+DjrFOBW2UBW64exk69S7plf9fVjKzWjMbAAg== X-Received: by 2002:a05:6402:12cc:b0:4f9:f07d:a978 with SMTP id k12-20020a05640212cc00b004f9f07da978mr32552802edx.5.1680533150434; Mon, 03 Apr 2023 07:45:50 -0700 (PDT) Received: from amikhalitsyn.. (ip5f5bd076.dynamic.kabel-deutschland.de. [95.91.208.118]) by smtp.gmail.com with ESMTPSA id i5-20020a50d745000000b004fa19f5ba99sm4735804edj.79.2023.04.03.07.45.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Apr 2023 07:45:50 -0700 (PDT) From: Alexander Mikhalitsyn To: mszeredi@redhat.com Cc: flyingpeng@tencent.com, Alexander Mikhalitsyn , Al Viro , Amir Goldstein , =?utf-8?q?St=C3=A9phane_Graber?= , Seth Forshee , Christian Brauner , Andrei Vagin , Pavel Tikhomirov , Bernd Schubert , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, criu@openvz.org Subject: [RFC PATCH v2 9/9] fuse: add fuse device ioctl(FUSE_DEV_IOC_BM_REVAL) Date: Mon, 3 Apr 2023 16:45:17 +0200 Message-Id: <20230403144517.347517-10-aleksandr.mikhalitsyn@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> References: <20230403144517.347517-1-aleksandr.mikhalitsyn@canonical.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org This ioctl allows to revalidate all the existing fuse bindmounts by performing relookup of all root dentries and resetting them. Useful if it's needed to make fuse bindmounts work without remounting them after fuse connection reinitialization. Cc: Miklos Szeredi Cc: Al Viro Cc: Amir Goldstein Cc: Stéphane Graber Cc: Seth Forshee Cc: Christian Brauner Cc: Andrei Vagin Cc: Pavel Tikhomirov Cc: Bernd Schubert Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: criu@openvz.org Signed-off-by: Alexander Mikhalitsyn --- fs/fuse/dev.c | 29 ++++++++++++++++++++++++++++- include/uapi/linux/fuse.h | 1 + 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 93a457c90b49..dae4d718b03a 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -2313,6 +2314,27 @@ static int fuse_reinit_conn(struct fuse_conn *fc) return 0; } +static ssize_t fuse_revalidate_bindmounts(struct fuse_conn *fc) +{ + int ret = 0; + + down_read(&fc->killsb); + if (!list_empty(&fc->mounts)) { + struct fuse_mount *fm; + + fm = list_first_entry(&fc->mounts, struct fuse_mount, fc_entry); + if (!fm->sb) { + up_read(&fc->killsb); + return -EINVAL; + } + + ret = sb_revalidate_bindmounts(fm->sb); + } + up_read(&fc->killsb); + + return ret; +} + void fuse_wait_aborted(struct fuse_conn *fc) { /* matches implicit memory barrier in fuse_drop_waiting() */ @@ -2409,6 +2431,7 @@ static long fuse_dev_ioctl(struct file *file, unsigned int cmd, } break; case FUSE_DEV_IOC_REINIT: + case FUSE_DEV_IOC_BM_REVAL: struct fuse_conn *fc; if (!checkpoint_restore_ns_capable(file->f_cred->user_ns)) @@ -2429,7 +2452,11 @@ static long fuse_dev_ioctl(struct file *file, unsigned int cmd, mutex_unlock(&fuse_mutex); if (fc) { - res = fuse_reinit_conn(fc); + if (cmd == FUSE_DEV_IOC_REINIT) + res = fuse_reinit_conn(fc); + else if (cmd == FUSE_DEV_IOC_BM_REVAL) + res = fuse_revalidate_bindmounts(fc); + fuse_conn_put(fc); } } diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h index 325da23431ef..d8d1997876d8 100644 --- a/include/uapi/linux/fuse.h +++ b/include/uapi/linux/fuse.h @@ -993,6 +993,7 @@ struct fuse_notify_retrieve_in { #define FUSE_DEV_IOC_MAGIC 229 #define FUSE_DEV_IOC_CLONE _IOR(FUSE_DEV_IOC_MAGIC, 0, uint32_t) #define FUSE_DEV_IOC_REINIT _IO(FUSE_DEV_IOC_MAGIC, 0) +#define FUSE_DEV_IOC_BM_REVAL _IO(FUSE_DEV_IOC_MAGIC, 1) struct fuse_lseek_in { uint64_t fh;