diff -urN FS-private_mount/fs/namespace.c FS-shared_mount/fs/namespace.c --- FS-private_mount/fs/namespace.c 2005-11-03 07:19:12.000000000 -0500 +++ FS-shared_mount/fs/namespace.c 2005-11-03 07:20:53.000000000 -0500 @@ -68,6 +68,7 @@ INIT_LIST_HEAD(&mnt->mnt_mounts); INIT_LIST_HEAD(&mnt->mnt_list); INIT_LIST_HEAD(&mnt->mnt_expire); + INIT_LIST_HEAD(&mnt->mnt_share); if (name) { int size = strlen(name) + 1; char *newname = kmalloc(size, GFP_KERNEL); @@ -1113,7 +1114,7 @@ data_page); else if (flags & MS_BIND) retval = do_loopback(&nd, dev_name, flags & MS_REC); - else if (flags & MS_PRIVATE) + else if (flags & (MS_SHARED | MS_PRIVATE)) retval = do_change_type(&nd, flags); else if (flags & MS_MOVE) retval = do_move_mount(&nd, dev_name); diff -urN FS-private_mount/fs/pnode.c FS-shared_mount/fs/pnode.c --- FS-private_mount/fs/pnode.c 2005-11-03 06:59:21.000000000 -0500 +++ FS-shared_mount/fs/pnode.c 2005-11-03 06:59:23.000000000 -0500 @@ -11,7 +11,18 @@ #include #include "pnode.h" +/* return the next shared peer mount of @p */ +static inline struct vfsmount *next_peer(struct vfsmount *p) +{ + return list_entry(p->mnt_share.next, struct vfsmount, mnt_share); +} + void change_mnt_propagation(struct vfsmount *mnt, int type) { - mnt->mnt_flags &= ~MNT_PNODE_MASK; + if (type == MS_SHARED) { + mnt->mnt_flags |= MNT_SHARED; + } else { + list_del_init(&mnt->mnt_share); + mnt->mnt_flags &= ~MNT_PNODE_MASK; + } } diff -urN FS-private_mount/fs/pnode.h FS-shared_mount/fs/pnode.h --- FS-private_mount/fs/pnode.h 2005-11-03 06:59:21.000000000 -0500 +++ FS-shared_mount/fs/pnode.h 2005-11-03 06:59:23.000000000 -0500 @@ -10,5 +10,9 @@ #include #include + +#define IS_MNT_SHARED(mnt) (mnt->mnt_flags & MNT_SHARED) +#define CLEAR_MNT_SHARED(mnt) (mnt->mnt_flags &= ~MNT_SHARED) + void change_mnt_propagation(struct vfsmount *, int); #endif /* _LINUX_PNODE_H */ diff -urN FS-private_mount/include/linux/fs.h FS-shared_mount/include/linux/fs.h --- FS-private_mount/include/linux/fs.h 2005-11-03 06:59:21.000000000 -0500 +++ FS-shared_mount/include/linux/fs.h 2005-11-03 06:59:23.000000000 -0500 @@ -105,6 +105,7 @@ #define MS_REC 16384 #define MS_VERBOSE 32768 #define MS_PRIVATE (1<<18) /* change to private */ +#define MS_SHARED (1<<20) /* change to shared */ #define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ #define MS_ACTIVE (1<<30) #define MS_NOUSER (1<<31) diff -urN FS-private_mount/include/linux/mount.h FS-shared_mount/include/linux/mount.h --- FS-private_mount/include/linux/mount.h 2005-11-03 06:59:21.000000000 -0500 +++ FS-shared_mount/include/linux/mount.h 2005-11-03 06:59:23.000000000 -0500 @@ -20,6 +20,7 @@ #define MNT_NOSUID 0x01 #define MNT_NODEV 0x02 #define MNT_NOEXEC 0x04 +#define MNT_SHARED 0x10 /* if the vfsmount is a shared mount */ #define MNT_PNODE_MASK 0x30 /* propogation flag mask */ struct vfsmount { @@ -36,6 +37,7 @@ char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ struct list_head mnt_list; struct list_head mnt_expire; /* link in fs-specific expiry list */ + struct list_head mnt_share; /* circular list of shared mounts */ struct namespace *mnt_namespace; /* containing namespace */ int mnt_pinned; };