aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@web.de>2010-02-08 05:12:06 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-16 19:01:18 -0500
commit90926f0e58dcd9f4ca877961000568a3be787f2f (patch)
treed3c589a3debf2f692c5f5a7643a78b7f20cb7a60 /drivers/isdn
parentc947862f9126983537a4cc11e07d26882d60b7e7 (diff)
CAPI: Sanitize capifs API
Instead of looking up the dentry of an NCCI node again in capifs_free_ncci pass the pointer via the capifs user. This patch also reduces the #ifdef mess in capi.c a bit as far as capifs was causing it. Signed-off-by: Jan Kiszka <jan.kiszka@web.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/capi/capi.c14
-rw-r--r--drivers/isdn/capi/capifs.c50
-rw-r--r--drivers/isdn/capi/capifs.h21
3 files changed, 54 insertions, 31 deletions
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 79f9364aded6..dc5ac52986ee 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -42,9 +42,8 @@
42#include <linux/moduleparam.h> 42#include <linux/moduleparam.h>
43#include <linux/isdn/capiutil.h> 43#include <linux/isdn/capiutil.h>
44#include <linux/isdn/capicmd.h> 44#include <linux/isdn/capicmd.h>
45#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE) 45
46#include "capifs.h" 46#include "capifs.h"
47#endif
48 47
49static char *revision = "$Revision: 1.1.2.7 $"; 48static char *revision = "$Revision: 1.1.2.7 $";
50 49
@@ -96,6 +95,7 @@ struct capiminor {
96 struct list_head list; 95 struct list_head list;
97 struct capincci *nccip; 96 struct capincci *nccip;
98 unsigned int minor; 97 unsigned int minor;
98 struct dentry *capifs_dentry;
99 99
100 struct capi20_appl *ap; 100 struct capi20_appl *ap;
101 u32 ncci; 101 u32 ncci;
@@ -328,9 +328,9 @@ static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci)
328#ifdef _DEBUG_REFCOUNT 328#ifdef _DEBUG_REFCOUNT
329 printk(KERN_DEBUG "set mp->nccip\n"); 329 printk(KERN_DEBUG "set mp->nccip\n");
330#endif 330#endif
331#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE) 331 mp->capifs_dentry =
332 capifs_new_ncci(mp->minor, MKDEV(capi_ttymajor, mp->minor)); 332 capifs_new_ncci(mp->minor,
333#endif 333 MKDEV(capi_ttymajor, mp->minor));
334 } 334 }
335#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ 335#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
336 for (pp=&cdev->nccis; *pp; pp = &(*pp)->next) 336 for (pp=&cdev->nccis; *pp; pp = &(*pp)->next)
@@ -353,9 +353,7 @@ static void capincci_free(struct capidev *cdev, u32 ncci)
353 *pp = (*pp)->next; 353 *pp = (*pp)->next;
354#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 354#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
355 if ((mp = np->minorp) != NULL) { 355 if ((mp = np->minorp) != NULL) {
356#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE) 356 capifs_free_ncci(mp->capifs_dentry);
357 capifs_free_ncci(mp->minor);
358#endif
359 if (mp->tty) { 357 if (mp->tty) {
360 mp->nccip = NULL; 358 mp->nccip = NULL;
361#ifdef _DEBUG_REFCOUNT 359#ifdef _DEBUG_REFCOUNT
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
index dc68fcb122a0..91aafadd413f 100644
--- a/drivers/isdn/capi/capifs.c
+++ b/drivers/isdn/capi/capifs.c
@@ -141,31 +141,32 @@ static struct file_system_type capifs_fs_type = {
141 .kill_sb = kill_anon_super, 141 .kill_sb = kill_anon_super,
142}; 142};
143 143
144static struct dentry *get_node(int num) 144struct dentry *capifs_new_ncci(unsigned int number, dev_t device)
145{
146 char s[10];
147 struct dentry *root = capifs_root;
148 mutex_lock(&root->d_inode->i_mutex);
149 return lookup_one_len(s, root, sprintf(s, "%d", num));
150}
151
152void capifs_new_ncci(unsigned int number, dev_t device)
153{ 145{
154 struct dentry *dentry; 146 struct dentry *dentry;
155 struct inode *inode; 147 struct inode *inode;
148 char name[10];
149 int namelen;
156 150
157 dentry = get_node(number); 151 mutex_lock(&capifs_root->d_inode->i_mutex);
158 if (IS_ERR(dentry)) 152
153 namelen = sprintf(name, "%d", number);
154 dentry = lookup_one_len(name, capifs_root, namelen);
155 if (IS_ERR(dentry)) {
156 dentry = NULL;
159 goto unlock_out; 157 goto unlock_out;
158 }
160 159
161 if (dentry->d_inode) { 160 if (dentry->d_inode) {
162 dput(dentry); 161 dput(dentry);
162 dentry = NULL;
163 goto unlock_out; 163 goto unlock_out;
164 } 164 }
165 165
166 inode = new_inode(capifs_mnt->mnt_sb); 166 inode = new_inode(capifs_mnt->mnt_sb);
167 if (!inode) { 167 if (!inode) {
168 dput(dentry); 168 dput(dentry);
169 dentry = NULL;
169 goto unlock_out; 170 goto unlock_out;
170 } 171 }
171 172
@@ -177,24 +178,31 @@ void capifs_new_ncci(unsigned int number, dev_t device)
177 init_special_inode(inode, S_IFCHR|config.mode, device); 178 init_special_inode(inode, S_IFCHR|config.mode, device);
178 179
179 d_instantiate(dentry, inode); 180 d_instantiate(dentry, inode);
181 dget(dentry);
180 182
181unlock_out: 183unlock_out:
182 mutex_unlock(&capifs_root->d_inode->i_mutex); 184 mutex_unlock(&capifs_root->d_inode->i_mutex);
185
186 return dentry;
183} 187}
184 188
185void capifs_free_ncci(unsigned int number) 189void capifs_free_ncci(struct dentry *dentry)
186{ 190{
187 struct dentry *dentry = get_node(number); 191 struct inode *inode;
188 192
189 if (!IS_ERR(dentry)) { 193 if (!dentry)
190 struct inode *inode = dentry->d_inode; 194 return;
191 if (inode) { 195
192 inode->i_nlink--; 196 mutex_lock(&capifs_root->d_inode->i_mutex);
193 d_delete(dentry); 197
194 dput(dentry); 198 inode = dentry->d_inode;
195 } 199 if (inode) {
200 drop_nlink(inode);
201 d_delete(dentry);
196 dput(dentry); 202 dput(dentry);
197 } 203 }
204 dput(dentry);
205
198 mutex_unlock(&capifs_root->d_inode->i_mutex); 206 mutex_unlock(&capifs_root->d_inode->i_mutex);
199} 207}
200 208
diff --git a/drivers/isdn/capi/capifs.h b/drivers/isdn/capi/capifs.h
index d0bd4c3c430a..e193d1189531 100644
--- a/drivers/isdn/capi/capifs.h
+++ b/drivers/isdn/capi/capifs.h
@@ -7,5 +7,22 @@
7 * 7 *
8 */ 8 */
9 9
10void capifs_new_ncci(unsigned int num, dev_t device); 10#include <linux/dcache.h>
11void capifs_free_ncci(unsigned int num); 11
12#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
13
14struct dentry *capifs_new_ncci(unsigned int num, dev_t device);
15void capifs_free_ncci(struct dentry *dentry);
16
17#else
18
19static inline struct dentry *capifs_new_ncci(unsigned int num, dev_t device)
20{
21 return NULL;
22}
23
24static inline void capifs_free_ncci(struct dentry *dentry)
25{
26}
27
28#endif