Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 125032
b: refs/heads/master
c: d4076ac
h: refs/heads/master
v: v3
  • Loading branch information
Sukadev Bhattiprolu authored and Linus Torvalds committed Jan 2, 2009
1 parent f99585b commit c3db250
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1f8f1e296583f9f832c2fe7b5a219675b74bf43e
refs/heads/master: d4076ac55bf8755ce6c5706478631c1726cf0179
55 changes: 54 additions & 1 deletion trunk/fs/devpts/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,10 +305,63 @@ devpts_fill_super(struct super_block *s, void *data, int silent)
return -ENOMEM;
}

static int compare_init_pts_sb(struct super_block *s, void *p)
{
if (devpts_mnt)
return devpts_mnt->mnt_sb == s;

return 0;
}

/*
* get_init_pts_sb()
*
* This interface is needed to support multiple namespace semantics in
* devpts while preserving backward compatibility of the current 'single-
* namespace' semantics. i.e all mounts of devpts without the 'newinstance'
* mount option should bind to the initial kernel mount, like
* get_sb_single().
*
* Mounts with 'newinstance' option create a new private namespace.
*
* But for single-mount semantics, devpts cannot use get_sb_single(),
* because get_sb_single()/sget() find and use the super-block from
* the most recent mount of devpts. But that recent mount may be a
* 'newinstance' mount and get_sb_single() would pick the newinstance
* super-block instead of the initial super-block.
*
* This interface is identical to get_sb_single() except that it
* consistently selects the 'single-namespace' superblock even in the
* presence of the private namespace (i.e 'newinstance') super-blocks.
*/
static int get_init_pts_sb(struct file_system_type *fs_type, int flags,
void *data, struct vfsmount *mnt)
{
struct super_block *s;
int error;

s = sget(fs_type, compare_init_pts_sb, set_anon_super, NULL);
if (IS_ERR(s))
return PTR_ERR(s);

if (!s->s_root) {
s->s_flags = flags;
error = devpts_fill_super(s, data, flags & MS_SILENT ? 1 : 0);
if (error) {
up_write(&s->s_umount);
deactivate_super(s);
return error;
}
s->s_flags |= MS_ACTIVE;
}
do_remount_sb(s, flags, data, 0);
return simple_set_mnt(mnt, s);
}

static int devpts_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data, struct vfsmount *mnt)
{
return get_sb_single(fs_type, flags, data, devpts_fill_super, mnt);
return get_init_pts_sb(fs_type, flags, data, mnt);
}

static void devpts_kill_sb(struct super_block *sb)
Expand Down

0 comments on commit c3db250

Please sign in to comment.