mirror of https://github.com/torvalds/linux.git
tty: use lock guard()s in tty_io
guard()s and scoped_guard()s express more clearly what is protected by locks. And also makes the code cleaner as it can return immediately in case of short returns. Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org> Link: https://lore.kernel.org/r/20250425111315.1036184-3-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
3eabc1a34b
commit
f49573f2f5
|
|
@ -276,11 +276,10 @@ static void check_tty_count(struct tty_struct *tty, const char *routine)
|
||||||
struct list_head *p;
|
struct list_head *p;
|
||||||
int count = 0, kopen_count = 0;
|
int count = 0, kopen_count = 0;
|
||||||
|
|
||||||
spin_lock(&tty->files_lock);
|
scoped_guard(spinlock, &tty->files_lock)
|
||||||
list_for_each(p, &tty->tty_files) {
|
list_for_each(p, &tty->tty_files)
|
||||||
count++;
|
count++;
|
||||||
}
|
|
||||||
spin_unlock(&tty->files_lock);
|
|
||||||
if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
|
if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
|
||||||
tty->driver->subtype == PTY_TYPE_SLAVE &&
|
tty->driver->subtype == PTY_TYPE_SLAVE &&
|
||||||
tty->link && tty->link->count)
|
tty->link && tty->link->count)
|
||||||
|
|
@ -378,7 +377,7 @@ EXPORT_SYMBOL_GPL(tty_dev_name_to_number);
|
||||||
*/
|
*/
|
||||||
struct tty_driver *tty_find_polling_driver(char *name, int *line)
|
struct tty_driver *tty_find_polling_driver(char *name, int *line)
|
||||||
{
|
{
|
||||||
struct tty_driver *p, *res = NULL;
|
struct tty_driver *p;
|
||||||
int tty_line = 0;
|
int tty_line = 0;
|
||||||
int len;
|
int len;
|
||||||
char *str, *stp;
|
char *str, *stp;
|
||||||
|
|
@ -392,7 +391,8 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
|
||||||
len = str - name;
|
len = str - name;
|
||||||
tty_line = simple_strtoul(str, &str, 10);
|
tty_line = simple_strtoul(str, &str, 10);
|
||||||
|
|
||||||
mutex_lock(&tty_mutex);
|
guard(mutex)(&tty_mutex);
|
||||||
|
|
||||||
/* Search through the tty devices to look for a match */
|
/* Search through the tty devices to look for a match */
|
||||||
list_for_each_entry(p, &tty_drivers, tty_drivers) {
|
list_for_each_entry(p, &tty_drivers, tty_drivers) {
|
||||||
if (!len || strncmp(name, p->name, len) != 0)
|
if (!len || strncmp(name, p->name, len) != 0)
|
||||||
|
|
@ -405,14 +405,12 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
|
||||||
|
|
||||||
if (tty_line >= 0 && tty_line < p->num && p->ops &&
|
if (tty_line >= 0 && tty_line < p->num && p->ops &&
|
||||||
p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) {
|
p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) {
|
||||||
res = tty_driver_kref_get(p);
|
|
||||||
*line = tty_line;
|
*line = tty_line;
|
||||||
break;
|
return tty_driver_kref_get(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&tty_mutex);
|
|
||||||
|
|
||||||
return res;
|
return NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(tty_find_polling_driver);
|
EXPORT_SYMBOL_GPL(tty_find_polling_driver);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -531,16 +529,15 @@ EXPORT_SYMBOL_GPL(tty_wakeup);
|
||||||
*/
|
*/
|
||||||
static struct file *tty_release_redirect(struct tty_struct *tty)
|
static struct file *tty_release_redirect(struct tty_struct *tty)
|
||||||
{
|
{
|
||||||
struct file *f = NULL;
|
guard(spinlock)(&redirect_lock);
|
||||||
|
|
||||||
spin_lock(&redirect_lock);
|
|
||||||
if (redirect && file_tty(redirect) == tty) {
|
if (redirect && file_tty(redirect) == tty) {
|
||||||
f = redirect;
|
struct file *f = redirect;
|
||||||
redirect = NULL;
|
redirect = NULL;
|
||||||
|
return f;
|
||||||
}
|
}
|
||||||
spin_unlock(&redirect_lock);
|
|
||||||
|
|
||||||
return f;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -765,11 +762,8 @@ void __stop_tty(struct tty_struct *tty)
|
||||||
*/
|
*/
|
||||||
void stop_tty(struct tty_struct *tty)
|
void stop_tty(struct tty_struct *tty)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
guard(spinlock_irqsave)(&tty->flow.lock);
|
||||||
|
|
||||||
spin_lock_irqsave(&tty->flow.lock, flags);
|
|
||||||
__stop_tty(tty);
|
__stop_tty(tty);
|
||||||
spin_unlock_irqrestore(&tty->flow.lock, flags);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(stop_tty);
|
EXPORT_SYMBOL(stop_tty);
|
||||||
|
|
||||||
|
|
@ -796,11 +790,8 @@ void __start_tty(struct tty_struct *tty)
|
||||||
*/
|
*/
|
||||||
void start_tty(struct tty_struct *tty)
|
void start_tty(struct tty_struct *tty)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
guard(spinlock_irqsave)(&tty->flow.lock);
|
||||||
|
|
||||||
spin_lock_irqsave(&tty->flow.lock, flags);
|
|
||||||
__start_tty(tty);
|
__start_tty(tty);
|
||||||
spin_unlock_irqrestore(&tty->flow.lock, flags);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(start_tty);
|
EXPORT_SYMBOL(start_tty);
|
||||||
|
|
||||||
|
|
@ -809,7 +800,8 @@ static void tty_update_time(struct tty_struct *tty, bool mtime)
|
||||||
time64_t sec = ktime_get_real_seconds();
|
time64_t sec = ktime_get_real_seconds();
|
||||||
struct tty_file_private *priv;
|
struct tty_file_private *priv;
|
||||||
|
|
||||||
spin_lock(&tty->files_lock);
|
guard(spinlock)(&tty->files_lock);
|
||||||
|
|
||||||
list_for_each_entry(priv, &tty->tty_files, list) {
|
list_for_each_entry(priv, &tty->tty_files, list) {
|
||||||
struct inode *inode = file_inode(priv->file);
|
struct inode *inode = file_inode(priv->file);
|
||||||
struct timespec64 time = mtime ? inode_get_mtime(inode) : inode_get_atime(inode);
|
struct timespec64 time = mtime ? inode_get_mtime(inode) : inode_get_atime(inode);
|
||||||
|
|
@ -827,7 +819,6 @@ static void tty_update_time(struct tty_struct *tty, bool mtime)
|
||||||
inode_set_atime(inode, sec, 0);
|
inode_set_atime(inode, sec, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock(&tty->files_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -2314,13 +2305,12 @@ static int tiocsti(struct tty_struct *tty, u8 __user *p)
|
||||||
*/
|
*/
|
||||||
static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
|
static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
|
||||||
{
|
{
|
||||||
int err;
|
guard(mutex)(&tty->winsize_mutex);
|
||||||
|
|
||||||
mutex_lock(&tty->winsize_mutex);
|
if (copy_to_user(arg, &tty->winsize, sizeof(*arg)))
|
||||||
err = copy_to_user(arg, &tty->winsize, sizeof(*arg));
|
return -EFAULT;
|
||||||
mutex_unlock(&tty->winsize_mutex);
|
|
||||||
|
|
||||||
return err ? -EFAULT : 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2335,10 +2325,10 @@ int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
|
||||||
{
|
{
|
||||||
struct pid *pgrp;
|
struct pid *pgrp;
|
||||||
|
|
||||||
/* Lock the tty */
|
guard(mutex)(&tty->winsize_mutex);
|
||||||
mutex_lock(&tty->winsize_mutex);
|
|
||||||
if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
|
if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
|
||||||
goto done;
|
return 0;
|
||||||
|
|
||||||
/* Signal the foreground process group */
|
/* Signal the foreground process group */
|
||||||
pgrp = tty_get_pgrp(tty);
|
pgrp = tty_get_pgrp(tty);
|
||||||
|
|
@ -2347,8 +2337,7 @@ int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
|
||||||
put_pid(pgrp);
|
put_pid(pgrp);
|
||||||
|
|
||||||
tty->winsize = *ws;
|
tty->winsize = *ws;
|
||||||
done:
|
|
||||||
mutex_unlock(&tty->winsize_mutex);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(tty_do_resize);
|
EXPORT_SYMBOL(tty_do_resize);
|
||||||
|
|
@ -2409,13 +2398,14 @@ static int tioccons(struct file *file)
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
if (!(file->f_mode & FMODE_CAN_WRITE))
|
if (!(file->f_mode & FMODE_CAN_WRITE))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
spin_lock(&redirect_lock);
|
|
||||||
if (redirect) {
|
guard(spinlock)(&redirect_lock);
|
||||||
spin_unlock(&redirect_lock);
|
|
||||||
|
if (redirect)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
|
||||||
redirect = get_file(file);
|
redirect = get_file(file);
|
||||||
spin_unlock(&redirect_lock);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3028,11 +3018,9 @@ void __do_SAK(struct tty_struct *tty)
|
||||||
struct task_struct *g, *p;
|
struct task_struct *g, *p;
|
||||||
struct pid *session;
|
struct pid *session;
|
||||||
int i;
|
int i;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&tty->ctrl.lock, flags);
|
scoped_guard(spinlock_irqsave, &tty->ctrl.lock)
|
||||||
session = get_pid(tty->ctrl.session);
|
session = get_pid(tty->ctrl.session);
|
||||||
spin_unlock_irqrestore(&tty->ctrl.lock, flags);
|
|
||||||
|
|
||||||
tty_ldisc_flush(tty);
|
tty_ldisc_flush(tty);
|
||||||
|
|
||||||
|
|
@ -3055,7 +3043,7 @@ void __do_SAK(struct tty_struct *tty)
|
||||||
PIDTYPE_SID);
|
PIDTYPE_SID);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
task_lock(p);
|
guard(task_lock)(p);
|
||||||
i = iterate_fd(p->files, 0, this_tty, tty);
|
i = iterate_fd(p->files, 0, this_tty, tty);
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
tty_notice(tty, "SAK: killed process %d (%s): by fd#%d\n",
|
tty_notice(tty, "SAK: killed process %d (%s): by fd#%d\n",
|
||||||
|
|
@ -3063,7 +3051,6 @@ void __do_SAK(struct tty_struct *tty)
|
||||||
group_send_sig_info(SIGKILL, SEND_SIG_PRIV, p,
|
group_send_sig_info(SIGKILL, SEND_SIG_PRIV, p,
|
||||||
PIDTYPE_SID);
|
PIDTYPE_SID);
|
||||||
}
|
}
|
||||||
task_unlock(p);
|
|
||||||
}
|
}
|
||||||
read_unlock(&tasklist_lock);
|
read_unlock(&tasklist_lock);
|
||||||
put_pid(session);
|
put_pid(session);
|
||||||
|
|
@ -3465,9 +3452,8 @@ int tty_register_driver(struct tty_driver *driver)
|
||||||
goto err_unreg_char;
|
goto err_unreg_char;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&tty_mutex);
|
scoped_guard(mutex, &tty_mutex)
|
||||||
list_add(&driver->tty_drivers, &tty_drivers);
|
list_add(&driver->tty_drivers, &tty_drivers);
|
||||||
mutex_unlock(&tty_mutex);
|
|
||||||
|
|
||||||
if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) {
|
if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) {
|
||||||
for (i = 0; i < driver->num; i++) {
|
for (i = 0; i < driver->num; i++) {
|
||||||
|
|
@ -3486,9 +3472,8 @@ int tty_register_driver(struct tty_driver *driver)
|
||||||
for (i--; i >= 0; i--)
|
for (i--; i >= 0; i--)
|
||||||
tty_unregister_device(driver, i);
|
tty_unregister_device(driver, i);
|
||||||
|
|
||||||
mutex_lock(&tty_mutex);
|
scoped_guard(mutex, &tty_mutex)
|
||||||
list_del(&driver->tty_drivers);
|
list_del(&driver->tty_drivers);
|
||||||
mutex_unlock(&tty_mutex);
|
|
||||||
|
|
||||||
err_unreg_char:
|
err_unreg_char:
|
||||||
unregister_chrdev_region(dev, driver->num);
|
unregister_chrdev_region(dev, driver->num);
|
||||||
|
|
@ -3507,9 +3492,8 @@ void tty_unregister_driver(struct tty_driver *driver)
|
||||||
{
|
{
|
||||||
unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
|
unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
|
||||||
driver->num);
|
driver->num);
|
||||||
mutex_lock(&tty_mutex);
|
scoped_guard(mutex, &tty_mutex)
|
||||||
list_del(&driver->tty_drivers);
|
list_del(&driver->tty_drivers);
|
||||||
mutex_unlock(&tty_mutex);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(tty_unregister_driver);
|
EXPORT_SYMBOL(tty_unregister_driver);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue