isdn: use non-racy method for proc entries creation
Use proc_create()/proc_create_data() to make sure that ->proc_fops and ->data be setup before gluing PDE to main tree. Add correct ->owner to proc_fops to fix reading/module unloading race. Signed-off-by: Denis V. Lunev <den@openvz.org> Acked-by: Karsten Keil <kkeil@suse.de> Cc: Alexey Dobriyan <adobriyan@gmail.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
a95609cb02
commit
ac41cfd19b
|
@ -114,6 +114,7 @@ static int seq_contrstats_open(struct inode *inode, struct file *file)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations proc_controller_ops = {
|
static const struct file_operations proc_controller_ops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
.open = seq_controller_open,
|
.open = seq_controller_open,
|
||||||
.read = seq_read,
|
.read = seq_read,
|
||||||
.llseek = seq_lseek,
|
.llseek = seq_lseek,
|
||||||
|
@ -121,6 +122,7 @@ static const struct file_operations proc_controller_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct file_operations proc_contrstats_ops = {
|
static const struct file_operations proc_contrstats_ops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
.open = seq_contrstats_open,
|
.open = seq_contrstats_open,
|
||||||
.read = seq_read,
|
.read = seq_read,
|
||||||
.llseek = seq_lseek,
|
.llseek = seq_lseek,
|
||||||
|
@ -219,6 +221,7 @@ seq_applstats_open(struct inode *inode, struct file *file)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations proc_applications_ops = {
|
static const struct file_operations proc_applications_ops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
.open = seq_applications_open,
|
.open = seq_applications_open,
|
||||||
.read = seq_read,
|
.read = seq_read,
|
||||||
.llseek = seq_lseek,
|
.llseek = seq_lseek,
|
||||||
|
@ -226,21 +229,13 @@ static const struct file_operations proc_applications_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct file_operations proc_applstats_ops = {
|
static const struct file_operations proc_applstats_ops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
.open = seq_applstats_open,
|
.open = seq_applstats_open,
|
||||||
.read = seq_read,
|
.read = seq_read,
|
||||||
.llseek = seq_lseek,
|
.llseek = seq_lseek,
|
||||||
.release = seq_release,
|
.release = seq_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
|
||||||
create_seq_entry(char *name, mode_t mode, const struct file_operations *f)
|
|
||||||
{
|
|
||||||
struct proc_dir_entry *entry;
|
|
||||||
entry = create_proc_entry(name, mode, NULL);
|
|
||||||
if (entry)
|
|
||||||
entry->proc_fops = f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
static void *capi_driver_start(struct seq_file *seq, loff_t *pos)
|
static void *capi_driver_start(struct seq_file *seq, loff_t *pos)
|
||||||
|
@ -283,6 +278,7 @@ seq_capi_driver_open(struct inode *inode, struct file *file)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations proc_driver_ops = {
|
static const struct file_operations proc_driver_ops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
.open = seq_capi_driver_open,
|
.open = seq_capi_driver_open,
|
||||||
.read = seq_read,
|
.read = seq_read,
|
||||||
.llseek = seq_lseek,
|
.llseek = seq_lseek,
|
||||||
|
@ -296,11 +292,11 @@ kcapi_proc_init(void)
|
||||||
{
|
{
|
||||||
proc_mkdir("capi", NULL);
|
proc_mkdir("capi", NULL);
|
||||||
proc_mkdir("capi/controllers", NULL);
|
proc_mkdir("capi/controllers", NULL);
|
||||||
create_seq_entry("capi/controller", 0, &proc_controller_ops);
|
proc_create("capi/controller", 0, NULL, &proc_controller_ops);
|
||||||
create_seq_entry("capi/contrstats", 0, &proc_contrstats_ops);
|
proc_create("capi/contrstats", 0, NULL, &proc_contrstats_ops);
|
||||||
create_seq_entry("capi/applications", 0, &proc_applications_ops);
|
proc_create("capi/applications", 0, NULL, &proc_applications_ops);
|
||||||
create_seq_entry("capi/applstats", 0, &proc_applstats_ops);
|
proc_create("capi/applstats", 0, NULL, &proc_applstats_ops);
|
||||||
create_seq_entry("capi/driver", 0, &proc_driver_ops);
|
proc_create("capi/driver", 0, NULL, &proc_driver_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __exit
|
void __exit
|
||||||
|
|
|
@ -288,13 +288,12 @@ divert_dev_init(void)
|
||||||
isdn_proc_entry = proc_mkdir("isdn", init_net.proc_net);
|
isdn_proc_entry = proc_mkdir("isdn", init_net.proc_net);
|
||||||
if (!isdn_proc_entry)
|
if (!isdn_proc_entry)
|
||||||
return (-1);
|
return (-1);
|
||||||
isdn_divert_entry = create_proc_entry("divert", S_IFREG | S_IRUGO, isdn_proc_entry);
|
isdn_divert_entry = proc_create("divert", S_IFREG | S_IRUGO,
|
||||||
|
isdn_proc_entry, &isdn_fops);
|
||||||
if (!isdn_divert_entry) {
|
if (!isdn_divert_entry) {
|
||||||
remove_proc_entry("isdn", init_net.proc_net);
|
remove_proc_entry("isdn", init_net.proc_net);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
isdn_divert_entry->proc_fops = &isdn_fops;
|
|
||||||
isdn_divert_entry->owner = THIS_MODULE;
|
|
||||||
#endif /* CONFIG_PROC_FS */
|
#endif /* CONFIG_PROC_FS */
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|
|
@ -125,15 +125,11 @@ static const struct file_operations divas_fops = {
|
||||||
|
|
||||||
int create_divas_proc(void)
|
int create_divas_proc(void)
|
||||||
{
|
{
|
||||||
divas_proc_entry = create_proc_entry(divas_proc_name,
|
proc_create(divas_proc_name, S_IFREG | S_IRUGO, proc_net_eicon,
|
||||||
S_IFREG | S_IRUGO,
|
&divas_fops);
|
||||||
proc_net_eicon);
|
|
||||||
if (!divas_proc_entry)
|
if (!divas_proc_entry)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
divas_proc_entry->proc_fops = &divas_fops;
|
|
||||||
divas_proc_entry->owner = THIS_MODULE;
|
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -370,6 +370,7 @@ hysdn_conf_close(struct inode *ino, struct file *filep)
|
||||||
/******************************************************/
|
/******************************************************/
|
||||||
static const struct file_operations conf_fops =
|
static const struct file_operations conf_fops =
|
||||||
{
|
{
|
||||||
|
.owner = THIS_MODULE,
|
||||||
.llseek = no_llseek,
|
.llseek = no_llseek,
|
||||||
.read = hysdn_conf_read,
|
.read = hysdn_conf_read,
|
||||||
.write = hysdn_conf_write,
|
.write = hysdn_conf_write,
|
||||||
|
@ -402,11 +403,9 @@ hysdn_procconf_init(void)
|
||||||
while (card) {
|
while (card) {
|
||||||
|
|
||||||
sprintf(conf_name, "%s%d", PROC_CONF_BASENAME, card->myid);
|
sprintf(conf_name, "%s%d", PROC_CONF_BASENAME, card->myid);
|
||||||
if ((card->procconf = (void *) create_proc_entry(conf_name,
|
if ((card->procconf = (void *) proc_create(conf_name,
|
||||||
S_IFREG | S_IRUGO | S_IWUSR,
|
S_IFREG | S_IRUGO | S_IWUSR,
|
||||||
hysdn_proc_entry)) != NULL) {
|
hysdn_proc_entry)) != NULL) {
|
||||||
((struct proc_dir_entry *) card->procconf)->proc_fops = &conf_fops;
|
|
||||||
((struct proc_dir_entry *) card->procconf)->owner = THIS_MODULE;
|
|
||||||
hysdn_proclog_init(card); /* init the log file entry */
|
hysdn_proclog_init(card); /* init the log file entry */
|
||||||
}
|
}
|
||||||
card = card->next; /* next entry */
|
card = card->next; /* next entry */
|
||||||
|
|
|
@ -380,6 +380,7 @@ hysdn_log_poll(struct file *file, poll_table * wait)
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
static const struct file_operations log_fops =
|
static const struct file_operations log_fops =
|
||||||
{
|
{
|
||||||
|
.owner = THIS_MODULE,
|
||||||
.llseek = no_llseek,
|
.llseek = no_llseek,
|
||||||
.read = hysdn_log_read,
|
.read = hysdn_log_read,
|
||||||
.write = hysdn_log_write,
|
.write = hysdn_log_write,
|
||||||
|
@ -402,10 +403,9 @@ hysdn_proclog_init(hysdn_card * card)
|
||||||
|
|
||||||
if ((pd = kzalloc(sizeof(struct procdata), GFP_KERNEL)) != NULL) {
|
if ((pd = kzalloc(sizeof(struct procdata), GFP_KERNEL)) != NULL) {
|
||||||
sprintf(pd->log_name, "%s%d", PROC_LOG_BASENAME, card->myid);
|
sprintf(pd->log_name, "%s%d", PROC_LOG_BASENAME, card->myid);
|
||||||
if ((pd->log = create_proc_entry(pd->log_name, S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry)) != NULL) {
|
pd->log = proc_create(pd->log_name,
|
||||||
pd->log->proc_fops = &log_fops;
|
S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry,
|
||||||
pd->log->owner = THIS_MODULE;
|
&log_fops);
|
||||||
}
|
|
||||||
|
|
||||||
init_waitqueue_head(&(pd->rd_queue));
|
init_waitqueue_head(&(pd->rd_queue));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue