From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf0-f194.google.com ([209.85.192.194]:46388 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934468AbeGCSd2 (ORCPT ); Tue, 3 Jul 2018 14:33:28 -0400 Date: Tue, 3 Jul 2018 11:33:25 -0700 From: Eric Biggers To: David Howells Cc: viro@zeniv.linux.org.uk, linux-fsdevel@vger.kernel.org, linux-afs@lists.infradead.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH 10/32] VFS: Implement a filesystem superblock creation/configuration context [ver #8] Message-ID: <20180703183325.GA210265@gmail.com> References: <152720672288.9073.9868393448836301272.stgit@warthog.procyon.org.uk> <152720678933.9073.11201500538963619904.stgit@warthog.procyon.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <152720678933.9073.11201500538963619904.stgit@warthog.procyon.org.uk> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: On Fri, May 25, 2018 at 01:06:29AM +0100, David Howells wrote: > +/** > + * sget_fc - Find or create a superblock > + * @fc: Filesystem context. > + * @test: Comparison callback > + * @set: Setup callback > + * > + * Find or create a superblock using the parameters stored in the filesystem > + * context and the two callback functions. > + * > + * If an extant superblock is matched, then that will be returned with an > + * elevated reference count that the caller must transfer or discard. > + * > + * If no match is made, a new superblock will be allocated and basic > + * initialisation will be performed (s_type, s_fs_info and s_id will be set and > + * the set() callback will be invoked), the superblock will be published and it > + * will be returned in a partially constructed state with SB_BORN and SB_ACTIVE > + * as yet unset. > + */ > +struct super_block *sget_fc(struct fs_context *fc, > + int (*test)(struct super_block *, struct fs_context *), > + int (*set)(struct super_block *, struct fs_context *)) > +{ > + struct super_block *s = NULL; > + struct super_block *old; > + int err; > + > + if (!(fc->sb_flags & SB_KERNMOUNT) && > + fc->purpose != FS_CONTEXT_FOR_SUBMOUNT) { > + /* Don't allow mounting unless the caller has CAP_SYS_ADMIN > + * over the namespace. > + */ > + if (!(fc->fs_type->fs_flags & FS_USERNS_MOUNT) && > + !capable(CAP_SYS_ADMIN)) > + return ERR_PTR(-EPERM); > + else if (!ns_capable(fc->user_ns, CAP_SYS_ADMIN)) > + return ERR_PTR(-EPERM); > + } > + > +retry: > + spin_lock(&sb_lock); > + if (test) { > + hlist_for_each_entry(old, &fc->fs_type->fs_supers, s_instances) { > + if (!test(old, fc)) > + continue; > + if (fc->user_ns != old->s_user_ns) { > + spin_unlock(&sb_lock); > + if (s) { > + up_write(&s->s_umount); > + destroy_unused_super(s); > + } ->s_umount is released once here and again in destroy_unused_super(). > + return ERR_PTR(-EBUSY); > + } > + if (!grab_super(old)) > + goto retry; > + if (s) { > + up_write(&s->s_umount); > + destroy_unused_super(s); Same bug here. > + up_write(&s->s_umount); > + destroy_unused_super(s); And here. - Eric