diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-08-01 14:26:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-08-01 14:26:51 -0400 |
commit | d65f5c5803d9cd6fa0b540a0dddf956be671bc36 (patch) | |
tree | d8b7e7197bd126ce857c9a368dd7573b531cb22f /fs/proc/generic.c | |
parent | a8086ad803fc4d251edb9a49838bf99c7fdfb44f (diff) | |
parent | 8d66bf5481002b0960aa49aed0987c73f5d7816c (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
[PATCH] pass struct path * to do_add_mount()
[PATCH] switch mtd and dm-table to lookup_bdev()
[patch 3/4] vfs: remove unused nameidata argument of may_create()
[PATCH] devpts: switch to IDA
[PATCH 2/2] proc: switch inode number allocation to IDA
[PATCH 1/2] proc: fix inode number bogorithmetic
[PATCH] fix bdev leak in block_dev.c do_open()
[PATCH] fix races and leaks in vfs_quota_on() users
[PATCH] clean dup2() up a bit
[PATCH] merge locate_fd() and get_unused_fd()
[PATCH] ipv4_static_sysctl_init() should be under CONFIG_SYSCTL
Re: BUG at security/selinux/avc.c:883 (was: Re: linux-next: Tree
Diffstat (limited to 'fs/proc/generic.c')
-rw-r--r-- | fs/proc/generic.c | 27 |
1 files changed, 12 insertions, 15 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index cb4096cc3fb7..4fb81e9c94e3 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -300,10 +300,10 @@ out: | |||
300 | return rtn; | 300 | return rtn; |
301 | } | 301 | } |
302 | 302 | ||
303 | static DEFINE_IDR(proc_inum_idr); | 303 | static DEFINE_IDA(proc_inum_ida); |
304 | static DEFINE_SPINLOCK(proc_inum_lock); /* protects the above */ | 304 | static DEFINE_SPINLOCK(proc_inum_lock); /* protects the above */ |
305 | 305 | ||
306 | #define PROC_DYNAMIC_FIRST 0xF0000000UL | 306 | #define PROC_DYNAMIC_FIRST 0xF0000000U |
307 | 307 | ||
308 | /* | 308 | /* |
309 | * Return an inode number between PROC_DYNAMIC_FIRST and | 309 | * Return an inode number between PROC_DYNAMIC_FIRST and |
@@ -311,36 +311,33 @@ static DEFINE_SPINLOCK(proc_inum_lock); /* protects the above */ | |||
311 | */ | 311 | */ |
312 | static unsigned int get_inode_number(void) | 312 | static unsigned int get_inode_number(void) |
313 | { | 313 | { |
314 | int i, inum = 0; | 314 | unsigned int i; |
315 | int error; | 315 | int error; |
316 | 316 | ||
317 | retry: | 317 | retry: |
318 | if (idr_pre_get(&proc_inum_idr, GFP_KERNEL) == 0) | 318 | if (ida_pre_get(&proc_inum_ida, GFP_KERNEL) == 0) |
319 | return 0; | 319 | return 0; |
320 | 320 | ||
321 | spin_lock(&proc_inum_lock); | 321 | spin_lock(&proc_inum_lock); |
322 | error = idr_get_new(&proc_inum_idr, NULL, &i); | 322 | error = ida_get_new(&proc_inum_ida, &i); |
323 | spin_unlock(&proc_inum_lock); | 323 | spin_unlock(&proc_inum_lock); |
324 | if (error == -EAGAIN) | 324 | if (error == -EAGAIN) |
325 | goto retry; | 325 | goto retry; |
326 | else if (error) | 326 | else if (error) |
327 | return 0; | 327 | return 0; |
328 | 328 | ||
329 | inum = (i & MAX_ID_MASK) + PROC_DYNAMIC_FIRST; | 329 | if (i > UINT_MAX - PROC_DYNAMIC_FIRST) { |
330 | 330 | spin_lock(&proc_inum_lock); | |
331 | /* inum will never be more than 0xf0ffffff, so no check | 331 | ida_remove(&proc_inum_ida, i); |
332 | * for overflow. | 332 | spin_unlock(&proc_inum_lock); |
333 | */ | 333 | } |
334 | 334 | return PROC_DYNAMIC_FIRST + i; | |
335 | return inum; | ||
336 | } | 335 | } |
337 | 336 | ||
338 | static void release_inode_number(unsigned int inum) | 337 | static void release_inode_number(unsigned int inum) |
339 | { | 338 | { |
340 | int id = (inum - PROC_DYNAMIC_FIRST) | ~MAX_ID_MASK; | ||
341 | |||
342 | spin_lock(&proc_inum_lock); | 339 | spin_lock(&proc_inum_lock); |
343 | idr_remove(&proc_inum_idr, id); | 340 | ida_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST); |
344 | spin_unlock(&proc_inum_lock); | 341 | spin_unlock(&proc_inum_lock); |
345 | } | 342 | } |
346 | 343 | ||