diff options
author | Ram Pai <linuxram@us.ibm.com> | 2005-11-07 17:19:33 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-07 21:18:10 -0500 |
commit | 03e06e68ff76294e53ffa898cb844d2a997b043e (patch) | |
tree | df17444b2c9b89e1eed75e09d46ea36c40ebd1df | |
parent | 07b20889e3052c7e77d6a6a54e7e83446eb1ba84 (diff) |
[PATCH] introduce shared mounts
This creates shared mounts. A shared mount when bind-mounted to some
mountpoint, propagates mount/umount events to each other. All the
shared mounts that propagate events to each other belong to the same
peer-group.
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>
-rw-r--r-- | fs/namespace.c | 3 | ||||
-rw-r--r-- | fs/pnode.c | 13 | ||||
-rw-r--r-- | fs/pnode.h | 4 | ||||
-rw-r--r-- | include/linux/fs.h | 1 | ||||
-rw-r--r-- | include/linux/mount.h | 2 |
5 files changed, 21 insertions, 2 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 3782923d6d4d..f6861a5487df 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -68,6 +68,7 @@ struct vfsmount *alloc_vfsmnt(const char *name) | |||
68 | INIT_LIST_HEAD(&mnt->mnt_mounts); | 68 | INIT_LIST_HEAD(&mnt->mnt_mounts); |
69 | INIT_LIST_HEAD(&mnt->mnt_list); | 69 | INIT_LIST_HEAD(&mnt->mnt_list); |
70 | INIT_LIST_HEAD(&mnt->mnt_expire); | 70 | INIT_LIST_HEAD(&mnt->mnt_expire); |
71 | INIT_LIST_HEAD(&mnt->mnt_share); | ||
71 | if (name) { | 72 | if (name) { |
72 | int size = strlen(name) + 1; | 73 | int size = strlen(name) + 1; |
73 | char *newname = kmalloc(size, GFP_KERNEL); | 74 | char *newname = kmalloc(size, GFP_KERNEL); |
@@ -1113,7 +1114,7 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, | |||
1113 | data_page); | 1114 | data_page); |
1114 | else if (flags & MS_BIND) | 1115 | else if (flags & MS_BIND) |
1115 | retval = do_loopback(&nd, dev_name, flags & MS_REC); | 1116 | retval = do_loopback(&nd, dev_name, flags & MS_REC); |
1116 | else if (flags & MS_PRIVATE) | 1117 | else if (flags & (MS_SHARED | MS_PRIVATE)) |
1117 | retval = do_change_type(&nd, flags); | 1118 | retval = do_change_type(&nd, flags); |
1118 | else if (flags & MS_MOVE) | 1119 | else if (flags & MS_MOVE) |
1119 | retval = do_move_mount(&nd, dev_name); | 1120 | retval = do_move_mount(&nd, dev_name); |
diff --git a/fs/pnode.c b/fs/pnode.c index aaa0dffda12a..1e22165ea41f 100644 --- a/fs/pnode.c +++ b/fs/pnode.c | |||
@@ -11,7 +11,18 @@ | |||
11 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
12 | #include "pnode.h" | 12 | #include "pnode.h" |
13 | 13 | ||
14 | /* return the next shared peer mount of @p */ | ||
15 | static inline struct vfsmount *next_peer(struct vfsmount *p) | ||
16 | { | ||
17 | return list_entry(p->mnt_share.next, struct vfsmount, mnt_share); | ||
18 | } | ||
19 | |||
14 | void change_mnt_propagation(struct vfsmount *mnt, int type) | 20 | void change_mnt_propagation(struct vfsmount *mnt, int type) |
15 | { | 21 | { |
16 | mnt->mnt_flags &= ~MNT_PNODE_MASK; | 22 | if (type == MS_SHARED) { |
23 | mnt->mnt_flags |= MNT_SHARED; | ||
24 | } else { | ||
25 | list_del_init(&mnt->mnt_share); | ||
26 | mnt->mnt_flags &= ~MNT_PNODE_MASK; | ||
27 | } | ||
17 | } | 28 | } |
diff --git a/fs/pnode.h b/fs/pnode.h index 33549a3a74eb..ab1bdaee4e08 100644 --- a/fs/pnode.h +++ b/fs/pnode.h | |||
@@ -10,5 +10,9 @@ | |||
10 | 10 | ||
11 | #include <linux/list.h> | 11 | #include <linux/list.h> |
12 | #include <linux/mount.h> | 12 | #include <linux/mount.h> |
13 | |||
14 | #define IS_MNT_SHARED(mnt) (mnt->mnt_flags & MNT_SHARED) | ||
15 | #define CLEAR_MNT_SHARED(mnt) (mnt->mnt_flags &= ~MNT_SHARED) | ||
16 | |||
13 | void change_mnt_propagation(struct vfsmount *, int); | 17 | void change_mnt_propagation(struct vfsmount *, int); |
14 | #endif /* _LINUX_PNODE_H */ | 18 | #endif /* _LINUX_PNODE_H */ |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 6c431086abb3..551fba303cf8 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -105,6 +105,7 @@ extern int dir_notify_enable; | |||
105 | #define MS_REC 16384 | 105 | #define MS_REC 16384 |
106 | #define MS_VERBOSE 32768 | 106 | #define MS_VERBOSE 32768 |
107 | #define MS_PRIVATE (1<<18) /* change to private */ | 107 | #define MS_PRIVATE (1<<18) /* change to private */ |
108 | #define MS_SHARED (1<<20) /* change to shared */ | ||
108 | #define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ | 109 | #define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ |
109 | #define MS_ACTIVE (1<<30) | 110 | #define MS_ACTIVE (1<<30) |
110 | #define MS_NOUSER (1<<31) | 111 | #define MS_NOUSER (1<<31) |
diff --git a/include/linux/mount.h b/include/linux/mount.h index 8eadd3b65899..2582559718fc 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #define MNT_NOSUID 0x01 | 20 | #define MNT_NOSUID 0x01 |
21 | #define MNT_NODEV 0x02 | 21 | #define MNT_NODEV 0x02 |
22 | #define MNT_NOEXEC 0x04 | 22 | #define MNT_NOEXEC 0x04 |
23 | #define MNT_SHARED 0x10 /* if the vfsmount is a shared mount */ | ||
23 | #define MNT_PNODE_MASK 0x30 /* propogation flag mask */ | 24 | #define MNT_PNODE_MASK 0x30 /* propogation flag mask */ |
24 | 25 | ||
25 | struct vfsmount { | 26 | struct vfsmount { |
@@ -36,6 +37,7 @@ struct vfsmount { | |||
36 | char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ | 37 | char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ |
37 | struct list_head mnt_list; | 38 | struct list_head mnt_list; |
38 | struct list_head mnt_expire; /* link in fs-specific expiry list */ | 39 | struct list_head mnt_expire; /* link in fs-specific expiry list */ |
40 | struct list_head mnt_share; /* circular list of shared mounts */ | ||
39 | struct namespace *mnt_namespace; /* containing namespace */ | 41 | struct namespace *mnt_namespace; /* containing namespace */ |
40 | int mnt_pinned; | 42 | int mnt_pinned; |
41 | }; | 43 | }; |