From 84ccc652b6cb3f57e6cff6ceab201a553bfe9561 Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Tue, 21 May 2013 15:33:16 -0500 Subject: [PATCH] dahdi: Replace create_proc_entry() with proc_create_data() create_proc_entry() was deprecated and replace with proc_create_data() since it's open to a race condition where the proc entry is visible before the file operations have been set for it. The PDE() macro also is no longer available as of Linux 3.10 and is replaced with PDE_DATA() to get the data member from a proc entry. This is due to the fact that 'struct proc_dir_entry' is now private to the proc_fs. This commit changes the core of DAHDI and also introduces proc_create_data() and PDE_DATA() for older kernels. Signed-off-by: Shaun Ruffell Acked-by: Tzafrir Cohen Cc: Russ Meyerriecks Cc: Oron Peled --- drivers/dahdi/dahdi-base.c | 26 ++++++++++++++++++-------- include/dahdi/kernel.h | 25 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c index 72aa5e3..f9cc628 100644 --- a/drivers/dahdi/dahdi-base.c +++ b/drivers/dahdi/dahdi-base.c @@ -900,7 +900,7 @@ static void seq_fill_alarm_string(struct seq_file *sfile, int alarms) seq_printf(sfile, "%s", tmp); } -static int dahdi_seq_show(struct seq_file *sfile, void *v) +static int dahdi_seq_show(struct seq_file *sfile, void *data) { long spanno = (long)sfile->private; int x; @@ -992,7 +992,7 @@ static int dahdi_seq_show(struct seq_file *sfile, void *v) static int dahdi_proc_open(struct inode *inode, struct file *file) { - return single_open(file, dahdi_seq_show, PDE(inode)->data); + return single_open(file, dahdi_seq_show, PDE_DATA(inode)); } static const struct file_operations dahdi_proc_ops = { @@ -7260,15 +7260,14 @@ static int _dahdi_assign_span(struct dahdi_span *span, unsigned int spanno, { char tempfile[17]; snprintf(tempfile, sizeof(tempfile), "%d", span->spanno); - span->proc_entry = create_proc_entry(tempfile, 0444, - root_proc_entry); + span->proc_entry = proc_create_data(tempfile, 0444, + root_proc_entry, &dahdi_proc_ops, + (void *)((unsigned long)span->spanno)); if (!span->proc_entry) { res = -EFAULT; span_err(span, "Error creating procfs entry\n"); goto cleanup; } - span->proc_entry->data = (void *)(long)span->spanno; - span->proc_entry->proc_fops = &dahdi_proc_ops; } #endif @@ -7416,6 +7415,15 @@ static void disable_span(struct dahdi_span *span) module_printk(KERN_INFO, "%s: span %d\n", __func__, span->spanno); } +#ifdef CONFIG_PROC_FS +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0) +static inline void proc_remove(struct proc_dir_entry *proc_entry) +{ + remove_proc_entry(proc_entry->name, root_proc_entry); +} +#endif +#endif + /** * _dahdi_unassign_span() - unassign a DAHDI span * @span: the DAHDI span @@ -7454,8 +7462,10 @@ static int _dahdi_unassign_span(struct dahdi_span *span) if (debug & DEBUG_MAIN) module_printk(KERN_NOTICE, "Unassigning Span '%s' with %d channels\n", span->name, span->channels); #ifdef CONFIG_PROC_FS - if (span->proc_entry) - remove_proc_entry(span->proc_entry->name, root_proc_entry); + if (span->proc_entry) { + proc_remove(span->proc_entry); + span->proc_entry = NULL; + } #endif /* CONFIG_PROC_FS */ span_sysfs_remove(span); diff --git a/include/dahdi/kernel.h b/include/dahdi/kernel.h index fca8ec1..8f3dc76 100644 --- a/include/dahdi/kernel.h +++ b/include/dahdi/kernel.h @@ -1401,9 +1401,33 @@ static inline short dahdi_txtone_nextsample(struct dahdi_chan *ss) /*! Maximum audio mask */ #define DAHDI_FORMAT_AUDIO_MASK ((1 << 16) - 1) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0) +#ifdef CONFIG_PROC_FS +#include +static inline void *PDE_DATA(const struct inode *inode) +{ + return PDE(inode)->data; +} +#endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) #define KERN_CONT "" #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) +#ifdef CONFIG_PROC_FS +#include +static inline struct proc_dir_entry *proc_create_data(const char *name, + mode_t mode, + struct proc_dir_entry *parent, + const struct file_operations *proc_fops, + void *data) +{ + struct proc_dir_entry *pde = create_proc_entry(name, mode, parent); + if (!pde) + return NULL; + pde->proc_fops = proc_fops; + pde->data = data; + return pde; +} +#endif /* CONFIG_PROC_FS */ #ifndef clamp #define clamp(x, low, high) min(max(low, x), high) #endif @@ -1456,6 +1480,7 @@ static inline int strcasecmp(const char *s1, const char *s2) #endif /* 2.6.25 */ #endif /* 2.6.26 */ #endif /* 2.6.31 */ +#endif /* 3.10.0 */ #ifndef DEFINE_SPINLOCK #define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED