linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ram <linuxram@us.ibm.com>
To: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org,
	viro@parcelfarce.linux.theplanet.co.uk,
	Andrew Morton <akpm@osdl.org>,
	mike@waychison.com, bfields@fieldses.org,
	Miklos Szeredi <miklos@szeredi.hu>
Subject: [RFC PATCH 4/8] move a shared/private/slave/unclone tree
Date: Fri, 08 Jul 2005 03:25:51 -0700	[thread overview]
Message-ID: <1120817640.30164.49.camel@localhost> (raw)
In-Reply-To: <1120816521.30164.22.camel@localhost>

[-- Attachment #1: Type: text/plain, Size: 164 bytes --]


Adds ability to move a shared/private/slave/unclone tree to any other
shared/private/slave/unclone tree. Also incorporates the same behavior
for pivot_root()

RP


[-- Attachment #2: move.patch --]
[-- Type: text/x-patch, Size: 8297 bytes --]

Adds ability to move a shared/private/slave/unclone tree to any other
shared/private/slave/unclone tree. Also incorporates the same behavior
for pivot_root()

RP


Signed by Ram Pai (linuxram@us.ibm.com)

 namespace.c |  106 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 94 insertions(+), 12 deletions(-)

Index: 2.6.12/fs/namespace.c
===================================================================
--- 2.6.12.orig/fs/namespace.c
+++ 2.6.12/fs/namespace.c
@@ -656,9 +656,12 @@ static struct vfsmount *copy_tree(struct
 	return NULL;
 }
 
+
  /*
  *  @source_mnt : mount tree to be attached
  *  @nd		: place the mount tree @source_mnt is attached
+ *  @move	: use the move semantics if set, else use normal attach semantics
+ *                as explained below
  *
  *  NOTE: in the table below explains the semantics when a source vfsmount
  *  of a given type is attached to a destination vfsmount of a give type.
@@ -691,6 +694,34 @@ static struct vfsmount *copy_tree(struct
  * (+)  the mount will be propogated to the destination vfsmount
  *    	  and the new mount will be added to the source vfsmount's pnode.
  *
+ *  -----------------------------------------------------------------------------
+ *  |				MOVE MOUNT SEMANTICS				|
+ *  |***************************************************************************|
+ *  |  dest --> | shared	 |	private	     |   slave	    |unclonable	|
+ *  | source   	|		 |       	     |   	    |    	|
+ *  |   |   	|		 |       	     |   	    |    	|
+ *  |   v 	|		 |       	     |   	    |    	|
+ *  |***************************************************************************|
+ *  |	     	|		 |       	     |   	    |    	|
+ *  | shared 	| shared (++) 	 |      shared (+)   | shared (+)   | shared (+)|
+ *  |		|		 |       	     |   	    |    	|
+ *  |		|		 |       	     |   	    |    	|
+ *  | private	| shared (+)	 |      private	     | private 	    | private  	|
+ *  |		|		 |       	     |   	    |    	|
+ *  |		|		 |       	     |   	    |    	|
+ *  | slave	| shared (+++)	 |      slave        | slave   	    | slave    	|
+ *  |		|		 |       	     |   	    |    	|
+ *  |		|		 |       	     |   	    |    	|
+ *  | unclonable| unclonable	 |     unclonable    | unclonable   | unclonable|
+ *  |		|		 |       	     |   	    |    	|
+ *  |		|		 |       	     |   	    |    	|
+ *  |***************************************************************************|
+ *
+ * (+++)  the mount will be propogated to all the vfsmounts in the pnode tree
+ *    	  of the destination vfsmount, and all the new mounts will be
+ *    	  added to a new pnode , which will be a slave pnode of the
+ *    	  source vfsmount's pnode.
+ *
  * if the source mount is a tree, the operations explained above is applied to each
  * vfsmount in the tree.
  *
@@ -699,7 +730,7 @@ static struct vfsmount *copy_tree(struct
  *
   */
 static void
-attach_recursive_mnt(struct vfsmount *source_mnt, struct nameidata *nd)
+attach_recursive_mnt(struct vfsmount *source_mnt, struct nameidata *nd, int move)
 {
 	struct vfsmount *mntpt_mnt, *m, *p;
 	struct vfspnode *src_pnode, *t_p, *dest_pnode, *tmp_pnode;
@@ -729,6 +760,7 @@ attach_recursive_mnt(struct vfsmount *so
 	p = NULL;
 	for (m = source_mnt; m; m = next_mnt(m, source_mnt)) {
 		int unclone = IS_MNT_UNCLONABLE(m);
+		int slave = IS_MNT_SLAVE(m);
 
 		list_del_init(&m->mnt_list);
 
@@ -747,7 +779,7 @@ attach_recursive_mnt(struct vfsmount *so
 		p=m;
 		dest_pnode = IS_MNT_SHARED(mntpt_mnt) ?
 			mntpt_mnt->mnt_pnode : NULL;
-		src_pnode = (IS_MNT_SHARED(m))?
+		src_pnode = (IS_MNT_SHARED(m) || (move && dest_pnode && slave))?
 				m->mnt_pnode : NULL;
 
 		m->mnt_pnode = NULL;
@@ -766,14 +798,20 @@ attach_recursive_mnt(struct vfsmount *so
 			if (m == m->mnt_parent)
 				do_attach_prepare_mnt(mntpt_mnt,
 					mntpt_dentry, m, 0);
-			pnode_add_member_mnt(tmp_pnode, m);
-			if (unclone)
-				SET_MNT_UNCLONABLE(m);
+			if (move && slave)
+				pnode_add_slave_mnt(tmp_pnode, m);
+			else {
+				pnode_add_member_mnt(tmp_pnode, m);
+				if (unclone)
+					SET_MNT_UNCLONABLE(m);
+			}
 		}
 
 		if ((!src_pnode && !dest_pnode) || unclone)
 			SET_PNODE_DELETE(tmp_pnode);
 		tmp_pnode->pnode_master = src_pnode;
+		if (move && dest_pnode && slave)
+			SET_PNODE_SLAVE(tmp_pnode);
 		/*
 		 * temporarily track the pnode with which the tmp_pnode
 		 * has to merge with; in the pnode_master field.
@@ -787,12 +825,16 @@ attach_recursive_mnt(struct vfsmount *so
 	spin_lock(&vfsmount_lock);
 	list_for_each_entry_safe(tmp_pnode, t_p, &pnodehead, pnode_peer_slave) {
 		int del_flag = IS_PNODE_DELETE(tmp_pnode);
+		int slave_flag = IS_PNODE_SLAVE(tmp_pnode);
 		struct vfspnode *master_pnode = tmp_pnode->pnode_master;
 		list_del_init(&tmp_pnode->pnode_peer_slave);
 		pnode_real_mount(tmp_pnode, del_flag);
 		if (!del_flag && master_pnode) {
 			tmp_pnode->pnode_master = NULL;
-			pnode_merge_pnode(tmp_pnode, master_pnode);
+			if (slave_flag)
+				pnode_add_slave_pnode(master_pnode, tmp_pnode);
+			else
+				pnode_merge_pnode(tmp_pnode, master_pnode);
 			/*
 			 * we don't need the extra reference to
 			 * the master_pnode, that was created either
@@ -809,6 +851,18 @@ out:
 	return;
 }
 
+static void
+detach_recursive_mnt(struct vfsmount *source_mnt, struct nameidata *nd)
+{
+	struct vfsmount *m;
+
+	detach_mnt(source_mnt, nd);
+	for (m = source_mnt; m; m = next_mnt(m, source_mnt)) {
+		list_del_init(&m->mnt_pnode_mntlist);
+	}
+	return;
+}
+
 static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
 {
 	int err, ret;
@@ -835,7 +889,7 @@ static int graft_tree(struct vfsmount *m
 	ret = (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry));
 	spin_unlock(&vfsmount_lock);
 	if (ret) {
-		attach_recursive_mnt(mnt, nd);
+		attach_recursive_mnt(mnt, nd, 0);
 		err = 0;
 	}
 out_unlock:
@@ -1195,6 +1249,12 @@ static int do_move_mount(struct nameidat
 	if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
 	      S_ISDIR(old_nd.dentry->d_inode->i_mode))
 		goto out2;
+	/*
+	 * Don't move a mount in a shared parent.
+	 */
+	if(old_nd.mnt->mnt_parent &&
+		IS_MNT_SHARED(old_nd.mnt->mnt_parent))
+		goto out2;
 
 	err = -ELOOP;
 	for (p = nd->mnt; p->mnt_parent!=p; p = p->mnt_parent)
@@ -1202,8 +1262,14 @@ static int do_move_mount(struct nameidat
 			goto out2;
 	err = 0;
 
-	detach_mnt(old_nd.mnt, &parent_nd);
-	attach_mnt(old_nd.mnt, nd);
+	detach_recursive_mnt(old_nd.mnt, &parent_nd);
+	if(IS_MNT_SHARED(nd->mnt)) {
+		spin_unlock(&vfsmount_lock);
+		attach_recursive_mnt(old_nd.mnt, nd, 1);
+		spin_lock(&vfsmount_lock);
+		mntput(old_nd.mnt);
+	} else
+		attach_mnt(old_nd.mnt, nd);
 
 	/* if the mount is moved, it should no longer be expire
 	 * automatically */
@@ -1794,6 +1860,16 @@ asmlinkage long sys_pivot_root(const cha
 		goto out2; /* not a mountpoint */
 	if (new_nd.mnt->mnt_root != new_nd.dentry)
 		goto out2; /* not a mountpoint */
+	/*
+	 * Don't move a mount in a shared parent.
+	 */
+	if(user_nd.mnt->mnt_parent &&
+		IS_MNT_SHARED(user_nd.mnt->mnt_parent))
+		goto out2;
+	if(new_nd.mnt->mnt_parent &&
+		IS_MNT_SHARED(new_nd.mnt->mnt_parent))
+		goto out2;
+
 	tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */
 	spin_lock(&vfsmount_lock);
 	if (tmp != new_nd.mnt) {
@@ -1808,10 +1884,22 @@ asmlinkage long sys_pivot_root(const cha
 			goto out3;
 	} else if (!is_subdir(old_nd.dentry, new_nd.dentry))
 		goto out3;
-	detach_mnt(new_nd.mnt, &parent_nd);
-	detach_mnt(user_nd.mnt, &root_parent);
-	attach_mnt(user_nd.mnt, &old_nd);     /* mount old root on put_old */
-	attach_mnt(new_nd.mnt, &root_parent); /* mount new_root on / */
+	detach_recursive_mnt(new_nd.mnt, &parent_nd);
+	detach_recursive_mnt(user_nd.mnt, &root_parent);
+ 	if(IS_MNT_SHARED(old_nd.mnt)) {
+		spin_unlock(&vfsmount_lock);
+ 		attach_recursive_mnt(user_nd.mnt, &old_nd, 1);
+		spin_lock(&vfsmount_lock);
+ 		mntput(user_nd.mnt);
+	} else
+ 		attach_mnt(user_nd.mnt, &old_nd);
+ 	if(IS_MNT_SHARED(root_parent.mnt)) {
+		spin_unlock(&vfsmount_lock);
+ 		attach_recursive_mnt(new_nd.mnt, &root_parent, 1);
+		spin_lock(&vfsmount_lock);
+ 		mntput(new_nd.mnt);
+	} else
+ 		attach_mnt(new_nd.mnt, &root_parent);
 	spin_unlock(&vfsmount_lock);
 	chroot_fs_refs(&user_nd, &new_nd);
 	security_sb_post_pivotroot(&user_nd, &new_nd);

  parent reply	other threads:[~2005-07-08 10:50 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1120816072.30164.10.camel@localhost>
2005-07-08 10:25 ` [RFC PATCH 0/8] shared subtree Ram
     [not found] ` <1120816229.30164.13.camel@localhost>
2005-07-08 10:25   ` [RFC PATCH 1/8] share/private/slave a subtree Ram
2005-07-08 11:17     ` Pekka Enberg
2005-07-08 12:19       ` Roman Zippel
2005-07-08 12:26         ` Pekka J Enberg
2005-07-08 12:46           ` Roman Zippel
2005-07-08 12:58             ` Pekka J Enberg
2005-07-08 13:34               ` Roman Zippel
2005-07-08 16:17                 ` Pekka Enberg
2005-07-08 16:33                 ` share/private/slave a subtree - define vs enum Bryan Henderson
2005-07-08 16:57                   ` Roman Zippel
2005-07-08 17:16                     ` Bryan Henderson
2005-07-08 18:21                       ` Pekka J Enberg
2005-07-08 19:11                         ` Roman Zippel
2005-07-08 19:33                           ` Pekka Enberg
2005-07-08 19:59                             ` Roman Zippel
2005-07-10 18:21                               ` Pekka Enberg
2005-07-10 18:40                                 ` randy_dunlap
2005-07-10 19:14                                 ` Roman Zippel
2005-07-11  6:37                                   ` Pekka J Enberg
2005-07-11 17:13                                   ` Horst von Brand
2005-07-11 17:57                                     ` Roman Zippel
2005-07-10 19:16                                 ` Vojtech Pavlik
2005-07-11 17:18                                   ` Horst von Brand
2005-07-08 19:38                           ` Ram
2005-07-08 22:12                         ` Bryan Henderson
2005-07-10 10:55                     ` Denis Vlasenko
2005-07-08 18:03                   ` Wichert Akkerman
2005-07-08 18:10                     ` Mike Waychison
2005-07-08 18:15                       ` Wichert Akkerman
2005-07-08 20:23                         ` Mike Waychison
2005-07-10 21:57                           ` Pavel Machek
2005-07-08 16:29       ` [RFC PATCH 1/8] share/private/slave a subtree Ram
2005-07-08 14:32     ` Miklos Szeredi
2005-07-08 16:19       ` Ram
2005-07-08 16:51         ` Miklos Szeredi
2005-07-08 17:52           ` Ram
2005-07-08 19:49             ` Miklos Szeredi
2005-07-14  1:27               ` Ram
2005-07-18 11:06                 ` shared subtrees implementation writeup Miklos Szeredi
2005-07-18 17:18                   ` Ram Pai
     [not found]   ` <1120816355.30164.16.camel@localhost>
2005-07-08 10:25     ` [RFC PATCH 2/8] unclone a subtree Ram
     [not found]     ` <1120816436.30164.19.camel@localhost>
2005-07-08 10:25       ` [RFC PATCH 3/8] bind/rbind a shared/private/slave/unclone tree Ram
     [not found]       ` <1120816521.30164.22.camel@localhost>
2005-07-08 10:25         ` Ram [this message]
     [not found]         ` <1120816600.30164.25.camel@localhost>
2005-07-08 10:25           ` [RFC PATCH 5/8] umount " Ram
     [not found]           ` <1120816720.30164.28.camel@localhost>
2005-07-08 10:26             ` [RFC PATCH 6/8] clone a namespace containing " Ram
     [not found]             ` <1120816835.30164.31.camel@localhost>
2005-07-08 10:26               ` [RFC PATCH 7/8] automounter support for shared/slave/private/unclone Ram
2005-07-08 10:26                 ` [RFC PATCH 8/8] pnode.c optimization Ram

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=1120817640.30164.49.camel@localhost \
    --to=linuxram@us.ibm.com \
    --cc=akpm@osdl.org \
    --cc=bfields@fieldses.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mike@waychison.com \
    --cc=miklos@szeredi.hu \
    --cc=viro@parcelfarce.linux.theplanet.co.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).