diff options
author | Jan Kiszka <jan.kiszka@web.de> | 2010-02-08 05:12:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-16 19:01:18 -0500 |
commit | 90926f0e58dcd9f4ca877961000568a3be787f2f (patch) | |
tree | d3c589a3debf2f692c5f5a7643a78b7f20cb7a60 | |
parent | c947862f9126983537a4cc11e07d26882d60b7e7 (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>
-rw-r--r-- | drivers/isdn/capi/capi.c | 14 | ||||
-rw-r--r-- | drivers/isdn/capi/capifs.c | 50 | ||||
-rw-r--r-- | drivers/isdn/capi/capifs.h | 21 |
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 | ||
49 | static char *revision = "$Revision: 1.1.2.7 $"; | 48 | static 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 | ||
144 | static struct dentry *get_node(int num) | 144 | struct 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 | |||
152 | void 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 | ||
181 | unlock_out: | 183 | unlock_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 | ||
185 | void capifs_free_ncci(unsigned int number) | 189 | void 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 | ||
10 | void capifs_new_ncci(unsigned int num, dev_t device); | 10 | #include <linux/dcache.h> |
11 | void capifs_free_ncci(unsigned int num); | 11 | |
12 | #if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE) | ||
13 | |||
14 | struct dentry *capifs_new_ncci(unsigned int num, dev_t device); | ||
15 | void capifs_free_ncci(struct dentry *dentry); | ||
16 | |||
17 | #else | ||
18 | |||
19 | static inline struct dentry *capifs_new_ncci(unsigned int num, dev_t device) | ||
20 | { | ||
21 | return NULL; | ||
22 | } | ||
23 | |||
24 | static inline void capifs_free_ncci(struct dentry *dentry) | ||
25 | { | ||
26 | } | ||
27 | |||
28 | #endif | ||