brintos

brintos / linux-shallow public Read only

0
0
Text · 29.6 KiB · 1cf5648 Raw
1000 lines · plain
1.. SPDX-License-Identifier: GPL-2.02 3===============4Shared Subtrees5===============6 7.. Contents:8	1) Overview9	2) Features10	3) Setting mount states11	4) Use-case12	5) Detailed semantics13	6) Quiz14	7) FAQ15	8) Implementation16 17 181) Overview19-----------20 21Consider the following situation:22 23A process wants to clone its own namespace, but still wants to access the CD24that got mounted recently.  Shared subtree semantics provide the necessary25mechanism to accomplish the above.26 27It provides the necessary building blocks for features like per-user-namespace28and versioned filesystem.29 302) Features31-----------32 33Shared subtree provides four different flavors of mounts; struct vfsmount to be34precise35 36	a. shared mount37	b. slave mount38	c. private mount39	d. unbindable mount40 41 422a) A shared mount can be replicated to as many mountpoints and all the43replicas continue to be exactly same.44 45	Here is an example:46 47	Let's say /mnt has a mount that is shared::48 49	    mount --make-shared /mnt50 51	Note: mount(8) command now supports the --make-shared flag,52	so the sample 'smount' program is no longer needed and has been53	removed.54 55	::56 57	    # mount --bind /mnt /tmp58 59	The above command replicates the mount at /mnt to the mountpoint /tmp60	and the contents of both the mounts remain identical.61 62	::63 64	    #ls /mnt65	    a b c66 67	    #ls /tmp68	    a b c69 70	Now let's say we mount a device at /tmp/a::71 72	    # mount /dev/sd0  /tmp/a73 74	    #ls /tmp/a75	    t1 t2 t376 77	    #ls /mnt/a78	    t1 t2 t379 80	Note that the mount has propagated to the mount at /mnt as well.81 82	And the same is true even when /dev/sd0 is mounted on /mnt/a. The83	contents will be visible under /tmp/a too.84 85 862b) A slave mount is like a shared mount except that mount and umount events87	only propagate towards it.88 89	All slave mounts have a master mount which is a shared.90 91	Here is an example:92 93	Let's say /mnt has a mount which is shared.94	# mount --make-shared /mnt95 96	Let's bind mount /mnt to /tmp97	# mount --bind /mnt /tmp98 99	the new mount at /tmp becomes a shared mount and it is a replica of100	the mount at /mnt.101 102	Now let's make the mount at /tmp; a slave of /mnt103	# mount --make-slave /tmp104 105	let's mount /dev/sd0 on /mnt/a106	# mount /dev/sd0 /mnt/a107 108	#ls /mnt/a109	t1 t2 t3110 111	#ls /tmp/a112	t1 t2 t3113 114	Note the mount event has propagated to the mount at /tmp115 116	However let's see what happens if we mount something on the mount at /tmp117 118	# mount /dev/sd1 /tmp/b119 120	#ls /tmp/b121	s1 s2 s3122 123	#ls /mnt/b124 125	Note how the mount event has not propagated to the mount at126	/mnt127 128 1292c) A private mount does not forward or receive propagation.130 131	This is the mount we are familiar with. Its the default type.132 133 1342d) A unbindable mount is a unbindable private mount135 136	let's say we have a mount at /mnt and we make it unbindable::137 138	    # mount --make-unbindable /mnt139 140	 Let's try to bind mount this mount somewhere else::141 142	    # mount --bind /mnt /tmp143	    mount: wrong fs type, bad option, bad superblock on /mnt,144		    or too many mounted file systems145 146	Binding a unbindable mount is a invalid operation.147 148 1493) Setting mount states150-----------------------151 152	The mount command (util-linux package) can be used to set mount153	states::154 155	    mount --make-shared mountpoint156	    mount --make-slave mountpoint157	    mount --make-private mountpoint158	    mount --make-unbindable mountpoint159 160 1614) Use cases162------------163 164	A) A process wants to clone its own namespace, but still wants to165	   access the CD that got mounted recently.166 167	   Solution:168 169		The system administrator can make the mount at /cdrom shared::170 171		    mount --bind /cdrom /cdrom172		    mount --make-shared /cdrom173 174		Now any process that clones off a new namespace will have a175		mount at /cdrom which is a replica of the same mount in the176		parent namespace.177 178		So when a CD is inserted and mounted at /cdrom that mount gets179		propagated to the other mount at /cdrom in all the other clone180		namespaces.181 182	B) A process wants its mounts invisible to any other process, but183	still be able to see the other system mounts.184 185	   Solution:186 187		To begin with, the administrator can mark the entire mount tree188		as shareable::189 190		    mount --make-rshared /191 192		A new process can clone off a new namespace. And mark some part193		of its namespace as slave::194 195		    mount --make-rslave /myprivatetree196 197		Hence forth any mounts within the /myprivatetree done by the198		process will not show up in any other namespace. However mounts199		done in the parent namespace under /myprivatetree still shows200		up in the process's namespace.201 202 203	Apart from the above semantics this feature provides the204	building blocks to solve the following problems:205 206	C)  Per-user namespace207 208		The above semantics allows a way to share mounts across209		namespaces.  But namespaces are associated with processes. If210		namespaces are made first class objects with user API to211		associate/disassociate a namespace with userid, then each user212		could have his/her own namespace and tailor it to his/her213		requirements. This needs to be supported in PAM.214 215	D)  Versioned files216 217		If the entire mount tree is visible at multiple locations, then218		an underlying versioning file system can return different219		versions of the file depending on the path used to access that220		file.221 222		An example is::223 224		    mount --make-shared /225		    mount --rbind / /view/v1226		    mount --rbind / /view/v2227		    mount --rbind / /view/v3228		    mount --rbind / /view/v4229 230		and if /usr has a versioning filesystem mounted, then that231		mount appears at /view/v1/usr, /view/v2/usr, /view/v3/usr and232		/view/v4/usr too233 234		A user can request v3 version of the file /usr/fs/namespace.c235		by accessing /view/v3/usr/fs/namespace.c . The underlying236		versioning filesystem can then decipher that v3 version of the237		filesystem is being requested and return the corresponding238		inode.239 2405) Detailed semantics241---------------------242	The section below explains the detailed semantics of243	bind, rbind, move, mount, umount and clone-namespace operations.244 245	Note: the word 'vfsmount' and the noun 'mount' have been used246	to mean the same thing, throughout this document.247 2485a) Mount states249 250	A given mount can be in one of the following states251 252	1) shared253	2) slave254	3) shared and slave255	4) private256	5) unbindable257 258	A 'propagation event' is defined as event generated on a vfsmount259	that leads to mount or unmount actions in other vfsmounts.260 261	A 'peer group' is defined as a group of vfsmounts that propagate262	events to each other.263 264	(1) Shared mounts265 266		A 'shared mount' is defined as a vfsmount that belongs to a267		'peer group'.268 269		For example::270 271			mount --make-shared /mnt272			mount --bind /mnt /tmp273 274		The mount at /mnt and that at /tmp are both shared and belong275		to the same peer group. Anything mounted or unmounted under276		/mnt or /tmp reflect in all the other mounts of its peer277		group.278 279 280	(2) Slave mounts281 282		A 'slave mount' is defined as a vfsmount that receives283		propagation events and does not forward propagation events.284 285		A slave mount as the name implies has a master mount from which286		mount/unmount events are received. Events do not propagate from287		the slave mount to the master.  Only a shared mount can be made288		a slave by executing the following command::289 290			mount --make-slave mount291 292		A shared mount that is made as a slave is no more shared unless293		modified to become shared.294 295	(3) Shared and Slave296 297		A vfsmount can be both shared as well as slave.  This state298		indicates that the mount is a slave of some vfsmount, and299		has its own peer group too.  This vfsmount receives propagation300		events from its master vfsmount, and also forwards propagation301		events to its 'peer group' and to its slave vfsmounts.302 303		Strictly speaking, the vfsmount is shared having its own304		peer group, and this peer-group is a slave of some other305		peer group.306 307		Only a slave vfsmount can be made as 'shared and slave' by308		either executing the following command::309 310			mount --make-shared mount311 312		or by moving the slave vfsmount under a shared vfsmount.313 314	(4) Private mount315 316		A 'private mount' is defined as vfsmount that does not317		receive or forward any propagation events.318 319	(5) Unbindable mount320 321		A 'unbindable mount' is defined as vfsmount that does not322		receive or forward any propagation events and cannot323		be bind mounted.324 325 326   	State diagram:327 328   	The state diagram below explains the state transition of a mount,329	in response to various commands::330 331	    -----------------------------------------------------------------------332	    |             |make-shared |  make-slave  | make-private |make-unbindab|333	    --------------|------------|--------------|--------------|-------------|334	    |shared	  |shared      |*slave/private|   private    | unbindable  |335	    |             |            |              |              |             |336	    |-------------|------------|--------------|--------------|-------------|337	    |slave	  |shared      | **slave      |    private   | unbindable  |338	    |             |and slave   |              |              |             |339	    |-------------|------------|--------------|--------------|-------------|340	    |shared       |shared      | slave        |    private   | unbindable  |341	    |and slave    |and slave   |              |              |             |342	    |-------------|------------|--------------|--------------|-------------|343	    |private      |shared      |  **private   |    private   | unbindable  |344	    |-------------|------------|--------------|--------------|-------------|345	    |unbindable   |shared      |**unbindable  |    private   | unbindable  |346	    ------------------------------------------------------------------------347 348	    * if the shared mount is the only mount in its peer group, making it349	    slave, makes it private automatically. Note that there is no master to350	    which it can be slaved to.351 352	    ** slaving a non-shared mount has no effect on the mount.353 354	Apart from the commands listed below, the 'move' operation also changes355	the state of a mount depending on type of the destination mount. Its356	explained in section 5d.357 3585b) Bind semantics359 360	Consider the following command::361 362	    mount --bind A/a  B/b363 364	where 'A' is the source mount, 'a' is the dentry in the mount 'A', 'B'365	is the destination mount and 'b' is the dentry in the destination mount.366 367	The outcome depends on the type of mount of 'A' and 'B'. The table368	below contains quick reference::369 370	    --------------------------------------------------------------------------371	    |         BIND MOUNT OPERATION                                           |372	    |************************************************************************|373	    |source(A)->| shared      |       private  |       slave    | unbindable |374	    | dest(B)  |              |                |                |            |375	    |   |      |              |                |                |            |376	    |   v      |              |                |                |            |377	    |************************************************************************|378	    |  shared  | shared       |     shared     | shared & slave |  invalid   |379	    |          |              |                |                |            |380	    |non-shared| shared       |      private   |      slave     |  invalid   |381	    **************************************************************************382 383     	Details:384 385    1. 'A' is a shared mount and 'B' is a shared mount. A new mount 'C'386	which is clone of 'A', is created. Its root dentry is 'a' . 'C' is387	mounted on mount 'B' at dentry 'b'. Also new mount 'C1', 'C2', 'C3' ...388	are created and mounted at the dentry 'b' on all mounts where 'B'389	propagates to. A new propagation tree containing 'C1',..,'Cn' is390	created. This propagation tree is identical to the propagation tree of391	'B'.  And finally the peer-group of 'C' is merged with the peer group392	of 'A'.393 394    2. 'A' is a private mount and 'B' is a shared mount. A new mount 'C'395	which is clone of 'A', is created. Its root dentry is 'a'. 'C' is396	mounted on mount 'B' at dentry 'b'. Also new mount 'C1', 'C2', 'C3' ...397	are created and mounted at the dentry 'b' on all mounts where 'B'398	propagates to. A new propagation tree is set containing all new mounts399	'C', 'C1', .., 'Cn' with exactly the same configuration as the400	propagation tree for 'B'.401 402    3. 'A' is a slave mount of mount 'Z' and 'B' is a shared mount. A new403	mount 'C' which is clone of 'A', is created. Its root dentry is 'a' .404	'C' is mounted on mount 'B' at dentry 'b'. Also new mounts 'C1', 'C2',405	'C3' ... are created and mounted at the dentry 'b' on all mounts where406	'B' propagates to. A new propagation tree containing the new mounts407	'C','C1',..  'Cn' is created. This propagation tree is identical to the408	propagation tree for 'B'. And finally the mount 'C' and its peer group409	is made the slave of mount 'Z'.  In other words, mount 'C' is in the410	state 'slave and shared'.411 412    4. 'A' is a unbindable mount and 'B' is a shared mount. This is a413	invalid operation.414 415    5. 'A' is a private mount and 'B' is a non-shared(private or slave or416	unbindable) mount. A new mount 'C' which is clone of 'A', is created.417	Its root dentry is 'a'. 'C' is mounted on mount 'B' at dentry 'b'.418 419    6. 'A' is a shared mount and 'B' is a non-shared mount. A new mount 'C'420	which is a clone of 'A' is created. Its root dentry is 'a'. 'C' is421	mounted on mount 'B' at dentry 'b'.  'C' is made a member of the422	peer-group of 'A'.423 424    7. 'A' is a slave mount of mount 'Z' and 'B' is a non-shared mount. A425	new mount 'C' which is a clone of 'A' is created. Its root dentry is426	'a'.  'C' is mounted on mount 'B' at dentry 'b'. Also 'C' is set as a427	slave mount of 'Z'. In other words 'A' and 'C' are both slave mounts of428	'Z'.  All mount/unmount events on 'Z' propagates to 'A' and 'C'. But429	mount/unmount on 'A' do not propagate anywhere else. Similarly430	mount/unmount on 'C' do not propagate anywhere else.431 432    8. 'A' is a unbindable mount and 'B' is a non-shared mount. This is a433	invalid operation. A unbindable mount cannot be bind mounted.434 4355c) Rbind semantics436 437	rbind is same as bind. Bind replicates the specified mount.  Rbind438	replicates all the mounts in the tree belonging to the specified mount.439	Rbind mount is bind mount applied to all the mounts in the tree.440 441	If the source tree that is rbind has some unbindable mounts,442	then the subtree under the unbindable mount is pruned in the new443	location.444 445	eg:446 447	  let's say we have the following mount tree::448 449		A450	      /   \451	      B   C452	     / \ / \453	     D E F G454 455	  Let's say all the mount except the mount C in the tree are456	  of a type other than unbindable.457 458	  If this tree is rbound to say Z459 460	  We will have the following tree at the new location::461 462		Z463		|464		A'465	       /466	      B'		Note how the tree under C is pruned467	     / \ 		in the new location.468	    D' E'469 470 471 4725d) Move semantics473 474	Consider the following command475 476	mount --move A  B/b477 478	where 'A' is the source mount, 'B' is the destination mount and 'b' is479	the dentry in the destination mount.480 481	The outcome depends on the type of the mount of 'A' and 'B'. The table482	below is a quick reference::483 484	    ---------------------------------------------------------------------------485	    |         		MOVE MOUNT OPERATION                                 |486	    |**************************************************************************487	    | source(A)->| shared      |       private  |       slave    | unbindable |488	    | dest(B)  |               |                |                |            |489	    |   |      |               |                |                |            |490	    |   v      |               |                |                |            |491	    |**************************************************************************492	    |  shared  | shared        |     shared     |shared and slave|  invalid   |493	    |          |               |                |                |            |494	    |non-shared| shared        |      private   |    slave       | unbindable |495	    ***************************************************************************496 497	.. Note:: moving a mount residing under a shared mount is invalid.498 499      Details follow:500 501    1. 'A' is a shared mount and 'B' is a shared mount.  The mount 'A' is502	mounted on mount 'B' at dentry 'b'.  Also new mounts 'A1', 'A2'...'An'503	are created and mounted at dentry 'b' on all mounts that receive504	propagation from mount 'B'. A new propagation tree is created in the505	exact same configuration as that of 'B'. This new propagation tree506	contains all the new mounts 'A1', 'A2'...  'An'.  And this new507	propagation tree is appended to the already existing propagation tree508	of 'A'.509 510    2. 'A' is a private mount and 'B' is a shared mount. The mount 'A' is511	mounted on mount 'B' at dentry 'b'. Also new mount 'A1', 'A2'... 'An'512	are created and mounted at dentry 'b' on all mounts that receive513	propagation from mount 'B'. The mount 'A' becomes a shared mount and a514	propagation tree is created which is identical to that of515	'B'. This new propagation tree contains all the new mounts 'A1',516	'A2'...  'An'.517 518    3. 'A' is a slave mount of mount 'Z' and 'B' is a shared mount.  The519	mount 'A' is mounted on mount 'B' at dentry 'b'.  Also new mounts 'A1',520	'A2'... 'An' are created and mounted at dentry 'b' on all mounts that521	receive propagation from mount 'B'. A new propagation tree is created522	in the exact same configuration as that of 'B'. This new propagation523	tree contains all the new mounts 'A1', 'A2'...  'An'.  And this new524	propagation tree is appended to the already existing propagation tree of525	'A'.  Mount 'A' continues to be the slave mount of 'Z' but it also526	becomes 'shared'.527 528    4. 'A' is a unbindable mount and 'B' is a shared mount. The operation529	is invalid. Because mounting anything on the shared mount 'B' can530	create new mounts that get mounted on the mounts that receive531	propagation from 'B'.  And since the mount 'A' is unbindable, cloning532	it to mount at other mountpoints is not possible.533 534    5. 'A' is a private mount and 'B' is a non-shared(private or slave or535	unbindable) mount. The mount 'A' is mounted on mount 'B' at dentry 'b'.536 537    6. 'A' is a shared mount and 'B' is a non-shared mount.  The mount 'A'538	is mounted on mount 'B' at dentry 'b'.  Mount 'A' continues to be a539	shared mount.540 541    7. 'A' is a slave mount of mount 'Z' and 'B' is a non-shared mount.542	The mount 'A' is mounted on mount 'B' at dentry 'b'.  Mount 'A'543	continues to be a slave mount of mount 'Z'.544 545    8. 'A' is a unbindable mount and 'B' is a non-shared mount. The mount546	'A' is mounted on mount 'B' at dentry 'b'. Mount 'A' continues to be a547	unbindable mount.548 5495e) Mount semantics550 551	Consider the following command::552 553	    mount device  B/b554 555	'B' is the destination mount and 'b' is the dentry in the destination556	mount.557 558	The above operation is the same as bind operation with the exception559	that the source mount is always a private mount.560 561 5625f) Unmount semantics563 564	Consider the following command::565 566	    umount A567 568	where 'A' is a mount mounted on mount 'B' at dentry 'b'.569 570	If mount 'B' is shared, then all most-recently-mounted mounts at dentry571	'b' on mounts that receive propagation from mount 'B' and does not have572	sub-mounts within them are unmounted.573 574	Example: Let's say 'B1', 'B2', 'B3' are shared mounts that propagate to575	each other.576 577	let's say 'A1', 'A2', 'A3' are first mounted at dentry 'b' on mount578	'B1', 'B2' and 'B3' respectively.579 580	let's say 'C1', 'C2', 'C3' are next mounted at the same dentry 'b' on581	mount 'B1', 'B2' and 'B3' respectively.582 583	if 'C1' is unmounted, all the mounts that are most-recently-mounted on584	'B1' and on the mounts that 'B1' propagates-to are unmounted.585 586	'B1' propagates to 'B2' and 'B3'. And the most recently mounted mount587	on 'B2' at dentry 'b' is 'C2', and that of mount 'B3' is 'C3'.588 589	So all 'C1', 'C2' and 'C3' should be unmounted.590 591	If any of 'C2' or 'C3' has some child mounts, then that mount is not592	unmounted, but all other mounts are unmounted. However if 'C1' is told593	to be unmounted and 'C1' has some sub-mounts, the umount operation is594	failed entirely.595 5965g) Clone Namespace597 598	A cloned namespace contains all the mounts as that of the parent599	namespace.600 601	Let's say 'A' and 'B' are the corresponding mounts in the parent and the602	child namespace.603 604	If 'A' is shared, then 'B' is also shared and 'A' and 'B' propagate to605	each other.606 607	If 'A' is a slave mount of 'Z', then 'B' is also the slave mount of608	'Z'.609 610	If 'A' is a private mount, then 'B' is a private mount too.611 612	If 'A' is unbindable mount, then 'B' is a unbindable mount too.613 614 6156) Quiz616-------617 618	A. What is the result of the following command sequence?619 620		::621 622		    mount --bind /mnt /mnt623		    mount --make-shared /mnt624		    mount --bind /mnt /tmp625		    mount --move /tmp /mnt/1626 627		what should be the contents of /mnt /mnt/1 /mnt/1/1 should be?628		Should they all be identical? or should /mnt and /mnt/1 be629		identical only?630 631 632	B. What is the result of the following command sequence?633 634		::635 636		    mount --make-rshared /637		    mkdir -p /v/1638		    mount --rbind / /v/1639 640		what should be the content of /v/1/v/1 be?641 642 643	C. What is the result of the following command sequence?644 645		::646 647		    mount --bind /mnt /mnt648		    mount --make-shared /mnt649		    mkdir -p /mnt/1/2/3 /mnt/1/test650		    mount --bind /mnt/1 /tmp651		    mount --make-slave /mnt652		    mount --make-shared /mnt653		    mount --bind /mnt/1/2 /tmp1654		    mount --make-slave /mnt655 656		At this point we have the first mount at /tmp and657		its root dentry is 1. Let's call this mount 'A'658		And then we have a second mount at /tmp1 with root659		dentry 2. Let's call this mount 'B'660		Next we have a third mount at /mnt with root dentry661		mnt. Let's call this mount 'C'662 663		'B' is the slave of 'A' and 'C' is a slave of 'B'664		A -> B -> C665 666		at this point if we execute the following command667 668		mount --bind /bin /tmp/test669 670		The mount is attempted on 'A'671 672		will the mount propagate to 'B' and 'C' ?673 674		what would be the contents of675		/mnt/1/test be?676 6777) FAQ678------679 680	Q1. Why is bind mount needed? How is it different from symbolic links?681		symbolic links can get stale if the destination mount gets682		unmounted or moved. Bind mounts continue to exist even if the683		other mount is unmounted or moved.684 685	Q2. Why can't the shared subtree be implemented using exportfs?686 687		exportfs is a heavyweight way of accomplishing part of what688		shared subtree can do. I cannot imagine a way to implement the689		semantics of slave mount using exportfs?690 691	Q3 Why is unbindable mount needed?692 693		Let's say we want to replicate the mount tree at multiple694		locations within the same subtree.695 696		if one rbind mounts a tree within the same subtree 'n' times697		the number of mounts created is an exponential function of 'n'.698		Having unbindable mount can help prune the unneeded bind699		mounts. Here is an example.700 701		step 1:702		   let's say the root tree has just two directories with703		   one vfsmount::704 705				    root706				   /    \707				  tmp    usr708 709		    And we want to replicate the tree at multiple710		    mountpoints under /root/tmp711 712		step 2:713		      ::714 715 716			mount --make-shared /root717 718			mkdir -p /tmp/m1719 720			mount --rbind /root /tmp/m1721 722		      the new tree now looks like this::723 724				    root725				   /    \726				 tmp    usr727				/728			       m1729			      /  \730			     tmp  usr731			     /732			    m1733 734			  it has two vfsmounts735 736		step 3:737		    ::738 739			    mkdir -p /tmp/m2740			    mount --rbind /root /tmp/m2741 742			the new tree now looks like this::743 744				      root745				     /    \746				   tmp     usr747				  /    \748				m1       m2749			       / \       /  \750			     tmp  usr   tmp  usr751			     / \          /752			    m1  m2      m1753				/ \     /  \754			      tmp usr  tmp   usr755			      /        / \756			     m1       m1  m2757			    /  \758			  tmp   usr759			  /  \760			 m1   m2761 762		       it has 6 vfsmounts763 764		step 4:765		      ::766			  mkdir -p /tmp/m3767			  mount --rbind /root /tmp/m3768 769			  I won't draw the tree..but it has 24 vfsmounts770 771 772		at step i the number of vfsmounts is V[i] = i*V[i-1].773		This is an exponential function. And this tree has way more774		mounts than what we really needed in the first place.775 776		One could use a series of umount at each step to prune777		out the unneeded mounts. But there is a better solution.778		Unclonable mounts come in handy here.779 780		step 1:781		   let's say the root tree has just two directories with782		   one vfsmount::783 784				    root785				   /    \786				  tmp    usr787 788		    How do we set up the same tree at multiple locations under789		    /root/tmp790 791		step 2:792		      ::793 794 795			mount --bind /root/tmp /root/tmp796 797			mount --make-rshared /root798			mount --make-unbindable /root/tmp799 800			mkdir -p /tmp/m1801 802			mount --rbind /root /tmp/m1803 804		      the new tree now looks like this::805 806				    root807				   /    \808				 tmp    usr809				/810			       m1811			      /  \812			     tmp  usr813 814		step 3:815		      ::816 817			    mkdir -p /tmp/m2818			    mount --rbind /root /tmp/m2819 820		      the new tree now looks like this::821 822				    root823				   /    \824				 tmp    usr825				/   \826			       m1     m2827			      /  \     / \828			     tmp  usr tmp usr829 830		step 4:831		      ::832 833			    mkdir -p /tmp/m3834			    mount --rbind /root /tmp/m3835 836		      the new tree now looks like this::837 838				    	  root839				      /    	  \840				     tmp    	   usr841			         /    \    \842			       m1     m2     m3843			      /  \     / \    /  \844			     tmp  usr tmp usr tmp usr845 8468) Implementation847-----------------848 8498A) Datastructure850 851	4 new fields are introduced to struct vfsmount:852 853	*   ->mnt_share854	*   ->mnt_slave_list855	*   ->mnt_slave856	*   ->mnt_master857 858	->mnt_share859		links together all the mount to/from which this vfsmount860		send/receives propagation events.861 862	->mnt_slave_list863		links all the mounts to which this vfsmount propagates864		to.865 866	->mnt_slave867		links together all the slaves that its master vfsmount868		propagates to.869 870	->mnt_master871		points to the master vfsmount from which this vfsmount872		receives propagation.873 874	->mnt_flags875		takes two more flags to indicate the propagation status of876		the vfsmount.  MNT_SHARE indicates that the vfsmount is a shared877		vfsmount.  MNT_UNCLONABLE indicates that the vfsmount cannot be878		replicated.879 880	All the shared vfsmounts in a peer group form a cyclic list through881	->mnt_share.882 883	All vfsmounts with the same ->mnt_master form on a cyclic list anchored884	in ->mnt_master->mnt_slave_list and going through ->mnt_slave.885 886	 ->mnt_master can point to arbitrary (and possibly different) members887	 of master peer group.  To find all immediate slaves of a peer group888	 you need to go through _all_ ->mnt_slave_list of its members.889	 Conceptually it's just a single set - distribution among the890	 individual lists does not affect propagation or the way propagation891	 tree is modified by operations.892 893	All vfsmounts in a peer group have the same ->mnt_master.  If it is894	non-NULL, they form a contiguous (ordered) segment of slave list.895 896	A example propagation tree looks as shown in the figure below.897	[ NOTE: Though it looks like a forest, if we consider all the shared898	mounts as a conceptual entity called 'pnode', it becomes a tree]::899 900 901		        A <--> B <--> C <---> D902		       /|\	      /|      |\903		      / F G	     J K      H I904		     /905		    E<-->K906			/|\907		       M L N908 909	In the above figure  A,B,C and D all are shared and propagate to each910	other.   'A' has got 3 slave mounts 'E' 'F' and 'G' 'C' has got 2 slave911	mounts 'J' and 'K'  and  'D' has got two slave mounts 'H' and 'I'.912	'E' is also shared with 'K' and they propagate to each other.  And913	'K' has 3 slaves 'M', 'L' and 'N'914 915	A's ->mnt_share links with the ->mnt_share of 'B' 'C' and 'D'916 917	A's ->mnt_slave_list links with ->mnt_slave of 'E', 'K', 'F' and 'G'918 919	E's ->mnt_share links with ->mnt_share of K920 921	'E', 'K', 'F', 'G' have their ->mnt_master point to struct vfsmount of 'A'922 923	'M', 'L', 'N' have their ->mnt_master point to struct vfsmount of 'K'924 925	K's ->mnt_slave_list links with ->mnt_slave of 'M', 'L' and 'N'926 927	C's ->mnt_slave_list links with ->mnt_slave of 'J' and 'K'928 929	J and K's ->mnt_master points to struct vfsmount of C930 931	and finally D's ->mnt_slave_list links with ->mnt_slave of 'H' and 'I'932 933	'H' and 'I' have their ->mnt_master pointing to struct vfsmount of 'D'.934 935 936	NOTE: The propagation tree is orthogonal to the mount tree.937 9388B Locking:939 940	->mnt_share, ->mnt_slave, ->mnt_slave_list, ->mnt_master are protected941	by namespace_sem (exclusive for modifications, shared for reading).942 943	Normally we have ->mnt_flags modifications serialized by vfsmount_lock.944	There are two exceptions: do_add_mount() and clone_mnt().945	The former modifies a vfsmount that has not been visible in any shared946	data structures yet.947	The latter holds namespace_sem and the only references to vfsmount948	are in lists that can't be traversed without namespace_sem.949 9508C Algorithm:951 952	The crux of the implementation resides in rbind/move operation.953 954	The overall algorithm breaks the operation into 3 phases: (look at955	attach_recursive_mnt() and propagate_mnt())956 957	1. prepare phase.958	2. commit phases.959	3. abort phases.960 961	Prepare phase:962 963	for each mount in the source tree:964 965		   a) Create the necessary number of mount trees to966		   	be attached to each of the mounts that receive967			propagation from the destination mount.968		   b) Do not attach any of the trees to its destination.969		      However note down its ->mnt_parent and ->mnt_mountpoint970		   c) Link all the new mounts to form a propagation tree that971		      is identical to the propagation tree of the destination972		      mount.973 974		   If this phase is successful, there should be 'n' new975		   propagation trees; where 'n' is the number of mounts in the976		   source tree.  Go to the commit phase977 978		   Also there should be 'm' new mount trees, where 'm' is979		   the number of mounts to which the destination mount980		   propagates to.981 982		   if any memory allocations fail, go to the abort phase.983 984	Commit phase985		attach each of the mount trees to their corresponding986		destination mounts.987 988	Abort phase989		delete all the newly created trees.990 991	.. Note::992	   all the propagation related functionality resides in the file pnode.c993 994 995------------------------------------------------------------------------996 997version 0.1  (created the initial document, Ram Pai linuxram@us.ibm.com)998 999version 0.2  (Incorporated comments from Al Viro)1000