Re: [PATCH 10/32] VFS: Implement a filesystem superblock creation/configuration context [ver #8]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux