From patchwork Fri Jun 4 16:11:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kurz X-Patchwork-Id: 12300055 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 707F7C4708F for ; Fri, 4 Jun 2021 16:12:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 51CEF61405 for ; Fri, 4 Jun 2021 16:12:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231357AbhFDQOG convert rfc822-to-8bit (ORCPT ); Fri, 4 Jun 2021 12:14:06 -0400 Received: from us-smtp-delivery-44.mimecast.com ([207.211.30.44]:23005 "EHLO us-smtp-delivery-44.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230453AbhFDQOF (ORCPT ); Fri, 4 Jun 2021 12:14:05 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-441-qyATIiLGPKW1OSiO_cFJ0g-1; Fri, 04 Jun 2021 12:12:13 -0400 X-MC-Unique: qyATIiLGPKW1OSiO_cFJ0g-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C26C5802938; Fri, 4 Jun 2021 16:12:11 +0000 (UTC) Received: from bahia.lan (ovpn-112-232.ams2.redhat.com [10.36.112.232]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2F2F7687CE; Fri, 4 Jun 2021 16:12:09 +0000 (UTC) From: Greg Kurz To: Miklos Szeredi Cc: linux-kernel@vger.kernel.org, Max Reitz , linux-fsdevel@vger.kernel.org, virtio-fs@redhat.com, Vivek Goyal , Greg Kurz , stable@vger.kernel.org Subject: [PATCH v2 1/7] fuse: Fix crash in fuse_dentry_automount() error path Date: Fri, 4 Jun 2021 18:11:50 +0200 Message-Id: <20210604161156.408496-2-groug@kaod.org> In-Reply-To: <20210604161156.408496-1-groug@kaod.org> References: <20210604161156.408496-1-groug@kaod.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=groug@kaod.org X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: kaod.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org If fuse_fill_super_submount() returns an error, the error path triggers a crash: [ 26.206673] BUG: kernel NULL pointer dereference, address: 0000000000000000 [...] [ 26.226362] RIP: 0010:__list_del_entry_valid+0x25/0x90 [...] [ 26.247938] Call Trace: [ 26.248300] fuse_mount_remove+0x2c/0x70 [fuse] [ 26.248892] virtio_kill_sb+0x22/0x160 [virtiofs] [ 26.249487] deactivate_locked_super+0x36/0xa0 [ 26.250077] fuse_dentry_automount+0x178/0x1a0 [fuse] The crash happens because fuse_mount_remove() assumes that the FUSE mount was already added to list under the FUSE connection, but this only done after fuse_fill_super_submount() has returned success. This means that until fuse_fill_super_submount() has returned success, the FUSE mount isn't actually owned by the superblock. We should thus reclaim ownership by clearing sb->s_fs_info, which will skip the call to fuse_mount_remove(), and perform rollback, like virtio_fs_get_tree() already does for the root sb. Fixes: bf109c64040f ("fuse: implement crossmounts") Cc: mreitz@redhat.com Cc: stable@vger.kernel.org # v5.10+ Signed-off-by: Greg Kurz Reviewed-by: Max Reitz --- fs/fuse/dir.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 1b6c001a7dd1..01559061cbfb 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -339,8 +339,12 @@ static struct vfsmount *fuse_dentry_automount(struct path *path) /* Initialize superblock, making @mp_fi its root */ err = fuse_fill_super_submount(sb, mp_fi); - if (err) + if (err) { + fuse_conn_put(fc); + kfree(fm); + sb->s_fs_info = NULL; goto out_put_sb; + } sb->s_flags |= SB_ACTIVE; fsc->root = dget(sb->s_root); From patchwork Fri Jun 4 16:11:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kurz X-Patchwork-Id: 12300053 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CD3DDC47098 for ; Fri, 4 Jun 2021 16:12:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B99BC613FF for ; Fri, 4 Jun 2021 16:12:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231285AbhFDQOG convert rfc822-to-8bit (ORCPT ); Fri, 4 Jun 2021 12:14:06 -0400 Received: from us-smtp-delivery-44.mimecast.com ([207.211.30.44]:26589 "EHLO us-smtp-delivery-44.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231281AbhFDQOE (ORCPT ); Fri, 4 Jun 2021 12:14:04 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-177-_9AFksQQM9iDjBrWox_Xcg-1; Fri, 04 Jun 2021 12:12:14 -0400 X-MC-Unique: _9AFksQQM9iDjBrWox_Xcg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 80AF9801817; Fri, 4 Jun 2021 16:12:13 +0000 (UTC) Received: from bahia.lan (ovpn-112-232.ams2.redhat.com [10.36.112.232]) by smtp.corp.redhat.com (Postfix) with ESMTP id 15F3060CEC; Fri, 4 Jun 2021 16:12:11 +0000 (UTC) From: Greg Kurz To: Miklos Szeredi Cc: linux-kernel@vger.kernel.org, Max Reitz , linux-fsdevel@vger.kernel.org, virtio-fs@redhat.com, Vivek Goyal , Greg Kurz Subject: [PATCH v2 2/7] fuse: Fix crash if superblock of submount gets killed early Date: Fri, 4 Jun 2021 18:11:51 +0200 Message-Id: <20210604161156.408496-3-groug@kaod.org> In-Reply-To: <20210604161156.408496-1-groug@kaod.org> References: <20210604161156.408496-1-groug@kaod.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: kaod.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org As soon as fuse_dentry_automount() does up_write(&sb->s_umount), the superblock can theoretically be killed. If this happens before the submount was added to the &fc->mounts list, fuse_mount_remove() later crashes in list_del_init() because it assumes the submount to be already there. Add the submount before dropping sb->s_umount to fix the inconsistency. It is okay to nest fc->killsb under sb->s_umount, we already do this on the ->kill_sb() path. Signed-off-by: Greg Kurz Reviewed-by: Max Reitz --- fs/fuse/dir.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 01559061cbfb..3fd1b71e546b 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -346,15 +346,15 @@ static struct vfsmount *fuse_dentry_automount(struct path *path) goto out_put_sb; } + down_write(&fc->killsb); + list_add_tail(&fm->fc_entry, &fc->mounts); + up_write(&fc->killsb); + sb->s_flags |= SB_ACTIVE; fsc->root = dget(sb->s_root); /* We are done configuring the superblock, so unlock it */ up_write(&sb->s_umount); - down_write(&fc->killsb); - list_add_tail(&fm->fc_entry, &fc->mounts); - up_write(&fc->killsb); - /* Create the submount */ mnt = vfs_create_mount(fsc); if (IS_ERR(mnt)) { From patchwork Fri Jun 4 16:11:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kurz X-Patchwork-Id: 12300057 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 023B0C07E94 for ; Fri, 4 Jun 2021 16:12:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E1E4061405 for ; Fri, 4 Jun 2021 16:12:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231376AbhFDQOJ convert rfc822-to-8bit (ORCPT ); Fri, 4 Jun 2021 12:14:09 -0400 Received: from us-smtp-delivery-44.mimecast.com ([205.139.111.44]:24774 "EHLO us-smtp-delivery-44.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231329AbhFDQOG (ORCPT ); Fri, 4 Jun 2021 12:14:06 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-570-R4Pyq-bqMRaU5LPdJd6bOA-1; Fri, 04 Jun 2021 12:12:16 -0400 X-MC-Unique: R4Pyq-bqMRaU5LPdJd6bOA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 6AA31180FD6E; Fri, 4 Jun 2021 16:12:15 +0000 (UTC) Received: from bahia.lan (ovpn-112-232.ams2.redhat.com [10.36.112.232]) by smtp.corp.redhat.com (Postfix) with ESMTP id CA7F060D06; Fri, 4 Jun 2021 16:12:13 +0000 (UTC) From: Greg Kurz To: Miklos Szeredi Cc: linux-kernel@vger.kernel.org, Max Reitz , linux-fsdevel@vger.kernel.org, virtio-fs@redhat.com, Vivek Goyal , Greg Kurz , stable@vger.kernel.org Subject: [PATCH v2 3/7] fuse: Fix infinite loop in sget_fc() Date: Fri, 4 Jun 2021 18:11:52 +0200 Message-Id: <20210604161156.408496-4-groug@kaod.org> In-Reply-To: <20210604161156.408496-1-groug@kaod.org> References: <20210604161156.408496-1-groug@kaod.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=groug@kaod.org X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: kaod.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org We don't set the SB_BORN flag on submounts. This is wrong as these superblocks are then considered as partially constructed or dying in the rest of the code and can break some assumptions. One such case is when you have a virtiofs filesystem with submounts and you try to mount it again : virtio_fs_get_tree() tries to obtain a superblock with sget_fc(). The logic in sget_fc() is to loop until it has either found an existing matching superblock with SB_BORN set or to create a brand new one. It is assumed that a superblock without SB_BORN is transient and the loop is restarted. Forgetting to set SB_BORN on submounts hence causes sget_fc() to retry forever. Setting SB_BORN requires special care, i.e. a write barrier for super_cache_count() which can check SB_BORN without taking any lock. We should call vfs_get_tree() to deal with that but this requires to have a proper ->get_tree() implementation for submounts, which is a bigger piece of work. Go for a simple bug fix in the meatime. Fixes: bf109c64040f ("fuse: implement crossmounts") Cc: mreitz@redhat.com Cc: stable@vger.kernel.org # v5.10+ Signed-off-by: Greg Kurz Reviewed-by: Max Reitz --- fs/fuse/dir.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 3fd1b71e546b..3fa8604c21d5 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -352,6 +352,17 @@ static struct vfsmount *fuse_dentry_automount(struct path *path) sb->s_flags |= SB_ACTIVE; fsc->root = dget(sb->s_root); + + /* + * FIXME: setting SB_BORN requires a write barrier for + * super_cache_count(). We should actually come + * up with a proper ->get_tree() implementation + * for submounts and call vfs_get_tree() to take + * care of the write barrier. + */ + smp_wmb(); + sb->s_flags |= SB_BORN; + /* We are done configuring the superblock, so unlock it */ up_write(&sb->s_umount); From patchwork Fri Jun 4 16:11:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kurz X-Patchwork-Id: 12300059 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C4E14C47083 for ; Fri, 4 Jun 2021 16:12:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B2920613FF for ; Fri, 4 Jun 2021 16:12:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231396AbhFDQOJ convert rfc822-to-8bit (ORCPT ); Fri, 4 Jun 2021 12:14:09 -0400 Received: from us-smtp-delivery-44.mimecast.com ([205.139.111.44]:24286 "EHLO us-smtp-delivery-44.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231289AbhFDQOI (ORCPT ); Fri, 4 Jun 2021 12:14:08 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-564-t0Dzju7TPcSRjZqzmv1G4Q-1; Fri, 04 Jun 2021 12:12:18 -0400 X-MC-Unique: t0Dzju7TPcSRjZqzmv1G4Q-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4E0011007B1A; Fri, 4 Jun 2021 16:12:17 +0000 (UTC) Received: from bahia.lan (ovpn-112-232.ams2.redhat.com [10.36.112.232]) by smtp.corp.redhat.com (Postfix) with ESMTP id B7DAF648A1; Fri, 4 Jun 2021 16:12:15 +0000 (UTC) From: Greg Kurz To: Miklos Szeredi Cc: linux-kernel@vger.kernel.org, Max Reitz , linux-fsdevel@vger.kernel.org, virtio-fs@redhat.com, Vivek Goyal , Greg Kurz Subject: [PATCH v2 4/7] fuse: Add dedicated filesystem context ops for submounts Date: Fri, 4 Jun 2021 18:11:53 +0200 Message-Id: <20210604161156.408496-5-groug@kaod.org> In-Reply-To: <20210604161156.408496-1-groug@kaod.org> References: <20210604161156.408496-1-groug@kaod.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=groug@kaod.org X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: kaod.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org The creation of a submount is open-coded in fuse_dentry_automount(). This brings a lot of complexity and we recently had to fix bugs because we weren't setting SB_BORN or because we were unlocking sb->s_umount before sb was fully configured. Most of these could have been avoided by using the mount API instead of open-coding. Basically, this means coming up with a proper ->get_tree() implementation for submounts and call vfs_get_tree(), or better fc_mount(). The creation of the superblock for submounts is quite different from the root mount. Especially, it doesn't require to allocate a FUSE filesystem context, nor to parse parameters. Introduce a dedicated context ops for submounts to make this clear. This is just a placeholder for now, fuse_get_tree_submount() will be populated in a subsequent patch. Only visible change is that we stop allocating/freeing a useless FUSE filesystem context with submounts. Signed-off-by: Greg Kurz Reviewed-by: Max Reitz --- fs/fuse/fuse_i.h | 5 +++++ fs/fuse/inode.c | 16 ++++++++++++++++ fs/fuse/virtio_fs.c | 3 +++ 3 files changed, 24 insertions(+) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 7e463e220053..862ad317bc89 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -1097,6 +1097,11 @@ int fuse_fill_super_submount(struct super_block *sb, */ bool fuse_mount_remove(struct fuse_mount *fm); +/* + * Setup context ops for submounts + */ +int fuse_init_fs_context_submount(struct fs_context *fsc); + /* * Shut down the connection (possibly sending DESTROY request). */ diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 393e36b74dc4..fa96a3762ea2 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -1313,6 +1313,22 @@ int fuse_fill_super_submount(struct super_block *sb, return 0; } +static int fuse_get_tree_submount(struct fs_context *fsc) +{ + return 0; +} + +static const struct fs_context_operations fuse_context_submount_ops = { + .get_tree = fuse_get_tree_submount, +}; + +int fuse_init_fs_context_submount(struct fs_context *fsc) +{ + fsc->ops = &fuse_context_submount_ops; + return 0; +} +EXPORT_SYMBOL_GPL(fuse_init_fs_context_submount); + int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx) { struct fuse_dev *fud = NULL; diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index bcb8a02e2d8b..e68467cc765c 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -1496,6 +1496,9 @@ static int virtio_fs_init_fs_context(struct fs_context *fsc) { struct fuse_fs_context *ctx; + if (fsc->purpose == FS_CONTEXT_FOR_SUBMOUNT) + return fuse_init_fs_context_submount(fsc); + ctx = kzalloc(sizeof(struct fuse_fs_context), GFP_KERNEL); if (!ctx) return -ENOMEM; From patchwork Fri Jun 4 16:11:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kurz X-Patchwork-Id: 12300061 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A36DEC07E94 for ; Fri, 4 Jun 2021 16:12:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9001E61405 for ; Fri, 4 Jun 2021 16:12:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231468AbhFDQON convert rfc822-to-8bit (ORCPT ); Fri, 4 Jun 2021 12:14:13 -0400 Received: from us-smtp-delivery-44.mimecast.com ([205.139.111.44]:33335 "EHLO us-smtp-delivery-44.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229774AbhFDQOM (ORCPT ); Fri, 4 Jun 2021 12:14:12 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-270-xGoyTos_OVKeYCaxchsOVA-1; Fri, 04 Jun 2021 12:12:22 -0400 X-MC-Unique: xGoyTos_OVKeYCaxchsOVA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1D8F6107ACC7; Fri, 4 Jun 2021 16:12:21 +0000 (UTC) Received: from bahia.lan (ovpn-112-232.ams2.redhat.com [10.36.112.232]) by smtp.corp.redhat.com (Postfix) with ESMTP id 969291B5B7; Fri, 4 Jun 2021 16:12:17 +0000 (UTC) From: Greg Kurz To: Miklos Szeredi Cc: linux-kernel@vger.kernel.org, Max Reitz , linux-fsdevel@vger.kernel.org, virtio-fs@redhat.com, Vivek Goyal , Greg Kurz Subject: [PATCH v2 5/7] fuse: Call vfs_get_tree() for submounts Date: Fri, 4 Jun 2021 18:11:54 +0200 Message-Id: <20210604161156.408496-6-groug@kaod.org> In-Reply-To: <20210604161156.408496-1-groug@kaod.org> References: <20210604161156.408496-1-groug@kaod.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: kaod.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org We recently fixed an infinite loop by setting the SB_BORN flag on submounts along with the write barrier needed by super_cache_count(). This is the job of vfs_get_tree() and FUSE shouldn't have to care about the barrier at all. Split out some code from fuse_dentry_automount() to the dedicated fuse_get_tree_submount() handler for submounts and call vfs_get_tree(). Signed-off-by: Greg Kurz Reviewed-by: Max Reitz --- fs/fuse/dir.c | 53 +++++-------------------------------------------- fs/fuse/inode.c | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 48 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 3fa8604c21d5..b88e5785a3dd 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -309,12 +309,8 @@ static int fuse_dentry_delete(const struct dentry *dentry) static struct vfsmount *fuse_dentry_automount(struct path *path) { struct fs_context *fsc; - struct fuse_mount *parent_fm = get_fuse_mount_super(path->mnt->mnt_sb); - struct fuse_conn *fc = parent_fm->fc; - struct fuse_mount *fm; struct vfsmount *mnt; struct fuse_inode *mp_fi = get_fuse_inode(d_inode(path->dentry)); - struct super_block *sb; int err; fsc = fs_context_for_submount(path->mnt->mnt_sb->s_type, path->dentry); @@ -323,48 +319,15 @@ static struct vfsmount *fuse_dentry_automount(struct path *path) goto out; } - err = -ENOMEM; - fm = kzalloc(sizeof(struct fuse_mount), GFP_KERNEL); - if (!fm) - goto out_put_fsc; + /* Pass the FUSE inode of the mount for fuse_get_tree_submount() */ + fsc->fs_private = mp_fi; - fsc->s_fs_info = fm; - sb = sget_fc(fsc, NULL, set_anon_super_fc); - if (IS_ERR(sb)) { - err = PTR_ERR(sb); - kfree(fm); + err = vfs_get_tree(fsc); + if (err) goto out_put_fsc; - } - fm->fc = fuse_conn_get(fc); - - /* Initialize superblock, making @mp_fi its root */ - err = fuse_fill_super_submount(sb, mp_fi); - if (err) { - fuse_conn_put(fc); - kfree(fm); - sb->s_fs_info = NULL; - goto out_put_sb; - } - - down_write(&fc->killsb); - list_add_tail(&fm->fc_entry, &fc->mounts); - up_write(&fc->killsb); - - sb->s_flags |= SB_ACTIVE; - fsc->root = dget(sb->s_root); - - /* - * FIXME: setting SB_BORN requires a write barrier for - * super_cache_count(). We should actually come - * up with a proper ->get_tree() implementation - * for submounts and call vfs_get_tree() to take - * care of the write barrier. - */ - smp_wmb(); - sb->s_flags |= SB_BORN; /* We are done configuring the superblock, so unlock it */ - up_write(&sb->s_umount); + up_write(&fsc->root->d_sb->s_umount); /* Create the submount */ mnt = vfs_create_mount(fsc); @@ -376,12 +339,6 @@ static struct vfsmount *fuse_dentry_automount(struct path *path) put_fs_context(fsc); return mnt; -out_put_sb: - /* - * Only jump here when fsc->root is NULL and sb is still locked - * (otherwise put_fs_context() will put the superblock) - */ - deactivate_locked_super(sb); out_put_fsc: put_fs_context(fsc); out: diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index fa96a3762ea2..bec1676811d4 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -1313,8 +1313,44 @@ int fuse_fill_super_submount(struct super_block *sb, return 0; } +/* Filesystem context private data holds the FUSE inode of the mount point */ static int fuse_get_tree_submount(struct fs_context *fsc) { + struct fuse_mount *fm; + struct fuse_inode *mp_fi = fsc->fs_private; + struct fuse_conn *fc = get_fuse_conn(&mp_fi->inode); + struct super_block *sb; + int err; + + fm = kzalloc(sizeof(struct fuse_mount), GFP_KERNEL); + if (!fm) + return -ENOMEM; + + fsc->s_fs_info = fm; + sb = sget_fc(fsc, NULL, set_anon_super_fc); + if (IS_ERR(sb)) { + kfree(fm); + return PTR_ERR(sb); + } + fm->fc = fuse_conn_get(fc); + + /* Initialize superblock, making @mp_fi its root */ + err = fuse_fill_super_submount(sb, mp_fi); + if (err) { + fuse_conn_put(fc); + kfree(fm); + sb->s_fs_info = NULL; + deactivate_locked_super(sb); + return err; + } + + down_write(&fc->killsb); + list_add_tail(&fm->fc_entry, &fc->mounts); + up_write(&fc->killsb); + + sb->s_flags |= SB_ACTIVE; + fsc->root = dget(sb->s_root); + return 0; } From patchwork Fri Jun 4 16:11:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kurz X-Patchwork-Id: 12300063 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DADFAC47083 for ; Fri, 4 Jun 2021 16:12:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C898261405 for ; Fri, 4 Jun 2021 16:12:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231474AbhFDQOO convert rfc822-to-8bit (ORCPT ); Fri, 4 Jun 2021 12:14:14 -0400 Received: from us-smtp-delivery-44.mimecast.com ([205.139.111.44]:39339 "EHLO us-smtp-delivery-44.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231364AbhFDQOM (ORCPT ); Fri, 4 Jun 2021 12:14:12 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-4-_RUPiRYdMxioWwaBmDx_Hw-1; Fri, 04 Jun 2021 12:12:23 -0400 X-MC-Unique: _RUPiRYdMxioWwaBmDx_Hw-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CE2D080293B; Fri, 4 Jun 2021 16:12:22 +0000 (UTC) Received: from bahia.lan (ovpn-112-232.ams2.redhat.com [10.36.112.232]) by smtp.corp.redhat.com (Postfix) with ESMTP id 65DBE60D06; Fri, 4 Jun 2021 16:12:21 +0000 (UTC) From: Greg Kurz To: Miklos Szeredi Cc: linux-kernel@vger.kernel.org, Max Reitz , linux-fsdevel@vger.kernel.org, virtio-fs@redhat.com, Vivek Goyal , Greg Kurz Subject: [PATCH v2 6/7] fuse: Switch to fc_mount() for submounts Date: Fri, 4 Jun 2021 18:11:55 +0200 Message-Id: <20210604161156.408496-7-groug@kaod.org> In-Reply-To: <20210604161156.408496-1-groug@kaod.org> References: <20210604161156.408496-1-groug@kaod.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=groug@kaod.org X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: kaod.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org fc_mount() already handles the vfs_get_tree(), sb->s_umount unlocking and vfs_create_mount() sequence. Using it greatly simplifies fuse_dentry_automount(). Signed-off-by: Greg Kurz Reviewed-by: Max Reitz --- fs/fuse/dir.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index b88e5785a3dd..fc9eddf7f9b2 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -311,38 +311,22 @@ static struct vfsmount *fuse_dentry_automount(struct path *path) struct fs_context *fsc; struct vfsmount *mnt; struct fuse_inode *mp_fi = get_fuse_inode(d_inode(path->dentry)); - int err; fsc = fs_context_for_submount(path->mnt->mnt_sb->s_type, path->dentry); - if (IS_ERR(fsc)) { - err = PTR_ERR(fsc); - goto out; - } + if (IS_ERR(fsc)) + return (struct vfsmount *) fsc; /* Pass the FUSE inode of the mount for fuse_get_tree_submount() */ fsc->fs_private = mp_fi; - err = vfs_get_tree(fsc); - if (err) - goto out_put_fsc; - - /* We are done configuring the superblock, so unlock it */ - up_write(&fsc->root->d_sb->s_umount); - /* Create the submount */ - mnt = vfs_create_mount(fsc); - if (IS_ERR(mnt)) { - err = PTR_ERR(mnt); + mnt = fc_mount(fsc); + if (IS_ERR(mnt)) goto out_put_fsc; - } mntget(mnt); - put_fs_context(fsc); - return mnt; - out_put_fsc: put_fs_context(fsc); -out: - return ERR_PTR(err); + return mnt; } const struct dentry_operations fuse_dentry_operations = { From patchwork Fri Jun 4 16:11:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kurz X-Patchwork-Id: 12300065 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1FBE7C07E94 for ; Fri, 4 Jun 2021 16:12:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0A022613F4 for ; Fri, 4 Jun 2021 16:12:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229916AbhFDQO1 convert rfc822-to-8bit (ORCPT ); Fri, 4 Jun 2021 12:14:27 -0400 Received: from us-smtp-delivery-44.mimecast.com ([205.139.111.44]:36338 "EHLO us-smtp-delivery-44.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231501AbhFDQOZ (ORCPT ); Fri, 4 Jun 2021 12:14:25 -0400 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-294-YjIqfu06PVicuVQWgSTnkA-1; Fri, 04 Jun 2021 12:12:25 -0400 X-MC-Unique: YjIqfu06PVicuVQWgSTnkA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 8FF3B107ACE4; Fri, 4 Jun 2021 16:12:24 +0000 (UTC) Received: from bahia.lan (ovpn-112-232.ams2.redhat.com [10.36.112.232]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2311360D06; Fri, 4 Jun 2021 16:12:22 +0000 (UTC) From: Greg Kurz To: Miklos Szeredi Cc: linux-kernel@vger.kernel.org, Max Reitz , linux-fsdevel@vger.kernel.org, virtio-fs@redhat.com, Vivek Goyal , Greg Kurz Subject: [PATCH v2 7/7] fuse: Make fuse_fill_super_submount() static Date: Fri, 4 Jun 2021 18:11:56 +0200 Message-Id: <20210604161156.408496-8-groug@kaod.org> In-Reply-To: <20210604161156.408496-1-groug@kaod.org> References: <20210604161156.408496-1-groug@kaod.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: kaod.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org This function used to be called from fuse_dentry_automount(). This code was moved to fuse_get_tree_submount() in the same file since then. It is unlikely there will ever be another user. No need to be extern in this case. Signed-off-by: Greg Kurz Reviewed-by: Max Reitz --- fs/fuse/fuse_i.h | 9 --------- fs/fuse/inode.c | 4 ++-- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 862ad317bc89..1d32251a439a 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -1081,15 +1081,6 @@ void fuse_send_init(struct fuse_mount *fm); */ int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx); -/* - * Fill in superblock for submounts - * @sb: partially-initialized superblock to fill in - * @parent_fi: The fuse_inode of the parent filesystem where this submount is - * mounted - */ -int fuse_fill_super_submount(struct super_block *sb, - struct fuse_inode *parent_fi); - /* * Remove the mount from the connection * diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index bec1676811d4..72d44121ea38 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -1275,8 +1275,8 @@ static void fuse_sb_defaults(struct super_block *sb) sb->s_xattr = fuse_no_acl_xattr_handlers; } -int fuse_fill_super_submount(struct super_block *sb, - struct fuse_inode *parent_fi) +static int fuse_fill_super_submount(struct super_block *sb, + struct fuse_inode *parent_fi) { struct fuse_mount *fm = get_fuse_mount_super(sb); struct super_block *parent_sb = parent_fi->inode.i_sb;