diff options
Diffstat (limited to 'drivers/isdn/hysdn/hysdn_procconf.c')
| -rw-r--r-- | drivers/isdn/hysdn/hysdn_procconf.c | 126 |
1 files changed, 47 insertions, 79 deletions
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c index 5da507e532f..73079213ec9 100644 --- a/drivers/isdn/hysdn/hysdn_procconf.c +++ b/drivers/isdn/hysdn/hysdn_procconf.c @@ -11,16 +11,18 @@ * */ +#include <linux/cred.h> #include <linux/module.h> -#include <linux/version.h> #include <linux/poll.h> #include <linux/proc_fs.h> #include <linux/pci.h> -#include <linux/smp_lock.h> +#include <linux/slab.h> +#include <linux/mutex.h> +#include <net/net_namespace.h> #include "hysdn_defs.h" -static char *hysdn_procconf_revision = "$Revision: 1.8.6.4 $"; +static DEFINE_MUTEX(hysdn_conf_mutex); #define INFO_OUT_LEN 80 /* length of info line including lf */ @@ -37,9 +39,9 @@ struct conf_writedata { int buf_size; /* actual number of bytes in the buffer */ int needed_size; /* needed size when reading pof */ int state; /* actual interface states from above constants */ - uchar conf_line[CONF_LINE_LEN]; /* buffered conf line */ - word channel; /* active channel number */ - uchar *pof_buffer; /* buffer when writing pof */ + unsigned char conf_line[CONF_LINE_LEN]; /* buffered conf line */ + unsigned short channel; /* active channel number */ + unsigned char *pof_buffer; /* buffer when writing pof */ }; /***********************************************************************/ @@ -50,7 +52,7 @@ struct conf_writedata { static int process_line(struct conf_writedata *cnf) { - uchar *cp = cnf->conf_line; + unsigned char *cp = cnf->conf_line; int i; if (cnf->card->debug_flags & LOG_CNF_LINE) @@ -89,11 +91,11 @@ process_line(struct conf_writedata *cnf) /* write conf file -> boot or send cfg line to card */ /****************************************************/ static ssize_t -hysdn_conf_write(struct file *file, const char __user *buf, size_t count, loff_t * off) +hysdn_conf_write(struct file *file, const char __user *buf, size_t count, loff_t *off) { struct conf_writedata *cnf; int i; - uchar ch, *cp; + unsigned char ch, *cp; if (!count) return (0); /* nothing to handle */ @@ -207,30 +209,17 @@ hysdn_conf_write(struct file *file, const char __user *buf, size_t count, loff_t /* read conf file -> output card info data */ /*******************************************/ static ssize_t -hysdn_conf_read(struct file *file, char __user *buf, size_t count, loff_t * off) +hysdn_conf_read(struct file *file, char __user *buf, size_t count, loff_t *off) { char *cp; - int i; - if (file->f_mode & FMODE_READ) { - if (!(cp = file->private_data)) - return (-EFAULT); /* should never happen */ - i = strlen(cp); /* get total string length */ - if (*off < i) { - /* still bytes to transfer */ - cp += *off; /* point to desired data offset */ - i -= *off; /* remaining length */ - if (i > count) - i = count; /* limit length to transfer */ - if (copy_to_user(buf, cp, i)) - return (-EFAULT); /* copy error */ - *off += i; /* adjust offset */ - } else - return (0); - } else - return (-EPERM); /* no permission to read */ - - return (i); + if (!(file->f_mode & FMODE_READ)) + return -EPERM; /* no permission to read */ + + if (!(cp = file->private_data)) + return -EFAULT; /* should never happen */ + + return simple_read_from_buffer(buf, count, off, cp, strlen(cp)); } /* hysdn_conf_read */ /******************/ @@ -240,32 +229,22 @@ static int hysdn_conf_open(struct inode *ino, struct file *filep) { hysdn_card *card; - struct proc_dir_entry *pd; struct conf_writedata *cnf; char *cp, *tmp; /* now search the addressed card */ - lock_kernel(); - card = card_root; - while (card) { - pd = card->procconf; - if (pd == PDE(ino)) - break; - card = card->next; /* search next entry */ - } - if (!card) { - unlock_kernel(); - return (-ENODEV); /* device is unknown/invalid */ - } + mutex_lock(&hysdn_conf_mutex); + card = PDE_DATA(ino); if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL)) hysdn_addlog(card, "config open for uid=%d gid=%d mode=0x%x", - filep->f_uid, filep->f_gid, filep->f_mode); + filep->f_cred->fsuid, filep->f_cred->fsgid, + filep->f_mode); if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) { /* write only access -> write boot file or conf line */ if (!(cnf = kmalloc(sizeof(struct conf_writedata), GFP_KERNEL))) { - unlock_kernel(); + mutex_unlock(&hysdn_conf_mutex); return (-EFAULT); } cnf->card = card; @@ -276,8 +255,8 @@ hysdn_conf_open(struct inode *ino, struct file *filep) } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) { /* read access -> output card info data */ - if (!(tmp = (char *) kmalloc(INFO_OUT_LEN * 2 + 2, GFP_KERNEL))) { - unlock_kernel(); + if (!(tmp = kmalloc(INFO_OUT_LEN * 2 + 2, GFP_KERNEL))) { + mutex_unlock(&hysdn_conf_mutex); return (-EFAULT); /* out of memory */ } filep->private_data = tmp; /* start of string */ @@ -311,10 +290,10 @@ hysdn_conf_open(struct inode *ino, struct file *filep) *cp++ = '\n'; *cp = 0; /* end of string */ } else { /* simultaneous read/write access forbidden ! */ - unlock_kernel(); + mutex_unlock(&hysdn_conf_mutex); return (-EPERM); /* no permission this time */ } - unlock_kernel(); + mutex_unlock(&hysdn_conf_mutex); return nonseekable_open(ino, filep); } /* hysdn_conf_open */ @@ -327,24 +306,13 @@ hysdn_conf_close(struct inode *ino, struct file *filep) hysdn_card *card; struct conf_writedata *cnf; int retval = 0; - struct proc_dir_entry *pd; - lock_kernel(); - /* search the addressed card */ - card = card_root; - while (card) { - pd = card->procconf; - if (pd == PDE(ino)) - break; - card = card->next; /* search next entry */ - } - if (!card) { - unlock_kernel(); - return (-ENODEV); /* device is unknown/invalid */ - } + mutex_lock(&hysdn_conf_mutex); + card = PDE_DATA(ino); if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL)) hysdn_addlog(card, "config close for uid=%d gid=%d mode=0x%x", - filep->f_uid, filep->f_gid, filep->f_mode); + filep->f_cred->fsuid, filep->f_cred->fsgid, + filep->f_mode); if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) { /* write only access -> write boot file or conf line */ @@ -359,23 +327,23 @@ hysdn_conf_close(struct inode *ino, struct file *filep) } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) { /* read access -> output card info data */ - if (filep->private_data) - kfree(filep->private_data); /* release memory */ + kfree(filep->private_data); /* release memory */ } - unlock_kernel(); + mutex_unlock(&hysdn_conf_mutex); return (retval); } /* hysdn_conf_close */ /******************************************************/ /* table for conf filesystem functions defined above. */ /******************************************************/ -static struct file_operations conf_fops = +static const struct file_operations conf_fops = { + .owner = THIS_MODULE, .llseek = no_llseek, .read = hysdn_conf_read, .write = hysdn_conf_write, .open = hysdn_conf_open, - .release = hysdn_conf_close, + .release = hysdn_conf_close, }; /*****************************/ @@ -392,9 +360,9 @@ int hysdn_procconf_init(void) { hysdn_card *card; - uchar conf_name[20]; + unsigned char conf_name[20]; - hysdn_proc_entry = create_proc_entry(PROC_SUBDIR_NAME, S_IFDIR | S_IRUGO | S_IXUGO, proc_net); + hysdn_proc_entry = proc_mkdir(PROC_SUBDIR_NAME, init_net.proc_net); if (!hysdn_proc_entry) { printk(KERN_ERR "HYSDN: unable to create hysdn subdir\n"); return (-1); @@ -403,17 +371,17 @@ hysdn_procconf_init(void) while (card) { sprintf(conf_name, "%s%d", PROC_CONF_BASENAME, card->myid); - if ((card->procconf = (void *) create_proc_entry(conf_name, - S_IFREG | S_IRUGO | S_IWUSR, - hysdn_proc_entry)) != NULL) { - ((struct proc_dir_entry *) card->procconf)->proc_fops = &conf_fops; - ((struct proc_dir_entry *) card->procconf)->owner = THIS_MODULE; + if ((card->procconf = (void *) proc_create_data(conf_name, + S_IFREG | S_IRUGO | S_IWUSR, + hysdn_proc_entry, + &conf_fops, + card)) != NULL) { hysdn_proclog_init(card); /* init the log file entry */ } card = card->next; /* next entry */ } - printk(KERN_NOTICE "HYSDN: procfs Rev. %s initialised\n", hysdn_getrev(hysdn_procconf_revision)); + printk(KERN_NOTICE "HYSDN: procfs initialised\n"); return (0); } /* hysdn_procconf_init */ @@ -425,7 +393,7 @@ void hysdn_procconf_release(void) { hysdn_card *card; - uchar conf_name[20]; + unsigned char conf_name[20]; card = card_root; /* start with first card */ while (card) { @@ -439,5 +407,5 @@ hysdn_procconf_release(void) card = card->next; /* point to next card */ } - remove_proc_entry(PROC_SUBDIR_NAME, proc_net); + remove_proc_entry(PROC_SUBDIR_NAME, init_net.proc_net); } |
