Define get_init_pts_sb()
See comments in the function header for details. The new interface will be used in a follow-on patch. Changelog [v2]: [Dave Hansen] Replace get_sb_ref() in fs/super.c with get_init_pts_sb() and make the new interface private to devpts Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com> Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
1f8f1e2965
commit
d4076ac55b
|
@ -305,10 +305,63 @@ fail:
|
||||||
return -ENOMEM;
|
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,
|
static int devpts_get_sb(struct file_system_type *fs_type,
|
||||||
int flags, const char *dev_name, void *data, struct vfsmount *mnt)
|
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)
|
static void devpts_kill_sb(struct super_block *sb)
|
||||||
|
|
Loading…
Reference in New Issue