All of lore.kernel.org
 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 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.