Re: [PATCH] Track and use TUCK mounts for precise umount semantics.

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

 



Ram Pai <linuxram@xxxxxxxxxx> writes:

> Shared-subtree has had many cases where unmount operation would leave a lot of
> residual mounts, because it was way too difficult to remove them. Eric
> Biederman came up with the idea of tucked mount which relieved the situation
> tremendously. But it still lacks the reversibility property --  A mount
> followed by a umount should reverse the mount-tree to the exact same state as
> before the mount.

There is a lot here so I am taking my time an digging through it all.

I have found two issues that I am going to point out before I comment
on the big picture.

> diff --git a/fs/pnode.c b/fs/pnode.c
> index 5bc7896..7dfbe9c 100644
> --- a/fs/pnode.c
> +++ b/fs/pnode.c
> @@ -322,19 +322,9 @@ int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp,
>  	return ret;
>  }
>  
> -static struct mount *find_topper(struct mount *mnt)
> +static struct mount *find_covering_child(struct mount *m)
>  {
> -	/* If there is exactly one mount covering mnt completely return it. */
> -	struct mount *child;
> -
> -	if (!list_is_singular(&mnt->mnt_mounts))
> -		return NULL;
> -
> -	child = list_first_entry(&mnt->mnt_mounts, struct mount, mnt_child);
> -	if (child->mnt_mountpoint != mnt->mnt.mnt_root)
> -		return NULL;
> -
> -	return child;
> +	return __lookup_mnt(&m->mnt, m->mnt.mnt_root);
>  }

Unless there is some reason you can't use mnt_mounts using
__lookup_mnt is a pessimization here as __lookup_mnt can go slowly
when the has chains get long.

>  /*
> @@ -357,8 +347,10 @@ static inline int do_refcount_check(struct mount *mnt, int count)
>   */
>  int propagate_mount_busy(struct mount *mnt, int refcnt)
>  {
> -	struct mount *m, *child, *topper;
> +	struct mount *m, *child;
>  	struct mount *parent = mnt->mnt_parent;
> +	bool tucks_can_ignore = !(IS_MNT_TUCK_END(parent) &&
> +				mnt->mnt_mountpoint == parent->mnt.mnt_root);
>  
>  	if (mnt == parent)
>  		return do_refcount_check(mnt, refcnt);
> @@ -372,19 +364,19 @@ int propagate_mount_busy(struct mount *mnt, int refcnt)
>  		return 1;
>  
>  	for (m = propagation_next(parent, parent); m;
> -	     		m = propagation_next(m, parent)) {
> +			m = propagation_next(m, parent)) {
>  		int count = 1;
> -		child = __lookup_mnt(&m->mnt, mnt->mnt_mountpoint);
> -		if (!child)
> -			continue;
>  
> -		/* Is there exactly one mount on the child that covers
> -		 * it completely whose reference should be ignored?
> +		/*
> +		 * read the comment in __propagate_umount()
>  		 */
> -		topper = find_topper(child);
> -		if (topper)
> -			count += 1;
> -		else if (!list_empty(&child->mnt_mounts))
> +		if (tucks_can_ignore &&
> +			IS_MNT_TUCK_END(m) &&
> +			(mnt->mnt_mountpoint == m->mnt.mnt_root))
> +			continue;
> +
> +		child = __lookup_mnt(&m->mnt, mnt->mnt_mountpoint);
> +		if (!child || !list_empty(&child->mnt_mounts))
>  			continue;
>  
>  		if (do_refcount_check(child, count))

Unless I am misreading this code you are skipping a refcount check that
we should be performing.

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