aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pnode.c
diff options
context:
space:
mode:
authorRam Pai <linuxram@us.ibm.com>2005-11-07 17:20:48 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 21:18:11 -0500
commita58b0eb8e64b78d9315a5491955e78b1391d42e5 (patch)
tree546f77cb0338c817ef1e34d8ebbc6eaf0e5d6be9 /fs/pnode.c
parenta05964f3917c7c55368c229d7985f8e7c9977e97 (diff)
[PATCH] introduce slave mounts
A slave mount always has a master mount from which it receives mount/umount events. Unlike shared mount the event propagation does not flow from the slave mount to the master. Signed-off-by: Ram Pai <linuxram@us.ibm.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/pnode.c')
-rw-r--r--fs/pnode.c54
1 files changed, 51 insertions, 3 deletions
diff --git a/fs/pnode.c b/fs/pnode.c
index 7bc942d047c..f73eba24f1d 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -17,13 +17,61 @@ static inline struct vfsmount *next_peer(struct vfsmount *p)
17 return list_entry(p->mnt_share.next, struct vfsmount, mnt_share); 17 return list_entry(p->mnt_share.next, struct vfsmount, mnt_share);
18} 18}
19 19
20static int do_make_slave(struct vfsmount *mnt)
21{
22 struct vfsmount *peer_mnt = mnt, *master = mnt->mnt_master;
23 struct vfsmount *slave_mnt;
24
25 /*
26 * slave 'mnt' to a peer mount that has the
27 * same root dentry. If none is available than
28 * slave it to anything that is available.
29 */
30 while ((peer_mnt = next_peer(peer_mnt)) != mnt &&
31 peer_mnt->mnt_root != mnt->mnt_root) ;
32
33 if (peer_mnt == mnt) {
34 peer_mnt = next_peer(mnt);
35 if (peer_mnt == mnt)
36 peer_mnt = NULL;
37 }
38 list_del_init(&mnt->mnt_share);
39
40 if (peer_mnt)
41 master = peer_mnt;
42
43 if (master) {
44 list_for_each_entry(slave_mnt, &mnt->mnt_slave_list, mnt_slave)
45 slave_mnt->mnt_master = master;
46 list_del(&mnt->mnt_slave);
47 list_add(&mnt->mnt_slave, &master->mnt_slave_list);
48 list_splice(&mnt->mnt_slave_list, master->mnt_slave_list.prev);
49 INIT_LIST_HEAD(&mnt->mnt_slave_list);
50 } else {
51 struct list_head *p = &mnt->mnt_slave_list;
52 while (!list_empty(p)) {
53 slave_mnt = list_entry(p->next,
54 struct vfsmount, mnt_slave);
55 list_del_init(&slave_mnt->mnt_slave);
56 slave_mnt->mnt_master = NULL;
57 }
58 }
59 mnt->mnt_master = master;
60 CLEAR_MNT_SHARED(mnt);
61 INIT_LIST_HEAD(&mnt->mnt_slave_list);
62 return 0;
63}
64
20void change_mnt_propagation(struct vfsmount *mnt, int type) 65void change_mnt_propagation(struct vfsmount *mnt, int type)
21{ 66{
22 if (type == MS_SHARED) { 67 if (type == MS_SHARED) {
23 set_mnt_shared(mnt); 68 set_mnt_shared(mnt);
24 } else { 69 return;
25 list_del_init(&mnt->mnt_share); 70 }
26 mnt->mnt_flags &= ~MNT_PNODE_MASK; 71 do_make_slave(mnt);
72 if (type != MS_SLAVE) {
73 list_del_init(&mnt->mnt_slave);
74 mnt->mnt_master = NULL;
27 } 75 }
28} 76}
29 77