On 02. 01. 19, 16:04, Tetsuo Handa wrote:
> +     if (wait_event_interruptible(tty->read_wait,
> +          (ret = -EIO, test_bit(TTY_OTHER_CLOSED, &tty->flags)) ||
> +          (ret = 0, tty_hung_up_p(file)) ||
> +          (rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list)) != NULL ||
> +          (ret = -EAGAIN, tty_io_nonblock(tty, file))))
> +             return -EINTR;

Oh, that looks really ugly. Could you move all this to a function
returning a bool and taking &ret and &rbuf as parameters?

> +     if (rbuf) {
> +             if (rbuf->count > nr)
> +                     /* too large for caller's buffer */
> +                     ret = -EOVERFLOW;
> +             else if (copy_to_user(buf, rbuf->buf, rbuf->count))
> +                     ret = -EFAULT;
> +             else
> +                     ret = rbuf->count;
> +             if (n_hdlc->rx_free_buf_list.count > DEFAULT_RX_BUF_COUNT)
> +                     kfree(rbuf);
> +             else
> +                     n_hdlc_buf_put(&n_hdlc->rx_free_buf_list, rbuf);
>       }
> -
> -     remove_wait_queue(&tty->read_wait, &wait);
> -     __set_current_state(TASK_RUNNING);
> -
>       return ret;
> -     
>  }    /* end of n_hdlc_tty_read() */
>  
>  /**
> @@ -645,21 +612,13 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, 
> struct file *file,
>  static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
>                           const unsigned char *data, size_t count)
>  {
> -     struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
> +     struct n_hdlc *n_hdlc;
>       int error = 0;
> -     DECLARE_WAITQUEUE(wait, current);
> -     struct n_hdlc_buf *tbuf;
> +     struct n_hdlc_buf *tbuf = NULL;
>  
>       if (debuglevel >= DEBUG_LEVEL_INFO)     
>               printk("%s(%d)n_hdlc_tty_write() called count=%zd\n",
>                       __FILE__,__LINE__,count);
> -             
> -     /* Verify pointers */
> -     if (!n_hdlc)
> -             return -EIO;
> -
> -     if (n_hdlc->magic != HDLC_MAGIC)
> -             return -EIO;
>  
>       /* verify frame size */
>       if (count > maxframe ) {
> @@ -670,40 +629,14 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, 
> struct file *file,
>                               maxframe );
>               count = maxframe;
>       }
> -     
> -     add_wait_queue(&tty->write_wait, &wait);
>  
> -     for (;;) {
> -             set_current_state(TASK_INTERRUPTIBLE);
> -     
> -             tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list);
> -             if (tbuf)
> -                     break;
> -
> -             if (tty_io_nonblock(tty, file)) {
> -                     error = -EAGAIN;
> -                     break;
> -             }
> -             schedule();
> -                     
> -             n_hdlc = tty2n_hdlc (tty);
> -             if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || 
> -                 tty != n_hdlc->tty) {
> -                     printk("n_hdlc_tty_write: %p invalid after wait!\n", 
> n_hdlc);
> -                     error = -EIO;
> -                     break;
> -             }
> -                     
> -             if (signal_pending(current)) {
> -                     error = -EINTR;
> -                     break;
> -             }
> -     }
> -
> -     __set_current_state(TASK_RUNNING);
> -     remove_wait_queue(&tty->write_wait, &wait);
> -
> -     if (!error) {           
> +     if (wait_event_interruptible(tty->write_wait,
> +          (error = -EIO, n_hdlc = tty2n_hdlc(tty), /* Verify pointers */
> +           !n_hdlc || n_hdlc->magic != HDLC_MAGIC || tty != n_hdlc->tty) ||
> +          (tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list)) != NULL ||
> +          (error = -EAGAIN, tty_io_nonblock(tty, file))))
> +             return -EINTR;

This is even worse. So detto as above?

> +     if (tbuf) {
>               /* Retrieve the user's buffer */
>               memcpy(tbuf->buf, data, count);
>  
> @@ -711,8 +644,9 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, 
> struct file *file,
>               tbuf->count = error = count;
>               n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf);
>               n_hdlc_send_frames(n_hdlc,tty);
> +     } else if (error == -EIO) {
> +             printk("n_hdlc_tty_write: %p invalid!\n", n_hdlc);
>       }
> -
>       return error;
>       
>  }    /* end of n_hdlc_tty_write() */
> 

thanks,
-- 
js
suse labs

Reply via email to