mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	tty: Wait interruptibly for tty lock on reopen
Allow a signal to interrupt the wait for a tty reopen; eg., if the tty has starting final close and is waiting for the device to drain. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Cc: stable <stable@vger.kernel.org> # 4.4 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
		
							parent
							
								
									92e963f50f
								
							
						
					
					
						commit
						0bfd464d3f
					
				
					 3 changed files with 16 additions and 1 deletions
				
			
		| 
						 | 
					@ -2065,7 +2065,12 @@ static int tty_open(struct inode *inode, struct file *filp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (tty) {
 | 
							if (tty) {
 | 
				
			||||||
			mutex_unlock(&tty_mutex);
 | 
								mutex_unlock(&tty_mutex);
 | 
				
			||||||
			tty_lock(tty);
 | 
								retval = tty_lock_interruptible(tty);
 | 
				
			||||||
 | 
								if (retval) {
 | 
				
			||||||
 | 
									if (retval == -EINTR)
 | 
				
			||||||
 | 
										retval = -ERESTARTSYS;
 | 
				
			||||||
 | 
									goto err_unref;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			/* safe to drop the kref from tty_driver_lookup_tty() */
 | 
								/* safe to drop the kref from tty_driver_lookup_tty() */
 | 
				
			||||||
			tty_kref_put(tty);
 | 
								tty_kref_put(tty);
 | 
				
			||||||
			retval = tty_reopen(tty);
 | 
								retval = tty_reopen(tty);
 | 
				
			||||||
| 
						 | 
					@ -2152,6 +2157,7 @@ static int tty_open(struct inode *inode, struct file *filp)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
err_unlock:
 | 
					err_unlock:
 | 
				
			||||||
	mutex_unlock(&tty_mutex);
 | 
						mutex_unlock(&tty_mutex);
 | 
				
			||||||
 | 
					err_unref:
 | 
				
			||||||
	/* after locks to avoid deadlock */
 | 
						/* after locks to avoid deadlock */
 | 
				
			||||||
	if (!IS_ERR_OR_NULL(driver))
 | 
						if (!IS_ERR_OR_NULL(driver))
 | 
				
			||||||
		tty_driver_kref_put(driver);
 | 
							tty_driver_kref_put(driver);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,6 +19,14 @@ void __lockfunc tty_lock(struct tty_struct *tty)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(tty_lock);
 | 
					EXPORT_SYMBOL(tty_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int tty_lock_interruptible(struct tty_struct *tty)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (WARN(tty->magic != TTY_MAGIC, "L Bad %p\n", tty))
 | 
				
			||||||
 | 
							return -EIO;
 | 
				
			||||||
 | 
						tty_kref_get(tty);
 | 
				
			||||||
 | 
						return mutex_lock_interruptible(&tty->legacy_mutex);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void __lockfunc tty_unlock(struct tty_struct *tty)
 | 
					void __lockfunc tty_unlock(struct tty_struct *tty)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (WARN(tty->magic != TTY_MAGIC, "U Bad %p\n", tty))
 | 
						if (WARN(tty->magic != TTY_MAGIC, "U Bad %p\n", tty))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -649,6 +649,7 @@ extern long vt_compat_ioctl(struct tty_struct *tty,
 | 
				
			||||||
/* tty_mutex.c */
 | 
					/* tty_mutex.c */
 | 
				
			||||||
/* functions for preparation of BKL removal */
 | 
					/* functions for preparation of BKL removal */
 | 
				
			||||||
extern void __lockfunc tty_lock(struct tty_struct *tty);
 | 
					extern void __lockfunc tty_lock(struct tty_struct *tty);
 | 
				
			||||||
 | 
					extern int  tty_lock_interruptible(struct tty_struct *tty);
 | 
				
			||||||
extern void __lockfunc tty_unlock(struct tty_struct *tty);
 | 
					extern void __lockfunc tty_unlock(struct tty_struct *tty);
 | 
				
			||||||
extern void __lockfunc tty_lock_slave(struct tty_struct *tty);
 | 
					extern void __lockfunc tty_lock_slave(struct tty_struct *tty);
 | 
				
			||||||
extern void __lockfunc tty_unlock_slave(struct tty_struct *tty);
 | 
					extern void __lockfunc tty_unlock_slave(struct tty_struct *tty);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue