All of lore.kernel.org
 help / color / mirror / Atom feed
From: ebiederm@xmission.com (Eric W. Biederman)
To: Ram Pai <linuxram@us.ibm.com>
Cc: Al Viro <viro@ZenIV.linux.org.uk>,
	linux-fsdevel@vger.kernel.org,
	Andrei Vagin <avagin@virtuozzo.com>
Subject: Re: [PATCH v5] mnt: Tuck mounts under others instead of creating shadow/side mounts.
Date: Sat, 21 Jan 2017 17:15:29 +1300	[thread overview]
Message-ID: <87efzxt5em.fsf@xmission.com> (raw)
In-Reply-To: <20170121035827.GA5657@ram.oc3035372033.ibm.com> (Ram Pai's message of "Fri, 20 Jan 2017 19:58:27 -0800")

Ram Pai <linuxram@us.ibm.com> writes:

>> @@ -359,12 +373,24 @@ int propagate_mount_busy(struct mount *mnt, int refcnt)
>> 
>>  	for (m = propagation_next(parent, parent); m;
>>  	     		m = propagation_next(m, parent)) {
>> -		child = __lookup_mnt_last(&m->mnt, mnt->mnt_mountpoint);
>> -		if (child && list_empty(&child->mnt_mounts) &&
>> -		    (ret = do_refcount_check(child, 1)))
>> -			break;
>> +		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?
>> +		 */
>> +		topper = find_topper(child);
>
> This is tricky. I understand it is trying to identify the case where a
> mount got tucked-in because of propagation.  But this will not
> distinguish the case where a mount got over-mounted genuinely, not because of
> propagation, but because of explicit user action.
>
>
> example:
>
> case 1: (explicit user action)
> 	B is a slave of A
> 	mount something on A/a , it will propagate to B/a
> 	and than mount something on B/a
>
> case 2: (tucked mount)
> 	B is a slave of A
> 	mount something on B/a
> 	and than mount something on A/a
>
> Both case 1 and case 2 lead to the same mount configuration.
>
>
> 	  however 'umount A/a' in case 1 should fail.
> 	  and 'umount A/a' in case 2 should pass.
>
> Right? in other words, umounts of 'tucked mounts' should pass(case 2).
> 	whereas umounts of mounts on which overmounts exist should
> 		fail.(case 1)

Looking at your example.  I agree that case 1 will fail today.
However my actual expectation would be for both mount configurations
to behave the same.  In both cases something has been explicitly mounted
on B/a and something has propagated to B/a.  In both cases the mount
on top is what was explicitly mounted, and the mount below is what was
propagated to B/a.

I don't see why the order of operations should matter.

> maybe we need a flag to identify tucked mounts?

To preserve our exact current semantics yes.

The mount configurations that are delibearately constructed that I am
aware of are comparatively simple.  I don't think anyone has even taken
advantage of the shadow/side mounts at this point.  I made a reasonable
effort to find out and no one was even aware they existed.  Much less
what they were.  And certainly no one I talked to could find code that
used them.

So I think we are fine with a very modest semantic change here.
Especially one that appears to make the semantics more consistent and
predictable.

I also expect the checkpoint/restart folks will appreciate the change
as by giving them options it will make it easier to reconstruct
complicated mount trees.

Eric


>> +
>> +		if (do_refcount_check(child, count))
>> +			return 1;
>>  	}
>> -	return ret;
>> +	return 0;
>>  }
>> 
>>  /*
>> @@ -381,7 +407,7 @@ void propagate_mount_unlock(struct mount *mnt)
>> 
>>  	for (m = propagation_next(parent, parent); m;
>>  			m = propagation_next(m, parent)) {
>> -		child = __lookup_mnt_last(&m->mnt, mnt->mnt_mountpoint);
>> +		child = __lookup_mnt(&m->mnt, mnt->mnt_mountpoint);
>>  		if (child)
>>  			child->mnt.mnt_flags &= ~MNT_LOCKED;
>>  	}
>> @@ -399,9 +425,11 @@ static void mark_umount_candidates(struct mount *mnt)
>> 
>>  	for (m = propagation_next(parent, parent); m;
>>  			m = propagation_next(m, parent)) {
>> -		struct mount *child = __lookup_mnt_last(&m->mnt,
>> +		struct mount *child = __lookup_mnt(&m->mnt,
>>  						mnt->mnt_mountpoint);
>> -		if (child && (!IS_MNT_LOCKED(child) || IS_MNT_MARKED(m))) {
>> +		if (!child || (child->mnt.mnt_flags & MNT_UMOUNT))
>> +			continue;
>> +		if (!IS_MNT_LOCKED(child) || IS_MNT_MARKED(m)) {
>>  			SET_MNT_MARK(child);
>>  		}
>>  	}
>> @@ -420,8 +448,8 @@ static void __propagate_umount(struct mount *mnt)
>> 
>>  	for (m = propagation_next(parent, parent); m;
>>  			m = propagation_next(m, parent)) {
>> -
>> -		struct mount *child = __lookup_mnt_last(&m->mnt,
>> +		struct mount *topper;
>> +		struct mount *child = __lookup_mnt(&m->mnt,
>>  						mnt->mnt_mountpoint);
>>  		/*
>>  		 * umount the child only if the child has no children
>> @@ -430,6 +458,15 @@ static void __propagate_umount(struct mount *mnt)
>>  		if (!child || !IS_MNT_MARKED(child))
>>  			continue;
>>  		CLEAR_MNT_MARK(child);
>> +
>> +		/* If there is exactly one mount covering all of child
>> +		 * replace child with that mount.
>> +		 */
>> +		topper = find_topper(child);
>> +		if (topper)
>> +			mnt_change_mountpoint(child->mnt_parent, child->mnt_mp,
>> +					      topper);
>> +
>>  		if (list_empty(&child->mnt_mounts)) {
>>  			list_del_init(&child->mnt_child);
>>  			child->mnt.mnt_flags |= MNT_UMOUNT;
>> diff --git a/fs/pnode.h b/fs/pnode.h
>> index 550f5a8b4fcf..dc87e65becd2 100644
>> --- a/fs/pnode.h
>> +++ b/fs/pnode.h
>> @@ -49,6 +49,8 @@ int get_dominating_id(struct mount *mnt, const struct path *root);
>>  unsigned int mnt_get_count(struct mount *mnt);
>>  void mnt_set_mountpoint(struct mount *, struct mountpoint *,
>>  			struct mount *);
>> +void mnt_change_mountpoint(struct mount *parent, struct mountpoint *mp,
>> +			   struct mount *mnt);
>>  struct mount *copy_tree(struct mount *, struct dentry *, int);
>>  bool is_path_reachable(struct mount *, struct dentry *,
>>  			 const struct path *root);
>> -- 
>> 2.10.1

  reply	other threads:[~2017-01-21  4:20 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-31  4:10 [PATCH] Fix a race in put_mountpoint Krister Johansen
2016-12-31  6:17 ` Al Viro
2017-01-03  0:51   ` Eric W. Biederman
2017-01-03  1:48     ` Al Viro
2017-01-03  3:17       ` Eric W. Biederman
2017-01-03  4:00         ` Al Viro
2017-01-04  3:52           ` Eric W. Biederman
2017-01-04  3:53             ` [PATCH] mnt: Protect the mountpoint hashtable with mount_lock Eric W. Biederman
2017-01-04 21:04               ` [REVIEW][PATCH] mnt: Tuck mounts under others instead of creating shadow/side mounts Eric W. Biederman
2017-01-07  5:06                 ` Al Viro
2017-01-11  0:10                   ` Eric W. Biederman
2017-01-11  4:11                     ` Al Viro
2017-01-11 16:03                       ` Eric W. Biederman
2017-01-11 16:18                         ` [REVIEW][PATCH 1/2] mnt: Fix propagate_mount_busy to notice all cases of busy mounts Eric W. Biederman
2017-01-11 16:19                           ` [REVIEW][PATCH 2/2] mnt: Tuck mounts under others instead of creating shadow/side mounts Eric W. Biederman
2017-01-12  5:45                             ` Al Viro
2017-01-20  7:20                               ` Eric W. Biederman
2017-01-20  7:26                               ` [PATCH v5] " Eric W. Biederman
2017-01-21  3:58                                 ` Ram Pai
2017-01-21  4:15                                   ` Eric W. Biederman [this message]
2017-01-23 19:02                                     ` Ram Pai
2017-01-24  0:16                                       ` Eric W. Biederman
2017-02-03 10:54                                         ` Eric W. Biederman
2017-02-03 17:10                                           ` Ram Pai
2017-02-03 18:26                                             ` Eric W. Biederman
2017-02-03 20:28                                               ` Ram Pai
2017-02-03 20:58                                                 ` Eric W. Biederman
2017-02-06  3:25                                                   ` Andrei Vagin
2017-02-06 21:40                                                     ` Ram Pai
2017-02-07  6:35                                                       ` Andrei Vagin
2017-01-12  5:30                           ` [REVIEW][PATCH 1/2] mnt: Fix propagate_mount_busy to notice all cases of busy mounts Al Viro
2017-01-20  7:18                             ` Eric W. Biederman
2017-01-13 20:32                           ` Andrei Vagin
2017-01-18 19:20                             ` Andrei Vagin
2017-01-20 23:18                           ` Ram Pai
2017-01-23  8:15                             ` Eric W. Biederman
2017-01-23 17:04                               ` Ram Pai
2017-01-12  5:03                         ` [REVIEW][PATCH] mnt: Tuck mounts under others instead of creating shadow/side mounts Al Viro
2017-05-14  2:15                 ` Andrei Vagin
2017-05-14  4:05                   ` Eric W. Biederman
2017-05-14  9:26                     ` Eric W. Biederman
2017-05-15 18:27                       ` Andrei Vagin
2017-05-15 19:42                         ` Eric W. Biederman
2017-05-15 20:10                           ` [REVIEW][PATCH] mnt: In umount propagation reparent in a separate pass Eric W. Biederman
2017-05-15 23:12                             ` Andrei Vagin
2017-05-16  5:42                             ` [PATCH] test: check a case when a mount is propagated between exiting mounts Andrei Vagin
2017-05-17  5:54                             ` [REVIEW][PATCH 1/2] mnt: In propgate_umount handle visiting mounts in any order Eric W. Biederman
2017-05-17  5:55                               ` [REVIEW][PATCH 2/2] mnt: Make propagate_umount less slow for overlapping mount propagation trees Eric W. Biederman
2017-05-17 22:48                                 ` Andrei Vagin
2017-05-17 23:26                                   ` Eric W. Biederman
2017-05-18  0:51                                     ` Andrei Vagin
2017-05-24 20:42                               ` [REVIEW][PATCH 1/2] mnt: In propgate_umount handle visiting mounts in any order Ram Pai
2017-05-24 21:54                                 ` Eric W. Biederman
2017-05-24 22:35                                   ` Ram Pai
2017-05-30  6:07                               ` Ram Pai
2017-05-30 15:07                                 ` Eric W. Biederman
2017-06-07  9:54                                   ` Ram Pai
2017-06-07 13:09                                     ` Eric W. Biederman
2017-05-22  8:15                             ` [REVIEW][PATCH] mnt: In umount propagation reparent in a separate pass Ram Pai
2017-05-22 18:33                               ` Eric W. Biederman
2017-05-22 22:34                                 ` Ram Pai
2017-05-23 13:58                                   ` Eric W. Biederman
2017-01-06  7:00               ` [PATCH] mnt: Protect the mountpoint hashtable with mount_lock Krister Johansen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87efzxt5em.fsf@xmission.com \
    --to=ebiederm@xmission.com \
    --cc=avagin@virtuozzo.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linuxram@us.ibm.com \
    --cc=viro@ZenIV.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.