diff options
Diffstat (limited to 'drivers/net/ppp_generic.c')
-rw-r--r-- | drivers/net/ppp_generic.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 1f4ca2b54a7..6b1d7a8edf1 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -39,6 +39,7 @@ #include <linux/if_arp.h> #include <linux/ip.h> #include <linux/tcp.h> +#include <linux/smp_lock.h> #include <linux/spinlock.h> #include <linux/rwsem.h> #include <linux/stddef.h> @@ -353,6 +354,7 @@ static const int npindex_to_ethertype[NUM_NP] = { */ static int ppp_open(struct inode *inode, struct file *file) { + cycle_kernel_lock(); /* * This could (should?) be enforced by the permissions on /dev/ppp. */ @@ -361,7 +363,7 @@ static int ppp_open(struct inode *inode, struct file *file) return 0; } -static int ppp_release(struct inode *inode, struct file *file) +static int ppp_release(struct inode *unused, struct file *file) { struct ppp_file *pf = file->private_data; struct ppp *ppp; @@ -545,8 +547,7 @@ static int get_filter(void __user *arg, struct sock_filter **p) } #endif /* CONFIG_PPP_FILTER */ -static int ppp_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct ppp_file *pf = file->private_data; struct ppp *ppp; @@ -574,24 +575,29 @@ static int ppp_ioctl(struct inode *inode, struct file *file, * this fd and reopening /dev/ppp. */ err = -EINVAL; + lock_kernel(); if (pf->kind == INTERFACE) { ppp = PF_TO_PPP(pf); if (file == ppp->owner) ppp_shutdown_interface(ppp); } if (atomic_read(&file->f_count) <= 2) { - ppp_release(inode, file); + ppp_release(NULL, file); err = 0; } else printk(KERN_DEBUG "PPPIOCDETACH file->f_count=%d\n", atomic_read(&file->f_count)); + unlock_kernel(); return err; } if (pf->kind == CHANNEL) { - struct channel *pch = PF_TO_CHANNEL(pf); + struct channel *pch; struct ppp_channel *chan; + lock_kernel(); + pch = PF_TO_CHANNEL(pf); + switch (cmd) { case PPPIOCCONNECT: if (get_user(unit, p)) @@ -611,6 +617,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file, err = chan->ops->ioctl(chan, cmd, arg); up_read(&pch->chan_sem); } + unlock_kernel(); return err; } @@ -620,6 +627,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file, return -EINVAL; } + lock_kernel(); ppp = PF_TO_PPP(pf); switch (cmd) { case PPPIOCSMRU: @@ -767,7 +775,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file, default: err = -ENOTTY; } - + unlock_kernel(); return err; } @@ -779,6 +787,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file, struct channel *chan; int __user *p = (int __user *)arg; + lock_kernel(); switch (cmd) { case PPPIOCNEWUNIT: /* Create a new ppp unit */ @@ -827,6 +836,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file, default: err = -ENOTTY; } + unlock_kernel(); return err; } @@ -835,7 +845,7 @@ static const struct file_operations ppp_device_fops = { .read = ppp_read, .write = ppp_write, .poll = ppp_poll, - .ioctl = ppp_ioctl, + .unlocked_ioctl = ppp_ioctl, .open = ppp_open, .release = ppp_release }; |