diff options
| -rw-r--r-- | fs/proc/base.c | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index c4fcd6465f73..725e279c3bdf 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
| @@ -1377,12 +1377,13 @@ out: | |||
| 1377 | /* SMP-safe */ | 1377 | /* SMP-safe */ |
| 1378 | static struct dentry *proc_pident_lookup(struct inode *dir, | 1378 | static struct dentry *proc_pident_lookup(struct inode *dir, |
| 1379 | struct dentry *dentry, | 1379 | struct dentry *dentry, |
| 1380 | struct pid_entry *ents) | 1380 | struct pid_entry *ents, |
| 1381 | unsigned int nents) | ||
| 1381 | { | 1382 | { |
| 1382 | struct inode *inode; | 1383 | struct inode *inode; |
| 1383 | struct dentry *error; | 1384 | struct dentry *error; |
| 1384 | struct task_struct *task = get_proc_task(dir); | 1385 | struct task_struct *task = get_proc_task(dir); |
| 1385 | struct pid_entry *p; | 1386 | struct pid_entry *p, *last; |
| 1386 | 1387 | ||
| 1387 | error = ERR_PTR(-ENOENT); | 1388 | error = ERR_PTR(-ENOENT); |
| 1388 | inode = NULL; | 1389 | inode = NULL; |
| @@ -1394,13 +1395,14 @@ static struct dentry *proc_pident_lookup(struct inode *dir, | |||
| 1394 | * Yes, it does not scale. And it should not. Don't add | 1395 | * Yes, it does not scale. And it should not. Don't add |
| 1395 | * new entries into /proc/<tgid>/ without very good reasons. | 1396 | * new entries into /proc/<tgid>/ without very good reasons. |
| 1396 | */ | 1397 | */ |
| 1397 | for (p = ents; p->name; p++) { | 1398 | last = &ents[nents - 1]; |
| 1399 | for (p = ents; p <= last; p++) { | ||
| 1398 | if (p->len != dentry->d_name.len) | 1400 | if (p->len != dentry->d_name.len) |
| 1399 | continue; | 1401 | continue; |
| 1400 | if (!memcmp(dentry->d_name.name, p->name, p->len)) | 1402 | if (!memcmp(dentry->d_name.name, p->name, p->len)) |
| 1401 | break; | 1403 | break; |
| 1402 | } | 1404 | } |
| 1403 | if (!p->name) | 1405 | if (p > last) |
| 1404 | goto out; | 1406 | goto out; |
| 1405 | 1407 | ||
| 1406 | error = proc_pident_instantiate(dir, dentry, task, p); | 1408 | error = proc_pident_instantiate(dir, dentry, task, p); |
| @@ -1426,7 +1428,7 @@ static int proc_pident_readdir(struct file *filp, | |||
| 1426 | struct dentry *dentry = filp->f_dentry; | 1428 | struct dentry *dentry = filp->f_dentry; |
| 1427 | struct inode *inode = dentry->d_inode; | 1429 | struct inode *inode = dentry->d_inode; |
| 1428 | struct task_struct *task = get_proc_task(inode); | 1430 | struct task_struct *task = get_proc_task(inode); |
| 1429 | struct pid_entry *p; | 1431 | struct pid_entry *p, *last; |
| 1430 | ino_t ino; | 1432 | ino_t ino; |
| 1431 | int ret; | 1433 | int ret; |
| 1432 | 1434 | ||
| @@ -1459,7 +1461,8 @@ static int proc_pident_readdir(struct file *filp, | |||
| 1459 | goto out; | 1461 | goto out; |
| 1460 | } | 1462 | } |
| 1461 | p = ents + i; | 1463 | p = ents + i; |
| 1462 | while (p->name) { | 1464 | last = &ents[nents - 1]; |
| 1465 | while (p <= last) { | ||
| 1463 | if (proc_pident_fill_cache(filp, dirent, filldir, task, p) < 0) | 1466 | if (proc_pident_fill_cache(filp, dirent, filldir, task, p) < 0) |
| 1464 | goto out; | 1467 | goto out; |
| 1465 | filp->f_pos++; | 1468 | filp->f_pos++; |
| @@ -1556,7 +1559,6 @@ static struct pid_entry attr_dir_stuff[] = { | |||
| 1556 | REG("fscreate", S_IRUGO|S_IWUGO, pid_attr), | 1559 | REG("fscreate", S_IRUGO|S_IWUGO, pid_attr), |
| 1557 | REG("keycreate", S_IRUGO|S_IWUGO, pid_attr), | 1560 | REG("keycreate", S_IRUGO|S_IWUGO, pid_attr), |
| 1558 | REG("sockcreate", S_IRUGO|S_IWUGO, pid_attr), | 1561 | REG("sockcreate", S_IRUGO|S_IWUGO, pid_attr), |
| 1559 | {} | ||
| 1560 | }; | 1562 | }; |
| 1561 | 1563 | ||
| 1562 | static int proc_attr_dir_readdir(struct file * filp, | 1564 | static int proc_attr_dir_readdir(struct file * filp, |
| @@ -1574,7 +1576,8 @@ static struct file_operations proc_attr_dir_operations = { | |||
| 1574 | static struct dentry *proc_attr_dir_lookup(struct inode *dir, | 1576 | static struct dentry *proc_attr_dir_lookup(struct inode *dir, |
| 1575 | struct dentry *dentry, struct nameidata *nd) | 1577 | struct dentry *dentry, struct nameidata *nd) |
| 1576 | { | 1578 | { |
| 1577 | return proc_pident_lookup(dir, dentry, attr_dir_stuff); | 1579 | return proc_pident_lookup(dir, dentry, |
| 1580 | attr_dir_stuff, ARRAY_SIZE(attr_dir_stuff)); | ||
| 1578 | } | 1581 | } |
| 1579 | 1582 | ||
| 1580 | static struct inode_operations proc_attr_dir_inode_operations = { | 1583 | static struct inode_operations proc_attr_dir_inode_operations = { |
| @@ -1618,7 +1621,6 @@ static struct inode_operations proc_self_inode_operations = { | |||
| 1618 | static struct pid_entry proc_base_stuff[] = { | 1621 | static struct pid_entry proc_base_stuff[] = { |
| 1619 | NOD("self", S_IFLNK|S_IRWXUGO, | 1622 | NOD("self", S_IFLNK|S_IRWXUGO, |
| 1620 | &proc_self_inode_operations, NULL, {}), | 1623 | &proc_self_inode_operations, NULL, {}), |
| 1621 | {} | ||
| 1622 | }; | 1624 | }; |
| 1623 | 1625 | ||
| 1624 | /* | 1626 | /* |
| @@ -1695,7 +1697,7 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) | |||
| 1695 | { | 1697 | { |
| 1696 | struct dentry *error; | 1698 | struct dentry *error; |
| 1697 | struct task_struct *task = get_proc_task(dir); | 1699 | struct task_struct *task = get_proc_task(dir); |
| 1698 | struct pid_entry *p; | 1700 | struct pid_entry *p, *last; |
| 1699 | 1701 | ||
| 1700 | error = ERR_PTR(-ENOENT); | 1702 | error = ERR_PTR(-ENOENT); |
| 1701 | 1703 | ||
| @@ -1703,13 +1705,14 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) | |||
| 1703 | goto out_no_task; | 1705 | goto out_no_task; |
| 1704 | 1706 | ||
| 1705 | /* Lookup the directory entry */ | 1707 | /* Lookup the directory entry */ |
| 1706 | for (p = proc_base_stuff; p->name; p++) { | 1708 | last = &proc_base_stuff[ARRAY_SIZE(proc_base_stuff) - 1]; |
| 1709 | for (p = proc_base_stuff; p <= last; p++) { | ||
| 1707 | if (p->len != dentry->d_name.len) | 1710 | if (p->len != dentry->d_name.len) |
| 1708 | continue; | 1711 | continue; |
| 1709 | if (!memcmp(dentry->d_name.name, p->name, p->len)) | 1712 | if (!memcmp(dentry->d_name.name, p->name, p->len)) |
| 1710 | break; | 1713 | break; |
| 1711 | } | 1714 | } |
| 1712 | if (!p->name) | 1715 | if (p > last) |
| 1713 | goto out; | 1716 | goto out; |
| 1714 | 1717 | ||
| 1715 | error = proc_base_instantiate(dir, dentry, task, p); | 1718 | error = proc_base_instantiate(dir, dentry, task, p); |
| @@ -1775,7 +1778,6 @@ static struct pid_entry tgid_base_stuff[] = { | |||
| 1775 | #ifdef CONFIG_AUDITSYSCALL | 1778 | #ifdef CONFIG_AUDITSYSCALL |
| 1776 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), | 1779 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), |
| 1777 | #endif | 1780 | #endif |
| 1778 | {} | ||
| 1779 | }; | 1781 | }; |
| 1780 | 1782 | ||
| 1781 | static int proc_tgid_base_readdir(struct file * filp, | 1783 | static int proc_tgid_base_readdir(struct file * filp, |
| @@ -1791,7 +1793,8 @@ static struct file_operations proc_tgid_base_operations = { | |||
| 1791 | }; | 1793 | }; |
| 1792 | 1794 | ||
| 1793 | static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ | 1795 | static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ |
| 1794 | return proc_pident_lookup(dir, dentry, tgid_base_stuff); | 1796 | return proc_pident_lookup(dir, dentry, |
| 1797 | tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff)); | ||
| 1795 | } | 1798 | } |
| 1796 | 1799 | ||
| 1797 | static struct inode_operations proc_tgid_base_inode_operations = { | 1800 | static struct inode_operations proc_tgid_base_inode_operations = { |
| @@ -1961,7 +1964,7 @@ retry: | |||
| 1961 | return task; | 1964 | return task; |
| 1962 | } | 1965 | } |
| 1963 | 1966 | ||
| 1964 | #define TGID_OFFSET (FIRST_PROCESS_ENTRY + (ARRAY_SIZE(proc_base_stuff) - 1)) | 1967 | #define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff)) |
| 1965 | 1968 | ||
| 1966 | static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | 1969 | static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir, |
| 1967 | struct task_struct *task, int tgid) | 1970 | struct task_struct *task, int tgid) |
| @@ -1983,7 +1986,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
| 1983 | if (!reaper) | 1986 | if (!reaper) |
| 1984 | goto out_no_task; | 1987 | goto out_no_task; |
| 1985 | 1988 | ||
| 1986 | for (; nr < (ARRAY_SIZE(proc_base_stuff) - 1); filp->f_pos++, nr++) { | 1989 | for (; nr < ARRAY_SIZE(proc_base_stuff); filp->f_pos++, nr++) { |
| 1987 | struct pid_entry *p = &proc_base_stuff[nr]; | 1990 | struct pid_entry *p = &proc_base_stuff[nr]; |
| 1988 | if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0) | 1991 | if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0) |
| 1989 | goto out; | 1992 | goto out; |
| @@ -2050,7 +2053,6 @@ static struct pid_entry tid_base_stuff[] = { | |||
| 2050 | #ifdef CONFIG_AUDITSYSCALL | 2053 | #ifdef CONFIG_AUDITSYSCALL |
| 2051 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), | 2054 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), |
| 2052 | #endif | 2055 | #endif |
| 2053 | {} | ||
| 2054 | }; | 2056 | }; |
| 2055 | 2057 | ||
| 2056 | static int proc_tid_base_readdir(struct file * filp, | 2058 | static int proc_tid_base_readdir(struct file * filp, |
| @@ -2061,7 +2063,8 @@ static int proc_tid_base_readdir(struct file * filp, | |||
| 2061 | } | 2063 | } |
| 2062 | 2064 | ||
| 2063 | static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ | 2065 | static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ |
| 2064 | return proc_pident_lookup(dir, dentry, tid_base_stuff); | 2066 | return proc_pident_lookup(dir, dentry, |
| 2067 | tid_base_stuff, ARRAY_SIZE(tid_base_stuff)); | ||
| 2065 | } | 2068 | } |
| 2066 | 2069 | ||
| 2067 | static struct file_operations proc_tid_base_operations = { | 2070 | static struct file_operations proc_tid_base_operations = { |
