.. | .. |
---|
1564 | 1564 | return dvb_usercopy(file, cmd, arg, dvb_net_do_ioctl); |
---|
1565 | 1565 | } |
---|
1566 | 1566 | |
---|
| 1567 | +static int locked_dvb_net_open(struct inode *inode, struct file *file) |
---|
| 1568 | +{ |
---|
| 1569 | + struct dvb_device *dvbdev = file->private_data; |
---|
| 1570 | + struct dvb_net *dvbnet = dvbdev->priv; |
---|
| 1571 | + int ret; |
---|
| 1572 | + |
---|
| 1573 | + if (mutex_lock_interruptible(&dvbnet->remove_mutex)) |
---|
| 1574 | + return -ERESTARTSYS; |
---|
| 1575 | + |
---|
| 1576 | + if (dvbnet->exit) { |
---|
| 1577 | + mutex_unlock(&dvbnet->remove_mutex); |
---|
| 1578 | + return -ENODEV; |
---|
| 1579 | + } |
---|
| 1580 | + |
---|
| 1581 | + ret = dvb_generic_open(inode, file); |
---|
| 1582 | + |
---|
| 1583 | + mutex_unlock(&dvbnet->remove_mutex); |
---|
| 1584 | + |
---|
| 1585 | + return ret; |
---|
| 1586 | +} |
---|
| 1587 | + |
---|
1567 | 1588 | static int dvb_net_close(struct inode *inode, struct file *file) |
---|
1568 | 1589 | { |
---|
1569 | 1590 | struct dvb_device *dvbdev = file->private_data; |
---|
1570 | 1591 | struct dvb_net *dvbnet = dvbdev->priv; |
---|
1571 | 1592 | |
---|
| 1593 | + mutex_lock(&dvbnet->remove_mutex); |
---|
| 1594 | + |
---|
1572 | 1595 | dvb_generic_release(inode, file); |
---|
1573 | 1596 | |
---|
1574 | | - if(dvbdev->users == 1 && dvbnet->exit == 1) |
---|
| 1597 | + if (dvbdev->users == 1 && dvbnet->exit == 1) { |
---|
| 1598 | + mutex_unlock(&dvbnet->remove_mutex); |
---|
1575 | 1599 | wake_up(&dvbdev->wait_queue); |
---|
| 1600 | + } else { |
---|
| 1601 | + mutex_unlock(&dvbnet->remove_mutex); |
---|
| 1602 | + } |
---|
| 1603 | + |
---|
1576 | 1604 | return 0; |
---|
1577 | 1605 | } |
---|
1578 | 1606 | |
---|
.. | .. |
---|
1580 | 1608 | static const struct file_operations dvb_net_fops = { |
---|
1581 | 1609 | .owner = THIS_MODULE, |
---|
1582 | 1610 | .unlocked_ioctl = dvb_net_ioctl, |
---|
1583 | | - .open = dvb_generic_open, |
---|
| 1611 | + .open = locked_dvb_net_open, |
---|
1584 | 1612 | .release = dvb_net_close, |
---|
1585 | 1613 | .llseek = noop_llseek, |
---|
1586 | 1614 | }; |
---|
.. | .. |
---|
1599 | 1627 | { |
---|
1600 | 1628 | int i; |
---|
1601 | 1629 | |
---|
| 1630 | + mutex_lock(&dvbnet->remove_mutex); |
---|
1602 | 1631 | dvbnet->exit = 1; |
---|
| 1632 | + mutex_unlock(&dvbnet->remove_mutex); |
---|
| 1633 | + |
---|
1603 | 1634 | if (dvbnet->dvbdev->users < 1) |
---|
1604 | 1635 | wait_event(dvbnet->dvbdev->wait_queue, |
---|
1605 | | - dvbnet->dvbdev->users==1); |
---|
| 1636 | + dvbnet->dvbdev->users == 1); |
---|
1606 | 1637 | |
---|
1607 | 1638 | dvb_unregister_device(dvbnet->dvbdev); |
---|
1608 | 1639 | |
---|
.. | .. |
---|
1621 | 1652 | int i; |
---|
1622 | 1653 | |
---|
1623 | 1654 | mutex_init(&dvbnet->ioctl_mutex); |
---|
| 1655 | + mutex_init(&dvbnet->remove_mutex); |
---|
1624 | 1656 | dvbnet->demux = dmx; |
---|
1625 | 1657 | |
---|
1626 | 1658 | for (i=0; i<DVB_NET_DEVICES_MAX; i++) |
---|