mirror of https://github.com/torvalds/linux.git
convert devpts
Two kinds of objects there - ptmx and everything else (pty). The former is
created on mount and kept until the fs shutdown; the latter get created
and removed by tty layer (the references are borrowed into tty->driver_data).
The reference to ptmx dentry is also kept, but we only ever use it to
find ptmx inode on remount.
* turn d_add() into d_make_persistent() + dput() both in mknod_ptmx() and
in devpts_pty_new().
* turn dput() to d_make_discardable() in devpts_pty_kill().
* switch mknod_ptmx() to simple_{start,done}_creating().
* instead of storing in pts_fs_info a reference to ptmx dentry, store a reference
to its inode, seeing that this is what we use it for.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
b83431564d
commit
b4a76faf9d
|
|
@ -102,7 +102,7 @@ struct pts_fs_info {
|
||||||
struct ida allocated_ptys;
|
struct ida allocated_ptys;
|
||||||
struct pts_mount_opts mount_opts;
|
struct pts_mount_opts mount_opts;
|
||||||
struct super_block *sb;
|
struct super_block *sb;
|
||||||
struct dentry *ptmx_dentry;
|
struct inode *ptmx_inode; // borrowed
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct pts_fs_info *DEVPTS_SB(struct super_block *sb)
|
static inline struct pts_fs_info *DEVPTS_SB(struct super_block *sb)
|
||||||
|
|
@ -259,7 +259,6 @@ static int devpts_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
||||||
static int mknod_ptmx(struct super_block *sb, struct fs_context *fc)
|
static int mknod_ptmx(struct super_block *sb, struct fs_context *fc)
|
||||||
{
|
{
|
||||||
int mode;
|
int mode;
|
||||||
int rc = -ENOMEM;
|
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
struct dentry *root = sb->s_root;
|
struct dentry *root = sb->s_root;
|
||||||
|
|
@ -268,18 +267,10 @@ static int mknod_ptmx(struct super_block *sb, struct fs_context *fc)
|
||||||
kuid_t ptmx_uid = current_fsuid();
|
kuid_t ptmx_uid = current_fsuid();
|
||||||
kgid_t ptmx_gid = current_fsgid();
|
kgid_t ptmx_gid = current_fsgid();
|
||||||
|
|
||||||
inode_lock(d_inode(root));
|
dentry = simple_start_creating(root, "ptmx");
|
||||||
|
if (IS_ERR(dentry)) {
|
||||||
/* If we have already created ptmx node, return */
|
|
||||||
if (fsi->ptmx_dentry) {
|
|
||||||
rc = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
dentry = d_alloc_name(root, "ptmx");
|
|
||||||
if (!dentry) {
|
|
||||||
pr_err("Unable to alloc dentry for ptmx node\n");
|
pr_err("Unable to alloc dentry for ptmx node\n");
|
||||||
goto out;
|
return PTR_ERR(dentry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -287,9 +278,9 @@ static int mknod_ptmx(struct super_block *sb, struct fs_context *fc)
|
||||||
*/
|
*/
|
||||||
inode = new_inode(sb);
|
inode = new_inode(sb);
|
||||||
if (!inode) {
|
if (!inode) {
|
||||||
|
simple_done_creating(dentry);
|
||||||
pr_err("Unable to alloc inode for ptmx node\n");
|
pr_err("Unable to alloc inode for ptmx node\n");
|
||||||
dput(dentry);
|
return -ENOMEM;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inode->i_ino = 2;
|
inode->i_ino = 2;
|
||||||
|
|
@ -299,23 +290,18 @@ static int mknod_ptmx(struct super_block *sb, struct fs_context *fc)
|
||||||
init_special_inode(inode, mode, MKDEV(TTYAUX_MAJOR, 2));
|
init_special_inode(inode, mode, MKDEV(TTYAUX_MAJOR, 2));
|
||||||
inode->i_uid = ptmx_uid;
|
inode->i_uid = ptmx_uid;
|
||||||
inode->i_gid = ptmx_gid;
|
inode->i_gid = ptmx_gid;
|
||||||
|
fsi->ptmx_inode = inode;
|
||||||
|
|
||||||
d_add(dentry, inode);
|
d_make_persistent(dentry, inode);
|
||||||
|
|
||||||
fsi->ptmx_dentry = dentry;
|
simple_done_creating(dentry);
|
||||||
rc = 0;
|
|
||||||
out:
|
return 0;
|
||||||
inode_unlock(d_inode(root));
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_ptmx_mode(struct pts_fs_info *fsi)
|
static void update_ptmx_mode(struct pts_fs_info *fsi)
|
||||||
{
|
{
|
||||||
struct inode *inode;
|
fsi->ptmx_inode->i_mode = S_IFCHR|fsi->mount_opts.ptmxmode;
|
||||||
if (fsi->ptmx_dentry) {
|
|
||||||
inode = d_inode(fsi->ptmx_dentry);
|
|
||||||
inode->i_mode = S_IFCHR|fsi->mount_opts.ptmxmode;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int devpts_reconfigure(struct fs_context *fc)
|
static int devpts_reconfigure(struct fs_context *fc)
|
||||||
|
|
@ -461,7 +447,7 @@ static void devpts_kill_sb(struct super_block *sb)
|
||||||
if (fsi)
|
if (fsi)
|
||||||
ida_destroy(&fsi->allocated_ptys);
|
ida_destroy(&fsi->allocated_ptys);
|
||||||
kfree(fsi);
|
kfree(fsi);
|
||||||
kill_litter_super(sb);
|
kill_anon_super(sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct file_system_type devpts_fs_type = {
|
static struct file_system_type devpts_fs_type = {
|
||||||
|
|
@ -534,16 +520,15 @@ struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv)
|
||||||
sprintf(s, "%d", index);
|
sprintf(s, "%d", index);
|
||||||
|
|
||||||
dentry = d_alloc_name(root, s);
|
dentry = d_alloc_name(root, s);
|
||||||
if (dentry) {
|
if (!dentry) {
|
||||||
dentry->d_fsdata = priv;
|
|
||||||
d_add(dentry, inode);
|
|
||||||
fsnotify_create(d_inode(root), dentry);
|
|
||||||
} else {
|
|
||||||
iput(inode);
|
iput(inode);
|
||||||
dentry = ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
|
dentry->d_fsdata = priv;
|
||||||
return dentry;
|
d_make_persistent(dentry, inode);
|
||||||
|
fsnotify_create(d_inode(root), dentry);
|
||||||
|
dput(dentry);
|
||||||
|
return dentry; // borrowed
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -573,7 +558,7 @@ void devpts_pty_kill(struct dentry *dentry)
|
||||||
drop_nlink(dentry->d_inode);
|
drop_nlink(dentry->d_inode);
|
||||||
d_drop(dentry);
|
d_drop(dentry);
|
||||||
fsnotify_unlink(d_inode(dentry->d_parent), dentry);
|
fsnotify_unlink(d_inode(dentry->d_parent), dentry);
|
||||||
dput(dentry); /* d_alloc_name() in devpts_pty_new() */
|
d_make_discardable(dentry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init init_devpts_fs(void)
|
static int __init init_devpts_fs(void)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue