aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2006-10-02 05:18:49 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-02 10:57:24 -0400
commit61a28784028e6d55755e4d0f39bee8d9bf2ee8d9 (patch)
treeee114d76871f98da80ab14e9a86416da27a1787e /fs/proc
parent444ceed8d186631fdded5e3f24dc20b93d0d3fda (diff)
[PATCH] proc: Remove the hard coded inode numbers
The hard coded inode numbers in proc currently limit its maintainability, its flexibility, and what can be done with the rest of system. /proc limits pid-max to 32768 on 32 bit systems it limits fd-max to 32768 on all systems, and placing the pid in the inode number really gets in the way of implementing subdirectories of per process information. Ever since people started adding to the middle of the file type enumeration we haven't been maintaing the historical inode numbers, all we have really succeeded in doing is keeping the pid in the proc inode number. The pid is already available in the directory name so no information is lost removing it from the inode number. So if something in user space cares if we remove the inode number from the /proc inode it is almost certainly broken. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/base.c384
1 files changed, 174 insertions, 210 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index e8084eb037e3..7bf28c3af70c 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -84,114 +84,11 @@
84 * in /proc for a task before it execs a suid executable. 84 * in /proc for a task before it execs a suid executable.
85 */ 85 */
86 86
87/*
88 * For hysterical raisins we keep the same inumbers as in the old procfs.
89 * Feel free to change the macro below - just keep the range distinct from
90 * inumbers of the rest of procfs (currently those are in 0x0000--0xffff).
91 * As soon as we'll get a separate superblock we will be able to forget
92 * about magical ranges too.
93 */
94
95#define fake_ino(pid,ino) (((pid)<<16)|(ino))
96
97enum pid_directory_inos {
98 PROC_TGID_INO = 2,
99 PROC_TGID_TASK,
100 PROC_TGID_STATUS,
101 PROC_TGID_MEM,
102#ifdef CONFIG_SECCOMP
103 PROC_TGID_SECCOMP,
104#endif
105 PROC_TGID_CWD,
106 PROC_TGID_ROOT,
107 PROC_TGID_EXE,
108 PROC_TGID_FD,
109 PROC_TGID_ENVIRON,
110 PROC_TGID_AUXV,
111 PROC_TGID_CMDLINE,
112 PROC_TGID_STAT,
113 PROC_TGID_STATM,
114 PROC_TGID_MAPS,
115 PROC_TGID_NUMA_MAPS,
116 PROC_TGID_MOUNTS,
117 PROC_TGID_MOUNTSTATS,
118 PROC_TGID_WCHAN,
119#ifdef CONFIG_MMU
120 PROC_TGID_SMAPS,
121#endif
122#ifdef CONFIG_SCHEDSTATS
123 PROC_TGID_SCHEDSTAT,
124#endif
125#ifdef CONFIG_CPUSETS
126 PROC_TGID_CPUSET,
127#endif
128#ifdef CONFIG_SECURITY
129 PROC_TGID_ATTR,
130 PROC_TGID_ATTR_CURRENT,
131 PROC_TGID_ATTR_PREV,
132 PROC_TGID_ATTR_EXEC,
133 PROC_TGID_ATTR_FSCREATE,
134 PROC_TGID_ATTR_KEYCREATE,
135 PROC_TGID_ATTR_SOCKCREATE,
136#endif
137#ifdef CONFIG_AUDITSYSCALL
138 PROC_TGID_LOGINUID,
139#endif
140 PROC_TGID_OOM_SCORE,
141 PROC_TGID_OOM_ADJUST,
142 PROC_TID_INO,
143 PROC_TID_STATUS,
144 PROC_TID_MEM,
145#ifdef CONFIG_SECCOMP
146 PROC_TID_SECCOMP,
147#endif
148 PROC_TID_CWD,
149 PROC_TID_ROOT,
150 PROC_TID_EXE,
151 PROC_TID_FD,
152 PROC_TID_ENVIRON,
153 PROC_TID_AUXV,
154 PROC_TID_CMDLINE,
155 PROC_TID_STAT,
156 PROC_TID_STATM,
157 PROC_TID_MAPS,
158 PROC_TID_NUMA_MAPS,
159 PROC_TID_MOUNTS,
160 PROC_TID_MOUNTSTATS,
161 PROC_TID_WCHAN,
162#ifdef CONFIG_MMU
163 PROC_TID_SMAPS,
164#endif
165#ifdef CONFIG_SCHEDSTATS
166 PROC_TID_SCHEDSTAT,
167#endif
168#ifdef CONFIG_CPUSETS
169 PROC_TID_CPUSET,
170#endif
171#ifdef CONFIG_SECURITY
172 PROC_TID_ATTR,
173 PROC_TID_ATTR_CURRENT,
174 PROC_TID_ATTR_PREV,
175 PROC_TID_ATTR_EXEC,
176 PROC_TID_ATTR_FSCREATE,
177 PROC_TID_ATTR_KEYCREATE,
178 PROC_TID_ATTR_SOCKCREATE,
179#endif
180#ifdef CONFIG_AUDITSYSCALL
181 PROC_TID_LOGINUID,
182#endif
183 PROC_TID_OOM_SCORE,
184 PROC_TID_OOM_ADJUST,
185
186 /* Add new entries before this */
187 PROC_TID_FD_DIR = 0x8000, /* 0x8000-0xffff */
188};
189 87
190/* Worst case buffer size needed for holding an integer. */ 88/* Worst case buffer size needed for holding an integer. */
191#define PROC_NUMBUF 10 89#define PROC_NUMBUF 10
192 90
193struct pid_entry { 91struct pid_entry {
194 int type;
195 int len; 92 int len;
196 char *name; 93 char *name;
197 mode_t mode; 94 mode_t mode;
@@ -200,8 +97,7 @@ struct pid_entry {
200 union proc_op op; 97 union proc_op op;
201}; 98};
202 99
203#define NOD(TYPE, NAME, MODE, IOP, FOP, OP) { \ 100#define NOD(NAME, MODE, IOP, FOP, OP) { \
204 .type = (TYPE), \
205 .len = sizeof(NAME) - 1, \ 101 .len = sizeof(NAME) - 1, \
206 .name = (NAME), \ 102 .name = (NAME), \
207 .mode = MODE, \ 103 .mode = MODE, \
@@ -210,19 +106,19 @@ struct pid_entry {
210 .op = OP, \ 106 .op = OP, \
211} 107}
212 108
213#define DIR(TYPE, NAME, MODE, OTYPE) \ 109#define DIR(NAME, MODE, OTYPE) \
214 NOD(TYPE, NAME, (S_IFDIR|(MODE)), \ 110 NOD(NAME, (S_IFDIR|(MODE)), \
215 &proc_##OTYPE##_inode_operations, &proc_##OTYPE##_operations, \ 111 &proc_##OTYPE##_inode_operations, &proc_##OTYPE##_operations, \
216 {} ) 112 {} )
217#define LNK(TYPE, NAME, OTYPE) \ 113#define LNK(NAME, OTYPE) \
218 NOD(TYPE, NAME, (S_IFLNK|S_IRWXUGO), \ 114 NOD(NAME, (S_IFLNK|S_IRWXUGO), \
219 &proc_pid_link_inode_operations, NULL, \ 115 &proc_pid_link_inode_operations, NULL, \
220 { .proc_get_link = &proc_##OTYPE##_link } ) 116 { .proc_get_link = &proc_##OTYPE##_link } )
221#define REG(TYPE, NAME, MODE, OTYPE) \ 117#define REG(NAME, MODE, OTYPE) \
222 NOD(TYPE, NAME, (S_IFREG|(MODE)), NULL, \ 118 NOD(NAME, (S_IFREG|(MODE)), NULL, \
223 &proc_##OTYPE##_operations, {}) 119 &proc_##OTYPE##_operations, {})
224#define INF(TYPE, NAME, MODE, OTYPE) \ 120#define INF(NAME, MODE, OTYPE) \
225 NOD(TYPE, NAME, (S_IFREG|(MODE)), \ 121 NOD(NAME, (S_IFREG|(MODE)), \
226 NULL, &proc_info_file_operations, \ 122 NULL, &proc_info_file_operations, \
227 { .proc_read = &proc_##OTYPE } ) 123 { .proc_read = &proc_##OTYPE } )
228 124
@@ -1043,7 +939,7 @@ static int task_dumpable(struct task_struct *task)
1043} 939}
1044 940
1045 941
1046static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task, int ino) 942static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task)
1047{ 943{
1048 struct inode * inode; 944 struct inode * inode;
1049 struct proc_inode *ei; 945 struct proc_inode *ei;
@@ -1057,7 +953,6 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
1057 /* Common stuff */ 953 /* Common stuff */
1058 ei = PROC_I(inode); 954 ei = PROC_I(inode);
1059 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 955 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
1060 inode->i_ino = fake_ino(task->pid, ino);
1061 inode->i_op = &proc_def_inode_operations; 956 inode->i_op = &proc_def_inode_operations;
1062 957
1063 /* 958 /*
@@ -1160,6 +1055,50 @@ static struct dentry_operations pid_dentry_operations =
1160 1055
1161/* Lookups */ 1056/* Lookups */
1162 1057
1058typedef struct dentry *instantiate_t(struct inode *, struct dentry *, struct task_struct *, void *);
1059
1060static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
1061 char *name, int len,
1062 instantiate_t instantiate, struct task_struct *task, void *ptr)
1063{
1064 struct dentry *child, *dir = filp->f_dentry;
1065 struct inode *inode;
1066 struct qstr qname;
1067 ino_t ino = 0;
1068 unsigned type = DT_UNKNOWN;
1069
1070 qname.name = name;
1071 qname.len = len;
1072 qname.hash = full_name_hash(name, len);
1073
1074 child = d_lookup(dir, &qname);
1075 if (!child) {
1076 struct dentry *new;
1077 new = d_alloc(dir, &qname);
1078 if (new) {
1079 child = instantiate(dir->d_inode, new, task, ptr);
1080 if (child)
1081 dput(new);
1082 else
1083 child = new;
1084 }
1085 }
1086 if (!child || IS_ERR(child) || !child->d_inode)
1087 goto end_instantiate;
1088 inode = child->d_inode;
1089 if (inode) {
1090 ino = inode->i_ino;
1091 type = inode->i_mode >> 12;
1092 }
1093 dput(child);
1094end_instantiate:
1095 if (!ino)
1096 ino = find_inode_number(dir, &qname);
1097 if (!ino)
1098 ino = 1;
1099 return filldir(dirent, name, len, filp->f_pos, ino, type);
1100}
1101
1163static unsigned name_to_int(struct dentry *dentry) 1102static unsigned name_to_int(struct dentry *dentry)
1164{ 1103{
1165 const char *name = dentry->d_name.name; 1104 const char *name = dentry->d_name.name;
@@ -1264,7 +1203,7 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
1264 struct proc_inode *ei; 1203 struct proc_inode *ei;
1265 struct dentry *error = ERR_PTR(-ENOENT); 1204 struct dentry *error = ERR_PTR(-ENOENT);
1266 1205
1267 inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_FD_DIR+fd); 1206 inode = proc_pid_make_inode(dir->i_sb, task);
1268 if (!inode) 1207 if (!inode)
1269 goto out; 1208 goto out;
1270 ei = PROC_I(inode); 1209 ei = PROC_I(inode);
@@ -1327,6 +1266,15 @@ out_no_task:
1327 return result; 1266 return result;
1328} 1267}
1329 1268
1269static int proc_fd_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
1270 struct task_struct *task, int fd)
1271{
1272 char name[PROC_NUMBUF];
1273 int len = snprintf(name, sizeof(name), "%d", fd);
1274 return proc_fill_cache(filp, dirent, filldir, name, len,
1275 proc_fd_instantiate, task, &fd);
1276}
1277
1330static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) 1278static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
1331{ 1279{
1332 struct dentry *dentry = filp->f_dentry; 1280 struct dentry *dentry = filp->f_dentry;
@@ -1334,7 +1282,6 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
1334 struct task_struct *p = get_proc_task(inode); 1282 struct task_struct *p = get_proc_task(inode);
1335 unsigned int fd, tid, ino; 1283 unsigned int fd, tid, ino;
1336 int retval; 1284 int retval;
1337 char buf[PROC_NUMBUF];
1338 struct files_struct * files; 1285 struct files_struct * files;
1339 struct fdtable *fdt; 1286 struct fdtable *fdt;
1340 1287
@@ -1364,22 +1311,12 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
1364 for (fd = filp->f_pos-2; 1311 for (fd = filp->f_pos-2;
1365 fd < fdt->max_fds; 1312 fd < fdt->max_fds;
1366 fd++, filp->f_pos++) { 1313 fd++, filp->f_pos++) {
1367 unsigned int i,j;
1368 1314
1369 if (!fcheck_files(files, fd)) 1315 if (!fcheck_files(files, fd))
1370 continue; 1316 continue;
1371 rcu_read_unlock(); 1317 rcu_read_unlock();
1372 1318
1373 j = PROC_NUMBUF; 1319 if (proc_fd_fill_cache(filp, dirent, filldir, p, fd) < 0) {
1374 i = fd;
1375 do {
1376 j--;
1377 buf[j] = '0' + (i % 10);
1378 i /= 10;
1379 } while (i);
1380
1381 ino = fake_ino(tid, PROC_TID_FD_DIR + fd);
1382 if (filldir(dirent, buf+j, PROC_NUMBUF-j, fd+2, ino, DT_LNK) < 0) {
1383 rcu_read_lock(); 1320 rcu_read_lock();
1384 break; 1321 break;
1385 } 1322 }
@@ -1415,7 +1352,7 @@ static struct dentry *proc_pident_instantiate(struct inode *dir,
1415 struct proc_inode *ei; 1352 struct proc_inode *ei;
1416 struct dentry *error = ERR_PTR(-EINVAL); 1353 struct dentry *error = ERR_PTR(-EINVAL);
1417 1354
1418 inode = proc_pid_make_inode(dir->i_sb, task, p->type); 1355 inode = proc_pid_make_inode(dir->i_sb, task);
1419 if (!inode) 1356 if (!inode)
1420 goto out; 1357 goto out;
1421 1358
@@ -1473,6 +1410,13 @@ out_no_task:
1473 return error; 1410 return error;
1474} 1411}
1475 1412
1413static int proc_pident_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
1414 struct task_struct *task, struct pid_entry *p)
1415{
1416 return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
1417 proc_pident_instantiate, task, p);
1418}
1419
1476static int proc_pident_readdir(struct file *filp, 1420static int proc_pident_readdir(struct file *filp,
1477 void *dirent, filldir_t filldir, 1421 void *dirent, filldir_t filldir,
1478 struct pid_entry *ents, unsigned int nents) 1422 struct pid_entry *ents, unsigned int nents)
@@ -1488,11 +1432,10 @@ static int proc_pident_readdir(struct file *filp,
1488 1432
1489 ret = -ENOENT; 1433 ret = -ENOENT;
1490 if (!task) 1434 if (!task)
1491 goto out; 1435 goto out_no_task;
1492 1436
1493 ret = 0; 1437 ret = 0;
1494 pid = task->pid; 1438 pid = task->pid;
1495 put_task_struct(task);
1496 i = filp->f_pos; 1439 i = filp->f_pos;
1497 switch (i) { 1440 switch (i) {
1498 case 0: 1441 case 0:
@@ -1517,8 +1460,7 @@ static int proc_pident_readdir(struct file *filp,
1517 } 1460 }
1518 p = ents + i; 1461 p = ents + i;
1519 while (p->name) { 1462 while (p->name) {
1520 if (filldir(dirent, p->name, p->len, filp->f_pos, 1463 if (proc_pident_fill_cache(filp, dirent, filldir, task, p) < 0)
1521 fake_ino(pid, p->type), p->mode >> 12) < 0)
1522 goto out; 1464 goto out;
1523 filp->f_pos++; 1465 filp->f_pos++;
1524 p++; 1466 p++;
@@ -1527,6 +1469,8 @@ static int proc_pident_readdir(struct file *filp,
1527 1469
1528 ret = 1; 1470 ret = 1;
1529out: 1471out:
1472 put_task_struct(task);
1473out_no_task:
1530 return ret; 1474 return ret;
1531} 1475}
1532 1476
@@ -1606,21 +1550,21 @@ static struct file_operations proc_pid_attr_operations = {
1606}; 1550};
1607 1551
1608static struct pid_entry tgid_attr_stuff[] = { 1552static struct pid_entry tgid_attr_stuff[] = {
1609 REG(PROC_TGID_ATTR_CURRENT, "current", S_IRUGO|S_IWUGO, pid_attr), 1553 REG("current", S_IRUGO|S_IWUGO, pid_attr),
1610 REG(PROC_TGID_ATTR_PREV, "prev", S_IRUGO, pid_attr), 1554 REG("prev", S_IRUGO, pid_attr),
1611 REG(PROC_TGID_ATTR_EXEC, "exec", S_IRUGO|S_IWUGO, pid_attr), 1555 REG("exec", S_IRUGO|S_IWUGO, pid_attr),
1612 REG(PROC_TGID_ATTR_FSCREATE, "fscreate", S_IRUGO|S_IWUGO, pid_attr), 1556 REG("fscreate", S_IRUGO|S_IWUGO, pid_attr),
1613 REG(PROC_TGID_ATTR_KEYCREATE, "keycreate", S_IRUGO|S_IWUGO, pid_attr), 1557 REG("keycreate", S_IRUGO|S_IWUGO, pid_attr),
1614 REG(PROC_TGID_ATTR_SOCKCREATE, "sockcreate", S_IRUGO|S_IWUGO, pid_attr), 1558 REG("sockcreate", S_IRUGO|S_IWUGO, pid_attr),
1615 {} 1559 {}
1616}; 1560};
1617static struct pid_entry tid_attr_stuff[] = { 1561static struct pid_entry tid_attr_stuff[] = {
1618 REG(PROC_TID_ATTR_CURRENT, "current", S_IRUGO|S_IWUGO, pid_attr), 1562 REG("current", S_IRUGO|S_IWUGO, pid_attr),
1619 REG(PROC_TID_ATTR_PREV, "prev", S_IRUGO, pid_attr), 1563 REG("prev", S_IRUGO, pid_attr),
1620 REG(PROC_TID_ATTR_EXEC, "exec", S_IRUGO|S_IWUGO, pid_attr), 1564 REG("exec", S_IRUGO|S_IWUGO, pid_attr),
1621 REG(PROC_TID_ATTR_FSCREATE, "fscreate", S_IRUGO|S_IWUGO, pid_attr), 1565 REG("fscreate", S_IRUGO|S_IWUGO, pid_attr),
1622 REG(PROC_TID_ATTR_KEYCREATE, "keycreate", S_IRUGO|S_IWUGO, pid_attr), 1566 REG("keycreate", S_IRUGO|S_IWUGO, pid_attr),
1623 REG(PROC_TID_ATTR_SOCKCREATE, "sockcreate", S_IRUGO|S_IWUGO, pid_attr), 1567 REG("sockcreate", S_IRUGO|S_IWUGO, pid_attr),
1624 {} 1568 {}
1625}; 1569};
1626 1570
@@ -1704,7 +1648,7 @@ static struct inode_operations proc_self_inode_operations = {
1704 * describe something that is process related. 1648 * describe something that is process related.
1705 */ 1649 */
1706static struct pid_entry proc_base_stuff[] = { 1650static struct pid_entry proc_base_stuff[] = {
1707 NOD(PROC_TGID_INO, "self", S_IFLNK|S_IRWXUGO, 1651 NOD("self", S_IFLNK|S_IRWXUGO,
1708 &proc_self_inode_operations, NULL, {}), 1652 &proc_self_inode_operations, NULL, {}),
1709 {} 1653 {}
1710}; 1654};
@@ -1749,7 +1693,6 @@ static struct dentry *proc_base_instantiate(struct inode *dir,
1749 /* Initialize the inode */ 1693 /* Initialize the inode */
1750 ei = PROC_I(inode); 1694 ei = PROC_I(inode);
1751 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 1695 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
1752 inode->i_ino = fake_ino(0, p->type);
1753 1696
1754 /* 1697 /*
1755 * grab the reference to the task. 1698 * grab the reference to the task.
@@ -1809,6 +1752,13 @@ out_no_task:
1809 return error; 1752 return error;
1810} 1753}
1811 1754
1755static int proc_base_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
1756 struct task_struct *task, struct pid_entry *p)
1757{
1758 return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
1759 proc_base_instantiate, task, p);
1760}
1761
1812/* 1762/*
1813 * Thread groups 1763 * Thread groups
1814 */ 1764 */
@@ -1816,46 +1766,46 @@ static struct file_operations proc_task_operations;
1816static struct inode_operations proc_task_inode_operations; 1766static struct inode_operations proc_task_inode_operations;
1817 1767
1818static struct pid_entry tgid_base_stuff[] = { 1768static struct pid_entry tgid_base_stuff[] = {
1819 DIR(PROC_TGID_TASK, "task", S_IRUGO|S_IXUGO, task), 1769 DIR("task", S_IRUGO|S_IXUGO, task),
1820 DIR(PROC_TGID_FD, "fd", S_IRUSR|S_IXUSR, fd), 1770 DIR("fd", S_IRUSR|S_IXUSR, fd),
1821 INF(PROC_TGID_ENVIRON, "environ", S_IRUSR, pid_environ), 1771 INF("environ", S_IRUSR, pid_environ),
1822 INF(PROC_TGID_AUXV, "auxv", S_IRUSR, pid_auxv), 1772 INF("auxv", S_IRUSR, pid_auxv),
1823 INF(PROC_TGID_STATUS, "status", S_IRUGO, pid_status), 1773 INF("status", S_IRUGO, pid_status),
1824 INF(PROC_TGID_CMDLINE, "cmdline", S_IRUGO, pid_cmdline), 1774 INF("cmdline", S_IRUGO, pid_cmdline),
1825 INF(PROC_TGID_STAT, "stat", S_IRUGO, tgid_stat), 1775 INF("stat", S_IRUGO, tgid_stat),
1826 INF(PROC_TGID_STATM, "statm", S_IRUGO, pid_statm), 1776 INF("statm", S_IRUGO, pid_statm),
1827 REG(PROC_TGID_MAPS, "maps", S_IRUGO, maps), 1777 REG("maps", S_IRUGO, maps),
1828#ifdef CONFIG_NUMA 1778#ifdef CONFIG_NUMA
1829 REG(PROC_TGID_NUMA_MAPS, "numa_maps", S_IRUGO, numa_maps), 1779 REG("numa_maps", S_IRUGO, numa_maps),
1830#endif 1780#endif
1831 REG(PROC_TGID_MEM, "mem", S_IRUSR|S_IWUSR, mem), 1781 REG("mem", S_IRUSR|S_IWUSR, mem),
1832#ifdef CONFIG_SECCOMP 1782#ifdef CONFIG_SECCOMP
1833 REG(PROC_TGID_SECCOMP, "seccomp", S_IRUSR|S_IWUSR, seccomp), 1783 REG("seccomp", S_IRUSR|S_IWUSR, seccomp),
1834#endif 1784#endif
1835 LNK(PROC_TGID_CWD, "cwd", cwd), 1785 LNK("cwd", cwd),
1836 LNK(PROC_TGID_ROOT, "root", root), 1786 LNK("root", root),
1837 LNK(PROC_TGID_EXE, "exe", exe), 1787 LNK("exe", exe),
1838 REG(PROC_TGID_MOUNTS, "mounts", S_IRUGO, mounts), 1788 REG("mounts", S_IRUGO, mounts),
1839 REG(PROC_TGID_MOUNTSTATS, "mountstats", S_IRUSR, mountstats), 1789 REG("mountstats", S_IRUSR, mountstats),
1840#ifdef CONFIG_MMU 1790#ifdef CONFIG_MMU
1841 REG(PROC_TGID_SMAPS, "smaps", S_IRUGO, smaps), 1791 REG("smaps", S_IRUGO, smaps),
1842#endif 1792#endif
1843#ifdef CONFIG_SECURITY 1793#ifdef CONFIG_SECURITY
1844 DIR(PROC_TGID_ATTR, "attr", S_IRUGO|S_IXUGO, tgid_attr), 1794 DIR("attr", S_IRUGO|S_IXUGO, tgid_attr),
1845#endif 1795#endif
1846#ifdef CONFIG_KALLSYMS 1796#ifdef CONFIG_KALLSYMS
1847 INF(PROC_TGID_WCHAN, "wchan", S_IRUGO, pid_wchan), 1797 INF("wchan", S_IRUGO, pid_wchan),
1848#endif 1798#endif
1849#ifdef CONFIG_SCHEDSTATS 1799#ifdef CONFIG_SCHEDSTATS
1850 INF(PROC_TGID_SCHEDSTAT, "schedstat", S_IRUGO, pid_schedstat), 1800 INF("schedstat", S_IRUGO, pid_schedstat),
1851#endif 1801#endif
1852#ifdef CONFIG_CPUSETS 1802#ifdef CONFIG_CPUSETS
1853 REG(PROC_TGID_CPUSET, "cpuset", S_IRUGO, cpuset), 1803 REG("cpuset", S_IRUGO, cpuset),
1854#endif 1804#endif
1855 INF(PROC_TGID_OOM_SCORE, "oom_score", S_IRUGO, oom_score), 1805 INF("oom_score", S_IRUGO, oom_score),
1856 REG(PROC_TGID_OOM_ADJUST, "oom_adj", S_IRUGO|S_IWUSR, oom_adjust), 1806 REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust),
1857#ifdef CONFIG_AUDITSYSCALL 1807#ifdef CONFIG_AUDITSYSCALL
1858 REG(PROC_TGID_LOGINUID, "loginuid", S_IWUSR|S_IRUGO, loginuid), 1808 REG("loginuid", S_IWUSR|S_IRUGO, loginuid),
1859#endif 1809#endif
1860 {} 1810 {}
1861}; 1811};
@@ -1955,7 +1905,7 @@ struct dentry *proc_pid_instantiate(struct inode *dir,
1955 struct dentry *error = ERR_PTR(-ENOENT); 1905 struct dentry *error = ERR_PTR(-ENOENT);
1956 struct inode *inode; 1906 struct inode *inode;
1957 1907
1958 inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO); 1908 inode = proc_pid_make_inode(dir->i_sb, task);
1959 if (!inode) 1909 if (!inode)
1960 goto out; 1910 goto out;
1961 1911
@@ -2045,18 +1995,29 @@ retry:
2045 1995
2046#define TGID_OFFSET (FIRST_PROCESS_ENTRY + (1 /* /proc/self */)) 1996#define TGID_OFFSET (FIRST_PROCESS_ENTRY + (1 /* /proc/self */))
2047 1997
1998static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
1999 struct task_struct *task, int tgid)
2000{
2001 char name[PROC_NUMBUF];
2002 int len = snprintf(name, sizeof(name), "%d", tgid);
2003 return proc_fill_cache(filp, dirent, filldir, name, len,
2004 proc_pid_instantiate, task, NULL);
2005}
2006
2048/* for the /proc/ directory itself, after non-process stuff has been done */ 2007/* for the /proc/ directory itself, after non-process stuff has been done */
2049int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) 2008int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
2050{ 2009{
2051 char buf[PROC_NUMBUF];
2052 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY; 2010 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
2011 struct task_struct *reaper = get_proc_task(filp->f_dentry->d_inode);
2053 struct task_struct *task; 2012 struct task_struct *task;
2054 int tgid; 2013 int tgid;
2055 2014
2015 if (!reaper)
2016 goto out_no_task;
2017
2056 for (; nr < (ARRAY_SIZE(proc_base_stuff) - 1); filp->f_pos++, nr++) { 2018 for (; nr < (ARRAY_SIZE(proc_base_stuff) - 1); filp->f_pos++, nr++) {
2057 struct pid_entry *p = &proc_base_stuff[nr]; 2019 struct pid_entry *p = &proc_base_stuff[nr];
2058 if (filldir(dirent, p->name, p->len, filp->f_pos, 2020 if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0)
2059 fake_ino(0, p->type), p->mode >> 12) < 0)
2060 goto out; 2021 goto out;
2061 } 2022 }
2062 2023
@@ -2064,19 +2025,17 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
2064 for (task = next_tgid(tgid); 2025 for (task = next_tgid(tgid);
2065 task; 2026 task;
2066 put_task_struct(task), task = next_tgid(tgid + 1)) { 2027 put_task_struct(task), task = next_tgid(tgid + 1)) {
2067 int len;
2068 ino_t ino;
2069 tgid = task->pid; 2028 tgid = task->pid;
2070 filp->f_pos = tgid + TGID_OFFSET; 2029 filp->f_pos = tgid + TGID_OFFSET;
2071 len = snprintf(buf, sizeof(buf), "%d", tgid); 2030 if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
2072 ino = fake_ino(tgid, PROC_TGID_INO);
2073 if (filldir(dirent, buf, len, filp->f_pos, ino, DT_DIR) < 0) {
2074 put_task_struct(task); 2031 put_task_struct(task);
2075 goto out; 2032 goto out;
2076 } 2033 }
2077 } 2034 }
2078 filp->f_pos = PID_MAX_LIMIT + TGID_OFFSET; 2035 filp->f_pos = PID_MAX_LIMIT + TGID_OFFSET;
2079out: 2036out:
2037 put_task_struct(reaper);
2038out_no_task:
2080 return 0; 2039 return 0;
2081} 2040}
2082 2041
@@ -2084,44 +2043,44 @@ out:
2084 * Tasks 2043 * Tasks
2085 */ 2044 */
2086static struct pid_entry tid_base_stuff[] = { 2045static struct pid_entry tid_base_stuff[] = {
2087 DIR(PROC_TID_FD, "fd", S_IRUSR|S_IXUSR, fd), 2046 DIR("fd", S_IRUSR|S_IXUSR, fd),
2088 INF(PROC_TID_ENVIRON, "environ", S_IRUSR, pid_environ), 2047 INF("environ", S_IRUSR, pid_environ),
2089 INF(PROC_TID_AUXV, "auxv", S_IRUSR, pid_auxv), 2048 INF("auxv", S_IRUSR, pid_auxv),
2090 INF(PROC_TID_STATUS, "status", S_IRUGO, pid_status), 2049 INF("status", S_IRUGO, pid_status),
2091 INF(PROC_TID_CMDLINE, "cmdline", S_IRUGO, pid_cmdline), 2050 INF("cmdline", S_IRUGO, pid_cmdline),
2092 INF(PROC_TID_STAT, "stat", S_IRUGO, tid_stat), 2051 INF("stat", S_IRUGO, tid_stat),
2093 INF(PROC_TID_STATM, "statm", S_IRUGO, pid_statm), 2052 INF("statm", S_IRUGO, pid_statm),
2094 REG(PROC_TID_MAPS, "maps", S_IRUGO, maps), 2053 REG("maps", S_IRUGO, maps),
2095#ifdef CONFIG_NUMA 2054#ifdef CONFIG_NUMA
2096 REG(PROC_TID_NUMA_MAPS, "numa_maps", S_IRUGO, numa_maps), 2055 REG("numa_maps", S_IRUGO, numa_maps),
2097#endif 2056#endif
2098 REG(PROC_TID_MEM, "mem", S_IRUSR|S_IWUSR, mem), 2057 REG("mem", S_IRUSR|S_IWUSR, mem),
2099#ifdef CONFIG_SECCOMP 2058#ifdef CONFIG_SECCOMP
2100 REG(PROC_TID_SECCOMP, "seccomp", S_IRUSR|S_IWUSR, seccomp), 2059 REG("seccomp", S_IRUSR|S_IWUSR, seccomp),
2101#endif 2060#endif
2102 LNK(PROC_TID_CWD, "cwd", cwd), 2061 LNK("cwd", cwd),
2103 LNK(PROC_TID_ROOT, "root", root), 2062 LNK("root", root),
2104 LNK(PROC_TID_EXE, "exe", exe), 2063 LNK("exe", exe),
2105 REG(PROC_TID_MOUNTS, "mounts", S_IRUGO, mounts), 2064 REG("mounts", S_IRUGO, mounts),
2106#ifdef CONFIG_MMU 2065#ifdef CONFIG_MMU
2107 REG(PROC_TID_SMAPS, "smaps", S_IRUGO, smaps), 2066 REG("smaps", S_IRUGO, smaps),
2108#endif 2067#endif
2109#ifdef CONFIG_SECURITY 2068#ifdef CONFIG_SECURITY
2110 DIR(PROC_TID_ATTR, "attr", S_IRUGO|S_IXUGO, tid_attr), 2069 DIR("attr", S_IRUGO|S_IXUGO, tid_attr),
2111#endif 2070#endif
2112#ifdef CONFIG_KALLSYMS 2071#ifdef CONFIG_KALLSYMS
2113 INF(PROC_TID_WCHAN, "wchan", S_IRUGO, pid_wchan), 2072 INF("wchan", S_IRUGO, pid_wchan),
2114#endif 2073#endif
2115#ifdef CONFIG_SCHEDSTATS 2074#ifdef CONFIG_SCHEDSTATS
2116 INF(PROC_TID_SCHEDSTAT, "schedstat", S_IRUGO, pid_schedstat), 2075 INF("schedstat", S_IRUGO, pid_schedstat),
2117#endif 2076#endif
2118#ifdef CONFIG_CPUSETS 2077#ifdef CONFIG_CPUSETS
2119 REG(PROC_TID_CPUSET, "cpuset", S_IRUGO, cpuset), 2078 REG("cpuset", S_IRUGO, cpuset),
2120#endif 2079#endif
2121 INF(PROC_TID_OOM_SCORE, "oom_score", S_IRUGO, oom_score), 2080 INF("oom_score", S_IRUGO, oom_score),
2122 REG(PROC_TID_OOM_ADJUST, "oom_adj", S_IRUGO|S_IWUSR, oom_adjust), 2081 REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust),
2123#ifdef CONFIG_AUDITSYSCALL 2082#ifdef CONFIG_AUDITSYSCALL
2124 REG(PROC_TID_LOGINUID, "loginuid", S_IWUSR|S_IRUGO, loginuid), 2083 REG("loginuid", S_IWUSR|S_IRUGO, loginuid),
2125#endif 2084#endif
2126 {} 2085 {}
2127}; 2086};
@@ -2153,7 +2112,7 @@ static struct dentry *proc_task_instantiate(struct inode *dir,
2153{ 2112{
2154 struct dentry *error = ERR_PTR(-ENOENT); 2113 struct dentry *error = ERR_PTR(-ENOENT);
2155 struct inode *inode; 2114 struct inode *inode;
2156 inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO); 2115 inode = proc_pid_make_inode(dir->i_sb, task);
2157 2116
2158 if (!inode) 2117 if (!inode)
2159 goto out; 2118 goto out;
@@ -2279,10 +2238,18 @@ static struct task_struct *next_tid(struct task_struct *start)
2279 return pos; 2238 return pos;
2280} 2239}
2281 2240
2241static int proc_task_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
2242 struct task_struct *task, int tid)
2243{
2244 char name[PROC_NUMBUF];
2245 int len = snprintf(name, sizeof(name), "%d", tid);
2246 return proc_fill_cache(filp, dirent, filldir, name, len,
2247 proc_task_instantiate, task, NULL);
2248}
2249
2282/* for the /proc/TGID/task/ directories */ 2250/* for the /proc/TGID/task/ directories */
2283static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir) 2251static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir)
2284{ 2252{
2285 char buf[PROC_NUMBUF];
2286 struct dentry *dentry = filp->f_dentry; 2253 struct dentry *dentry = filp->f_dentry;
2287 struct inode *inode = dentry->d_inode; 2254 struct inode *inode = dentry->d_inode;
2288 struct task_struct *leader = get_proc_task(inode); 2255 struct task_struct *leader = get_proc_task(inode);
@@ -2319,11 +2286,8 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi
2319 for (task = first_tid(leader, tid, pos - 2); 2286 for (task = first_tid(leader, tid, pos - 2);
2320 task; 2287 task;
2321 task = next_tid(task), pos++) { 2288 task = next_tid(task), pos++) {
2322 int len;
2323 tid = task->pid; 2289 tid = task->pid;
2324 len = snprintf(buf, sizeof(buf), "%d", tid); 2290 if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) {
2325 ino = fake_ino(tid, PROC_TID_INO);
2326 if (filldir(dirent, buf, len, pos, ino, DT_DIR < 0)) {
2327 /* returning this tgid failed, save it as the first 2291 /* returning this tgid failed, save it as the first
2328 * pid for the next readir call */ 2292 * pid for the next readir call */
2329 filp->f_version = tid; 2293 filp->f_version = tid;