aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmisison.com>2006-10-02 05:17:05 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-02 10:57:13 -0400
commit28a6d67179da6964d1640d379c5e5d4f46dd0042 (patch)
treedac1acf4a94f5718699d287603933f49df55d1e5 /fs/proc
parent0804ef4b0de7121261f77c565b20a11ac694e877 (diff)
[PATCH] proc: reorder the functions in base.c
There were enough changes in my last round of cleaning up proc I had to break up the patch series into smaller chunks, and my last chunk never got resent. This patchset gives proc dynamic inode numbers (the static inode numbers were a pain to maintain and prevent all kinds of things), and removes the horrible switch statements that had to be kept in sync with everything else. Being fully table driver takes us 90% of the way of being able to register new process specific attributes in proc. This patch: Group the functions by what they implement instead of by type of operation. As it existed base.c was quickly approaching the point where it could not be followed. No functionality or code changes asside from adding/removing forward declartions are implemented in this patch. 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.c998
1 files changed, 501 insertions, 497 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index b18f3773dd43..cb0cf84df748 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -198,147 +198,6 @@ struct pid_entry {
198 198
199#define E(type,name,mode) {(type),sizeof(name)-1,(name),(mode)} 199#define E(type,name,mode) {(type),sizeof(name)-1,(name),(mode)}
200 200
201static struct pid_entry tgid_base_stuff[] = {
202 E(PROC_TGID_TASK, "task", S_IFDIR|S_IRUGO|S_IXUGO),
203 E(PROC_TGID_FD, "fd", S_IFDIR|S_IRUSR|S_IXUSR),
204 E(PROC_TGID_ENVIRON, "environ", S_IFREG|S_IRUSR),
205 E(PROC_TGID_AUXV, "auxv", S_IFREG|S_IRUSR),
206 E(PROC_TGID_STATUS, "status", S_IFREG|S_IRUGO),
207 E(PROC_TGID_CMDLINE, "cmdline", S_IFREG|S_IRUGO),
208 E(PROC_TGID_STAT, "stat", S_IFREG|S_IRUGO),
209 E(PROC_TGID_STATM, "statm", S_IFREG|S_IRUGO),
210 E(PROC_TGID_MAPS, "maps", S_IFREG|S_IRUGO),
211#ifdef CONFIG_NUMA
212 E(PROC_TGID_NUMA_MAPS, "numa_maps", S_IFREG|S_IRUGO),
213#endif
214 E(PROC_TGID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR),
215#ifdef CONFIG_SECCOMP
216 E(PROC_TGID_SECCOMP, "seccomp", S_IFREG|S_IRUSR|S_IWUSR),
217#endif
218 E(PROC_TGID_CWD, "cwd", S_IFLNK|S_IRWXUGO),
219 E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO),
220 E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO),
221 E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
222 E(PROC_TGID_MOUNTSTATS, "mountstats", S_IFREG|S_IRUSR),
223#ifdef CONFIG_MMU
224 E(PROC_TGID_SMAPS, "smaps", S_IFREG|S_IRUGO),
225#endif
226#ifdef CONFIG_SECURITY
227 E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
228#endif
229#ifdef CONFIG_KALLSYMS
230 E(PROC_TGID_WCHAN, "wchan", S_IFREG|S_IRUGO),
231#endif
232#ifdef CONFIG_SCHEDSTATS
233 E(PROC_TGID_SCHEDSTAT, "schedstat", S_IFREG|S_IRUGO),
234#endif
235#ifdef CONFIG_CPUSETS
236 E(PROC_TGID_CPUSET, "cpuset", S_IFREG|S_IRUGO),
237#endif
238 E(PROC_TGID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO),
239 E(PROC_TGID_OOM_ADJUST,"oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
240#ifdef CONFIG_AUDITSYSCALL
241 E(PROC_TGID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
242#endif
243 {0,0,NULL,0}
244};
245static struct pid_entry tid_base_stuff[] = {
246 E(PROC_TID_FD, "fd", S_IFDIR|S_IRUSR|S_IXUSR),
247 E(PROC_TID_ENVIRON, "environ", S_IFREG|S_IRUSR),
248 E(PROC_TID_AUXV, "auxv", S_IFREG|S_IRUSR),
249 E(PROC_TID_STATUS, "status", S_IFREG|S_IRUGO),
250 E(PROC_TID_CMDLINE, "cmdline", S_IFREG|S_IRUGO),
251 E(PROC_TID_STAT, "stat", S_IFREG|S_IRUGO),
252 E(PROC_TID_STATM, "statm", S_IFREG|S_IRUGO),
253 E(PROC_TID_MAPS, "maps", S_IFREG|S_IRUGO),
254#ifdef CONFIG_NUMA
255 E(PROC_TID_NUMA_MAPS, "numa_maps", S_IFREG|S_IRUGO),
256#endif
257 E(PROC_TID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR),
258#ifdef CONFIG_SECCOMP
259 E(PROC_TID_SECCOMP, "seccomp", S_IFREG|S_IRUSR|S_IWUSR),
260#endif
261 E(PROC_TID_CWD, "cwd", S_IFLNK|S_IRWXUGO),
262 E(PROC_TID_ROOT, "root", S_IFLNK|S_IRWXUGO),
263 E(PROC_TID_EXE, "exe", S_IFLNK|S_IRWXUGO),
264 E(PROC_TID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
265#ifdef CONFIG_MMU
266 E(PROC_TID_SMAPS, "smaps", S_IFREG|S_IRUGO),
267#endif
268#ifdef CONFIG_SECURITY
269 E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
270#endif
271#ifdef CONFIG_KALLSYMS
272 E(PROC_TID_WCHAN, "wchan", S_IFREG|S_IRUGO),
273#endif
274#ifdef CONFIG_SCHEDSTATS
275 E(PROC_TID_SCHEDSTAT, "schedstat",S_IFREG|S_IRUGO),
276#endif
277#ifdef CONFIG_CPUSETS
278 E(PROC_TID_CPUSET, "cpuset", S_IFREG|S_IRUGO),
279#endif
280 E(PROC_TID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO),
281 E(PROC_TID_OOM_ADJUST, "oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
282#ifdef CONFIG_AUDITSYSCALL
283 E(PROC_TID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
284#endif
285 {0,0,NULL,0}
286};
287
288#ifdef CONFIG_SECURITY
289static struct pid_entry tgid_attr_stuff[] = {
290 E(PROC_TGID_ATTR_CURRENT, "current", S_IFREG|S_IRUGO|S_IWUGO),
291 E(PROC_TGID_ATTR_PREV, "prev", S_IFREG|S_IRUGO),
292 E(PROC_TGID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
293 E(PROC_TGID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
294 E(PROC_TGID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO),
295 E(PROC_TGID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO),
296 {0,0,NULL,0}
297};
298static struct pid_entry tid_attr_stuff[] = {
299 E(PROC_TID_ATTR_CURRENT, "current", S_IFREG|S_IRUGO|S_IWUGO),
300 E(PROC_TID_ATTR_PREV, "prev", S_IFREG|S_IRUGO),
301 E(PROC_TID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
302 E(PROC_TID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
303 E(PROC_TID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO),
304 E(PROC_TID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO),
305 {0,0,NULL,0}
306};
307#endif
308
309#undef E
310
311static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
312{
313 struct task_struct *task = get_proc_task(inode);
314 struct files_struct *files = NULL;
315 struct file *file;
316 int fd = proc_fd(inode);
317
318 if (task) {
319 files = get_files_struct(task);
320 put_task_struct(task);
321 }
322 if (files) {
323 /*
324 * We are not taking a ref to the file structure, so we must
325 * hold ->file_lock.
326 */
327 spin_lock(&files->file_lock);
328 file = fcheck_files(files, fd);
329 if (file) {
330 *mnt = mntget(file->f_vfsmnt);
331 *dentry = dget(file->f_dentry);
332 spin_unlock(&files->file_lock);
333 put_files_struct(files);
334 return 0;
335 }
336 spin_unlock(&files->file_lock);
337 put_files_struct(files);
338 }
339 return -ENOENT;
340}
341
342static struct fs_struct *get_fs_struct(struct task_struct *task) 201static struct fs_struct *get_fs_struct(struct task_struct *task)
343{ 202{
344 struct fs_struct *fs; 203 struct fs_struct *fs;
@@ -1137,143 +996,6 @@ static struct inode_operations proc_pid_link_inode_operations = {
1137 .setattr = proc_setattr, 996 .setattr = proc_setattr,
1138}; 997};
1139 998
1140static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
1141{
1142 struct dentry *dentry = filp->f_dentry;
1143 struct inode *inode = dentry->d_inode;
1144 struct task_struct *p = get_proc_task(inode);
1145 unsigned int fd, tid, ino;
1146 int retval;
1147 char buf[PROC_NUMBUF];
1148 struct files_struct * files;
1149 struct fdtable *fdt;
1150
1151 retval = -ENOENT;
1152 if (!p)
1153 goto out_no_task;
1154 retval = 0;
1155 tid = p->pid;
1156
1157 fd = filp->f_pos;
1158 switch (fd) {
1159 case 0:
1160 if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
1161 goto out;
1162 filp->f_pos++;
1163 case 1:
1164 ino = parent_ino(dentry);
1165 if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
1166 goto out;
1167 filp->f_pos++;
1168 default:
1169 files = get_files_struct(p);
1170 if (!files)
1171 goto out;
1172 rcu_read_lock();
1173 fdt = files_fdtable(files);
1174 for (fd = filp->f_pos-2;
1175 fd < fdt->max_fds;
1176 fd++, filp->f_pos++) {
1177 unsigned int i,j;
1178
1179 if (!fcheck_files(files, fd))
1180 continue;
1181 rcu_read_unlock();
1182
1183 j = PROC_NUMBUF;
1184 i = fd;
1185 do {
1186 j--;
1187 buf[j] = '0' + (i % 10);
1188 i /= 10;
1189 } while (i);
1190
1191 ino = fake_ino(tid, PROC_TID_FD_DIR + fd);
1192 if (filldir(dirent, buf+j, PROC_NUMBUF-j, fd+2, ino, DT_LNK) < 0) {
1193 rcu_read_lock();
1194 break;
1195 }
1196 rcu_read_lock();
1197 }
1198 rcu_read_unlock();
1199 put_files_struct(files);
1200 }
1201out:
1202 put_task_struct(p);
1203out_no_task:
1204 return retval;
1205}
1206
1207static int proc_pident_readdir(struct file *filp,
1208 void *dirent, filldir_t filldir,
1209 struct pid_entry *ents, unsigned int nents)
1210{
1211 int i;
1212 int pid;
1213 struct dentry *dentry = filp->f_dentry;
1214 struct inode *inode = dentry->d_inode;
1215 struct task_struct *task = get_proc_task(inode);
1216 struct pid_entry *p;
1217 ino_t ino;
1218 int ret;
1219
1220 ret = -ENOENT;
1221 if (!task)
1222 goto out;
1223
1224 ret = 0;
1225 pid = task->pid;
1226 put_task_struct(task);
1227 i = filp->f_pos;
1228 switch (i) {
1229 case 0:
1230 ino = inode->i_ino;
1231 if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
1232 goto out;
1233 i++;
1234 filp->f_pos++;
1235 /* fall through */
1236 case 1:
1237 ino = parent_ino(dentry);
1238 if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
1239 goto out;
1240 i++;
1241 filp->f_pos++;
1242 /* fall through */
1243 default:
1244 i -= 2;
1245 if (i >= nents) {
1246 ret = 1;
1247 goto out;
1248 }
1249 p = ents + i;
1250 while (p->name) {
1251 if (filldir(dirent, p->name, p->len, filp->f_pos,
1252 fake_ino(pid, p->type), p->mode >> 12) < 0)
1253 goto out;
1254 filp->f_pos++;
1255 p++;
1256 }
1257 }
1258
1259 ret = 1;
1260out:
1261 return ret;
1262}
1263
1264static int proc_tgid_base_readdir(struct file * filp,
1265 void * dirent, filldir_t filldir)
1266{
1267 return proc_pident_readdir(filp,dirent,filldir,
1268 tgid_base_stuff,ARRAY_SIZE(tgid_base_stuff));
1269}
1270
1271static int proc_tid_base_readdir(struct file * filp,
1272 void * dirent, filldir_t filldir)
1273{
1274 return proc_pident_readdir(filp,dirent,filldir,
1275 tid_base_stuff,ARRAY_SIZE(tid_base_stuff));
1276}
1277 999
1278/* building an inode */ 1000/* building an inode */
1279 1001
@@ -1299,7 +1021,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
1299 struct proc_inode *ei; 1021 struct proc_inode *ei;
1300 1022
1301 /* We need a new inode */ 1023 /* We need a new inode */
1302 1024
1303 inode = new_inode(sb); 1025 inode = new_inode(sb);
1304 if (!inode) 1026 if (!inode)
1305 goto out; 1027 goto out;
@@ -1333,6 +1055,27 @@ out_unlock:
1333 return NULL; 1055 return NULL;
1334} 1056}
1335 1057
1058static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
1059{
1060 struct inode *inode = dentry->d_inode;
1061 struct task_struct *task;
1062 generic_fillattr(inode, stat);
1063
1064 rcu_read_lock();
1065 stat->uid = 0;
1066 stat->gid = 0;
1067 task = pid_task(proc_pid(inode), PIDTYPE_PID);
1068 if (task) {
1069 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
1070 task_dumpable(task)) {
1071 stat->uid = task->euid;
1072 stat->gid = task->egid;
1073 }
1074 }
1075 rcu_read_unlock();
1076 return 0;
1077}
1078
1336/* dentry stuff */ 1079/* dentry stuff */
1337 1080
1338/* 1081/*
@@ -1372,25 +1115,74 @@ static int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
1372 return 0; 1115 return 0;
1373} 1116}
1374 1117
1375static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) 1118static int pid_delete_dentry(struct dentry * dentry)
1376{ 1119{
1377 struct inode *inode = dentry->d_inode; 1120 /* Is the task we represent dead?
1378 struct task_struct *task; 1121 * If so, then don't put the dentry on the lru list,
1379 generic_fillattr(inode, stat); 1122 * kill it immediately.
1123 */
1124 return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
1125}
1126
1127static struct dentry_operations pid_dentry_operations =
1128{
1129 .d_revalidate = pid_revalidate,
1130 .d_delete = pid_delete_dentry,
1131};
1132
1133/* Lookups */
1134
1135static unsigned name_to_int(struct dentry *dentry)
1136{
1137 const char *name = dentry->d_name.name;
1138 int len = dentry->d_name.len;
1139 unsigned n = 0;
1140
1141 if (len > 1 && *name == '0')
1142 goto out;
1143 while (len-- > 0) {
1144 unsigned c = *name++ - '0';
1145 if (c > 9)
1146 goto out;
1147 if (n >= (~0U-9)/10)
1148 goto out;
1149 n *= 10;
1150 n += c;
1151 }
1152 return n;
1153out:
1154 return ~0U;
1155}
1156
1157static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
1158{
1159 struct task_struct *task = get_proc_task(inode);
1160 struct files_struct *files = NULL;
1161 struct file *file;
1162 int fd = proc_fd(inode);
1380 1163
1381 rcu_read_lock();
1382 stat->uid = 0;
1383 stat->gid = 0;
1384 task = pid_task(proc_pid(inode), PIDTYPE_PID);
1385 if (task) { 1164 if (task) {
1386 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || 1165 files = get_files_struct(task);
1387 task_dumpable(task)) { 1166 put_task_struct(task);
1388 stat->uid = task->euid; 1167 }
1389 stat->gid = task->egid; 1168 if (files) {
1169 /*
1170 * We are not taking a ref to the file structure, so we must
1171 * hold ->file_lock.
1172 */
1173 spin_lock(&files->file_lock);
1174 file = fcheck_files(files, fd);
1175 if (file) {
1176 *mnt = mntget(file->f_vfsmnt);
1177 *dentry = dget(file->f_dentry);
1178 spin_unlock(&files->file_lock);
1179 put_files_struct(files);
1180 return 0;
1390 } 1181 }
1182 spin_unlock(&files->file_lock);
1183 put_files_struct(files);
1391 } 1184 }
1392 rcu_read_unlock(); 1185 return -ENOENT;
1393 return 0;
1394} 1186}
1395 1187
1396static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) 1188static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
@@ -1428,51 +1220,12 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
1428 return 0; 1220 return 0;
1429} 1221}
1430 1222
1431static int pid_delete_dentry(struct dentry * dentry)
1432{
1433 /* Is the task we represent dead?
1434 * If so, then don't put the dentry on the lru list,
1435 * kill it immediately.
1436 */
1437 return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
1438}
1439
1440static struct dentry_operations tid_fd_dentry_operations = 1223static struct dentry_operations tid_fd_dentry_operations =
1441{ 1224{
1442 .d_revalidate = tid_fd_revalidate, 1225 .d_revalidate = tid_fd_revalidate,
1443 .d_delete = pid_delete_dentry, 1226 .d_delete = pid_delete_dentry,
1444}; 1227};
1445 1228
1446static struct dentry_operations pid_dentry_operations =
1447{
1448 .d_revalidate = pid_revalidate,
1449 .d_delete = pid_delete_dentry,
1450};
1451
1452/* Lookups */
1453
1454static unsigned name_to_int(struct dentry *dentry)
1455{
1456 const char *name = dentry->d_name.name;
1457 int len = dentry->d_name.len;
1458 unsigned n = 0;
1459
1460 if (len > 1 && *name == '0')
1461 goto out;
1462 while (len-- > 0) {
1463 unsigned c = *name++ - '0';
1464 if (c > 9)
1465 goto out;
1466 if (n >= (~0U-9)/10)
1467 goto out;
1468 n *= 10;
1469 n += c;
1470 }
1471 return n;
1472out:
1473 return ~0U;
1474}
1475
1476/* SMP-safe */ 1229/* SMP-safe */
1477static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd) 1230static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
1478{ 1231{
@@ -1534,20 +1287,78 @@ out_unlock:
1534 goto out; 1287 goto out;
1535} 1288}
1536 1289
1537static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir); 1290static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
1538static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd); 1291{
1539static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); 1292 struct dentry *dentry = filp->f_dentry;
1293 struct inode *inode = dentry->d_inode;
1294 struct task_struct *p = get_proc_task(inode);
1295 unsigned int fd, tid, ino;
1296 int retval;
1297 char buf[PROC_NUMBUF];
1298 struct files_struct * files;
1299 struct fdtable *fdt;
1300
1301 retval = -ENOENT;
1302 if (!p)
1303 goto out_no_task;
1304 retval = 0;
1305 tid = p->pid;
1306
1307 fd = filp->f_pos;
1308 switch (fd) {
1309 case 0:
1310 if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
1311 goto out;
1312 filp->f_pos++;
1313 case 1:
1314 ino = parent_ino(dentry);
1315 if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
1316 goto out;
1317 filp->f_pos++;
1318 default:
1319 files = get_files_struct(p);
1320 if (!files)
1321 goto out;
1322 rcu_read_lock();
1323 fdt = files_fdtable(files);
1324 for (fd = filp->f_pos-2;
1325 fd < fdt->max_fds;
1326 fd++, filp->f_pos++) {
1327 unsigned int i,j;
1328
1329 if (!fcheck_files(files, fd))
1330 continue;
1331 rcu_read_unlock();
1332
1333 j = PROC_NUMBUF;
1334 i = fd;
1335 do {
1336 j--;
1337 buf[j] = '0' + (i % 10);
1338 i /= 10;
1339 } while (i);
1340
1341 ino = fake_ino(tid, PROC_TID_FD_DIR + fd);
1342 if (filldir(dirent, buf+j, PROC_NUMBUF-j, fd+2, ino, DT_LNK) < 0) {
1343 rcu_read_lock();
1344 break;
1345 }
1346 rcu_read_lock();
1347 }
1348 rcu_read_unlock();
1349 put_files_struct(files);
1350 }
1351out:
1352 put_task_struct(p);
1353out_no_task:
1354 return retval;
1355}
1540 1356
1541static struct file_operations proc_fd_operations = { 1357static struct file_operations proc_fd_operations = {
1542 .read = generic_read_dir, 1358 .read = generic_read_dir,
1543 .readdir = proc_readfd, 1359 .readdir = proc_readfd,
1544}; 1360};
1545 1361
1546static struct file_operations proc_task_operations = {
1547 .read = generic_read_dir,
1548 .readdir = proc_task_readdir,
1549};
1550
1551/* 1362/*
1552 * proc directories can do almost nothing.. 1363 * proc directories can do almost nothing..
1553 */ 1364 */
@@ -1556,87 +1367,11 @@ static struct inode_operations proc_fd_inode_operations = {
1556 .setattr = proc_setattr, 1367 .setattr = proc_setattr,
1557}; 1368};
1558 1369
1559static struct inode_operations proc_task_inode_operations = { 1370static struct file_operations proc_task_operations;
1560 .lookup = proc_task_lookup, 1371static struct inode_operations proc_task_inode_operations;
1561 .getattr = proc_task_getattr,
1562 .setattr = proc_setattr,
1563};
1564 1372
1565#ifdef CONFIG_SECURITY 1373#ifdef CONFIG_SECURITY
1566static ssize_t proc_pid_attr_read(struct file * file, char __user * buf, 1374static struct file_operations proc_pid_attr_operations;
1567 size_t count, loff_t *ppos)
1568{
1569 struct inode * inode = file->f_dentry->d_inode;
1570 unsigned long page;
1571 ssize_t length;
1572 struct task_struct *task = get_proc_task(inode);
1573
1574 length = -ESRCH;
1575 if (!task)
1576 goto out_no_task;
1577
1578 if (count > PAGE_SIZE)
1579 count = PAGE_SIZE;
1580 length = -ENOMEM;
1581 if (!(page = __get_free_page(GFP_KERNEL)))
1582 goto out;
1583
1584 length = security_getprocattr(task,
1585 (char*)file->f_dentry->d_name.name,
1586 (void*)page, count);
1587 if (length >= 0)
1588 length = simple_read_from_buffer(buf, count, ppos, (char *)page, length);
1589 free_page(page);
1590out:
1591 put_task_struct(task);
1592out_no_task:
1593 return length;
1594}
1595
1596static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
1597 size_t count, loff_t *ppos)
1598{
1599 struct inode * inode = file->f_dentry->d_inode;
1600 char *page;
1601 ssize_t length;
1602 struct task_struct *task = get_proc_task(inode);
1603
1604 length = -ESRCH;
1605 if (!task)
1606 goto out_no_task;
1607 if (count > PAGE_SIZE)
1608 count = PAGE_SIZE;
1609
1610 /* No partial writes. */
1611 length = -EINVAL;
1612 if (*ppos != 0)
1613 goto out;
1614
1615 length = -ENOMEM;
1616 page = (char*)__get_free_page(GFP_USER);
1617 if (!page)
1618 goto out;
1619
1620 length = -EFAULT;
1621 if (copy_from_user(page, buf, count))
1622 goto out_free;
1623
1624 length = security_setprocattr(task,
1625 (char*)file->f_dentry->d_name.name,
1626 (void*)page, count);
1627out_free:
1628 free_page((unsigned long) page);
1629out:
1630 put_task_struct(task);
1631out_no_task:
1632 return length;
1633}
1634
1635static struct file_operations proc_pid_attr_operations = {
1636 .read = proc_pid_attr_read,
1637 .write = proc_pid_attr_write,
1638};
1639
1640static struct file_operations proc_tid_attr_operations; 1375static struct file_operations proc_tid_attr_operations;
1641static struct inode_operations proc_tid_attr_inode_operations; 1376static struct inode_operations proc_tid_attr_inode_operations;
1642static struct file_operations proc_tgid_attr_operations; 1377static struct file_operations proc_tgid_attr_operations;
@@ -1852,37 +1587,157 @@ out_no_task:
1852 return error; 1587 return error;
1853} 1588}
1854 1589
1855static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ 1590static int proc_pident_readdir(struct file *filp,
1856 return proc_pident_lookup(dir, dentry, tgid_base_stuff); 1591 void *dirent, filldir_t filldir,
1592 struct pid_entry *ents, unsigned int nents)
1593{
1594 int i;
1595 int pid;
1596 struct dentry *dentry = filp->f_dentry;
1597 struct inode *inode = dentry->d_inode;
1598 struct task_struct *task = get_proc_task(inode);
1599 struct pid_entry *p;
1600 ino_t ino;
1601 int ret;
1602
1603 ret = -ENOENT;
1604 if (!task)
1605 goto out;
1606
1607 ret = 0;
1608 pid = task->pid;
1609 put_task_struct(task);
1610 i = filp->f_pos;
1611 switch (i) {
1612 case 0:
1613 ino = inode->i_ino;
1614 if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
1615 goto out;
1616 i++;
1617 filp->f_pos++;
1618 /* fall through */
1619 case 1:
1620 ino = parent_ino(dentry);
1621 if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
1622 goto out;
1623 i++;
1624 filp->f_pos++;
1625 /* fall through */
1626 default:
1627 i -= 2;
1628 if (i >= nents) {
1629 ret = 1;
1630 goto out;
1631 }
1632 p = ents + i;
1633 while (p->name) {
1634 if (filldir(dirent, p->name, p->len, filp->f_pos,
1635 fake_ino(pid, p->type), p->mode >> 12) < 0)
1636 goto out;
1637 filp->f_pos++;
1638 p++;
1639 }
1640 }
1641
1642 ret = 1;
1643out:
1644 return ret;
1857} 1645}
1858 1646
1859static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ 1647#ifdef CONFIG_SECURITY
1860 return proc_pident_lookup(dir, dentry, tid_base_stuff); 1648static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
1649 size_t count, loff_t *ppos)
1650{
1651 struct inode * inode = file->f_dentry->d_inode;
1652 unsigned long page;
1653 ssize_t length;
1654 struct task_struct *task = get_proc_task(inode);
1655
1656 length = -ESRCH;
1657 if (!task)
1658 goto out_no_task;
1659
1660 if (count > PAGE_SIZE)
1661 count = PAGE_SIZE;
1662 length = -ENOMEM;
1663 if (!(page = __get_free_page(GFP_KERNEL)))
1664 goto out;
1665
1666 length = security_getprocattr(task,
1667 (char*)file->f_dentry->d_name.name,
1668 (void*)page, count);
1669 if (length >= 0)
1670 length = simple_read_from_buffer(buf, count, ppos, (char *)page, length);
1671 free_page(page);
1672out:
1673 put_task_struct(task);
1674out_no_task:
1675 return length;
1861} 1676}
1862 1677
1863static struct file_operations proc_tgid_base_operations = { 1678static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
1864 .read = generic_read_dir, 1679 size_t count, loff_t *ppos)
1865 .readdir = proc_tgid_base_readdir, 1680{
1866}; 1681 struct inode * inode = file->f_dentry->d_inode;
1682 char *page;
1683 ssize_t length;
1684 struct task_struct *task = get_proc_task(inode);
1867 1685
1868static struct file_operations proc_tid_base_operations = { 1686 length = -ESRCH;
1869 .read = generic_read_dir, 1687 if (!task)
1870 .readdir = proc_tid_base_readdir, 1688 goto out_no_task;
1871}; 1689 if (count > PAGE_SIZE)
1690 count = PAGE_SIZE;
1872 1691
1873static struct inode_operations proc_tgid_base_inode_operations = { 1692 /* No partial writes. */
1874 .lookup = proc_tgid_base_lookup, 1693 length = -EINVAL;
1875 .getattr = pid_getattr, 1694 if (*ppos != 0)
1876 .setattr = proc_setattr, 1695 goto out;
1696
1697 length = -ENOMEM;
1698 page = (char*)__get_free_page(GFP_USER);
1699 if (!page)
1700 goto out;
1701
1702 length = -EFAULT;
1703 if (copy_from_user(page, buf, count))
1704 goto out_free;
1705
1706 length = security_setprocattr(task,
1707 (char*)file->f_dentry->d_name.name,
1708 (void*)page, count);
1709out_free:
1710 free_page((unsigned long) page);
1711out:
1712 put_task_struct(task);
1713out_no_task:
1714 return length;
1715}
1716
1717static struct file_operations proc_pid_attr_operations = {
1718 .read = proc_pid_attr_read,
1719 .write = proc_pid_attr_write,
1877}; 1720};
1878 1721
1879static struct inode_operations proc_tid_base_inode_operations = { 1722static struct pid_entry tgid_attr_stuff[] = {
1880 .lookup = proc_tid_base_lookup, 1723 E(PROC_TGID_ATTR_CURRENT, "current", S_IFREG|S_IRUGO|S_IWUGO),
1881 .getattr = pid_getattr, 1724 E(PROC_TGID_ATTR_PREV, "prev", S_IFREG|S_IRUGO),
1882 .setattr = proc_setattr, 1725 E(PROC_TGID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
1726 E(PROC_TGID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
1727 E(PROC_TGID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO),
1728 E(PROC_TGID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO),
1729 {0,0,NULL,0}
1730};
1731static struct pid_entry tid_attr_stuff[] = {
1732 E(PROC_TID_ATTR_CURRENT, "current", S_IFREG|S_IRUGO|S_IWUGO),
1733 E(PROC_TID_ATTR_PREV, "prev", S_IFREG|S_IRUGO),
1734 E(PROC_TID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
1735 E(PROC_TID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
1736 E(PROC_TID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO),
1737 E(PROC_TID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO),
1738 {0,0,NULL,0}
1883}; 1739};
1884 1740
1885#ifdef CONFIG_SECURITY
1886static int proc_tgid_attr_readdir(struct file * filp, 1741static int proc_tgid_attr_readdir(struct file * filp,
1887 void * dirent, filldir_t filldir) 1742 void * dirent, filldir_t filldir)
1888{ 1743{
@@ -1948,13 +1803,83 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
1948 char tmp[PROC_NUMBUF]; 1803 char tmp[PROC_NUMBUF];
1949 sprintf(tmp, "%d", current->tgid); 1804 sprintf(tmp, "%d", current->tgid);
1950 return ERR_PTR(vfs_follow_link(nd,tmp)); 1805 return ERR_PTR(vfs_follow_link(nd,tmp));
1951} 1806}
1952 1807
1953static struct inode_operations proc_self_inode_operations = { 1808static struct inode_operations proc_self_inode_operations = {
1954 .readlink = proc_self_readlink, 1809 .readlink = proc_self_readlink,
1955 .follow_link = proc_self_follow_link, 1810 .follow_link = proc_self_follow_link,
1956}; 1811};
1957 1812
1813/*
1814 * Thread groups
1815 */
1816static struct pid_entry tgid_base_stuff[] = {
1817 E(PROC_TGID_TASK, "task", S_IFDIR|S_IRUGO|S_IXUGO),
1818 E(PROC_TGID_FD, "fd", S_IFDIR|S_IRUSR|S_IXUSR),
1819 E(PROC_TGID_ENVIRON, "environ", S_IFREG|S_IRUSR),
1820 E(PROC_TGID_AUXV, "auxv", S_IFREG|S_IRUSR),
1821 E(PROC_TGID_STATUS, "status", S_IFREG|S_IRUGO),
1822 E(PROC_TGID_CMDLINE, "cmdline", S_IFREG|S_IRUGO),
1823 E(PROC_TGID_STAT, "stat", S_IFREG|S_IRUGO),
1824 E(PROC_TGID_STATM, "statm", S_IFREG|S_IRUGO),
1825 E(PROC_TGID_MAPS, "maps", S_IFREG|S_IRUGO),
1826#ifdef CONFIG_NUMA
1827 E(PROC_TGID_NUMA_MAPS, "numa_maps", S_IFREG|S_IRUGO),
1828#endif
1829 E(PROC_TGID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR),
1830#ifdef CONFIG_SECCOMP
1831 E(PROC_TGID_SECCOMP, "seccomp", S_IFREG|S_IRUSR|S_IWUSR),
1832#endif
1833 E(PROC_TGID_CWD, "cwd", S_IFLNK|S_IRWXUGO),
1834 E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO),
1835 E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO),
1836 E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
1837 E(PROC_TGID_MOUNTSTATS, "mountstats", S_IFREG|S_IRUSR),
1838#ifdef CONFIG_MMU
1839 E(PROC_TGID_SMAPS, "smaps", S_IFREG|S_IRUGO),
1840#endif
1841#ifdef CONFIG_SECURITY
1842 E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
1843#endif
1844#ifdef CONFIG_KALLSYMS
1845 E(PROC_TGID_WCHAN, "wchan", S_IFREG|S_IRUGO),
1846#endif
1847#ifdef CONFIG_SCHEDSTATS
1848 E(PROC_TGID_SCHEDSTAT, "schedstat", S_IFREG|S_IRUGO),
1849#endif
1850#ifdef CONFIG_CPUSETS
1851 E(PROC_TGID_CPUSET, "cpuset", S_IFREG|S_IRUGO),
1852#endif
1853 E(PROC_TGID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO),
1854 E(PROC_TGID_OOM_ADJUST,"oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
1855#ifdef CONFIG_AUDITSYSCALL
1856 E(PROC_TGID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
1857#endif
1858 {0,0,NULL,0}
1859};
1860
1861static int proc_tgid_base_readdir(struct file * filp,
1862 void * dirent, filldir_t filldir)
1863{
1864 return proc_pident_readdir(filp,dirent,filldir,
1865 tgid_base_stuff,ARRAY_SIZE(tgid_base_stuff));
1866}
1867
1868static struct file_operations proc_tgid_base_operations = {
1869 .read = generic_read_dir,
1870 .readdir = proc_tgid_base_readdir,
1871};
1872
1873static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
1874 return proc_pident_lookup(dir, dentry, tgid_base_stuff);
1875}
1876
1877static struct inode_operations proc_tgid_base_inode_operations = {
1878 .lookup = proc_tgid_base_lookup,
1879 .getattr = pid_getattr,
1880 .setattr = proc_setattr,
1881};
1882
1958/** 1883/**
1959 * proc_flush_task - Remove dcache entries for @task from the /proc dcache. 1884 * proc_flush_task - Remove dcache entries for @task from the /proc dcache.
1960 * 1885 *
@@ -2085,62 +2010,6 @@ out:
2085 return result; 2010 return result;
2086} 2011}
2087 2012
2088/* SMP-safe */
2089static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
2090{
2091 struct dentry *result = ERR_PTR(-ENOENT);
2092 struct task_struct *task;
2093 struct task_struct *leader = get_proc_task(dir);
2094 struct inode *inode;
2095 unsigned tid;
2096
2097 if (!leader)
2098 goto out_no_task;
2099
2100 tid = name_to_int(dentry);
2101 if (tid == ~0U)
2102 goto out;
2103
2104 rcu_read_lock();
2105 task = find_task_by_pid(tid);
2106 if (task)
2107 get_task_struct(task);
2108 rcu_read_unlock();
2109 if (!task)
2110 goto out;
2111 if (leader->tgid != task->tgid)
2112 goto out_drop_task;
2113
2114 inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO);
2115
2116
2117 if (!inode)
2118 goto out_drop_task;
2119 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
2120 inode->i_op = &proc_tid_base_inode_operations;
2121 inode->i_fop = &proc_tid_base_operations;
2122 inode->i_flags|=S_IMMUTABLE;
2123#ifdef CONFIG_SECURITY
2124 inode->i_nlink = 4;
2125#else
2126 inode->i_nlink = 3;
2127#endif
2128
2129 dentry->d_op = &pid_dentry_operations;
2130
2131 d_add(dentry, inode);
2132 /* Close the race of the process dying before we return the dentry */
2133 if (pid_revalidate(dentry, NULL))
2134 result = NULL;
2135
2136out_drop_task:
2137 put_task_struct(task);
2138out:
2139 put_task_struct(leader);
2140out_no_task:
2141 return result;
2142}
2143
2144/* 2013/*
2145 * Find the first task with tgid >= tgid 2014 * Find the first task with tgid >= tgid
2146 * 2015 *
@@ -2216,6 +2085,130 @@ out:
2216} 2085}
2217 2086
2218/* 2087/*
2088 * Tasks
2089 */
2090static struct pid_entry tid_base_stuff[] = {
2091 E(PROC_TID_FD, "fd", S_IFDIR|S_IRUSR|S_IXUSR),
2092 E(PROC_TID_ENVIRON, "environ", S_IFREG|S_IRUSR),
2093 E(PROC_TID_AUXV, "auxv", S_IFREG|S_IRUSR),
2094 E(PROC_TID_STATUS, "status", S_IFREG|S_IRUGO),
2095 E(PROC_TID_CMDLINE, "cmdline", S_IFREG|S_IRUGO),
2096 E(PROC_TID_STAT, "stat", S_IFREG|S_IRUGO),
2097 E(PROC_TID_STATM, "statm", S_IFREG|S_IRUGO),
2098 E(PROC_TID_MAPS, "maps", S_IFREG|S_IRUGO),
2099#ifdef CONFIG_NUMA
2100 E(PROC_TID_NUMA_MAPS, "numa_maps", S_IFREG|S_IRUGO),
2101#endif
2102 E(PROC_TID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR),
2103#ifdef CONFIG_SECCOMP
2104 E(PROC_TID_SECCOMP, "seccomp", S_IFREG|S_IRUSR|S_IWUSR),
2105#endif
2106 E(PROC_TID_CWD, "cwd", S_IFLNK|S_IRWXUGO),
2107 E(PROC_TID_ROOT, "root", S_IFLNK|S_IRWXUGO),
2108 E(PROC_TID_EXE, "exe", S_IFLNK|S_IRWXUGO),
2109 E(PROC_TID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
2110#ifdef CONFIG_MMU
2111 E(PROC_TID_SMAPS, "smaps", S_IFREG|S_IRUGO),
2112#endif
2113#ifdef CONFIG_SECURITY
2114 E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
2115#endif
2116#ifdef CONFIG_KALLSYMS
2117 E(PROC_TID_WCHAN, "wchan", S_IFREG|S_IRUGO),
2118#endif
2119#ifdef CONFIG_SCHEDSTATS
2120 E(PROC_TID_SCHEDSTAT, "schedstat",S_IFREG|S_IRUGO),
2121#endif
2122#ifdef CONFIG_CPUSETS
2123 E(PROC_TID_CPUSET, "cpuset", S_IFREG|S_IRUGO),
2124#endif
2125 E(PROC_TID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO),
2126 E(PROC_TID_OOM_ADJUST, "oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
2127#ifdef CONFIG_AUDITSYSCALL
2128 E(PROC_TID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
2129#endif
2130 {0,0,NULL,0}
2131};
2132
2133static int proc_tid_base_readdir(struct file * filp,
2134 void * dirent, filldir_t filldir)
2135{
2136 return proc_pident_readdir(filp,dirent,filldir,
2137 tid_base_stuff,ARRAY_SIZE(tid_base_stuff));
2138}
2139
2140static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
2141 return proc_pident_lookup(dir, dentry, tid_base_stuff);
2142}
2143
2144static struct file_operations proc_tid_base_operations = {
2145 .read = generic_read_dir,
2146 .readdir = proc_tid_base_readdir,
2147};
2148
2149static struct inode_operations proc_tid_base_inode_operations = {
2150 .lookup = proc_tid_base_lookup,
2151 .getattr = pid_getattr,
2152 .setattr = proc_setattr,
2153};
2154
2155/* SMP-safe */
2156static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
2157{
2158 struct dentry *result = ERR_PTR(-ENOENT);
2159 struct task_struct *task;
2160 struct task_struct *leader = get_proc_task(dir);
2161 struct inode *inode;
2162 unsigned tid;
2163
2164 if (!leader)
2165 goto out_no_task;
2166
2167 tid = name_to_int(dentry);
2168 if (tid == ~0U)
2169 goto out;
2170
2171 rcu_read_lock();
2172 task = find_task_by_pid(tid);
2173 if (task)
2174 get_task_struct(task);
2175 rcu_read_unlock();
2176 if (!task)
2177 goto out;
2178 if (leader->tgid != task->tgid)
2179 goto out_drop_task;
2180
2181 inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO);
2182
2183
2184 if (!inode)
2185 goto out_drop_task;
2186 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
2187 inode->i_op = &proc_tid_base_inode_operations;
2188 inode->i_fop = &proc_tid_base_operations;
2189 inode->i_flags|=S_IMMUTABLE;
2190#ifdef CONFIG_SECURITY
2191 inode->i_nlink = 4;
2192#else
2193 inode->i_nlink = 3;
2194#endif
2195
2196 dentry->d_op = &pid_dentry_operations;
2197
2198 d_add(dentry, inode);
2199 /* Close the race of the process dying before we return the dentry */
2200 if (pid_revalidate(dentry, NULL))
2201 result = NULL;
2202
2203out_drop_task:
2204 put_task_struct(task);
2205out:
2206 put_task_struct(leader);
2207out_no_task:
2208 return result;
2209}
2210
2211/*
2219 * Find the first tid of a thread group to return to user space. 2212 * Find the first tid of a thread group to return to user space.
2220 * 2213 *
2221 * Usually this is just the thread group leader, but if the users 2214 * Usually this is just the thread group leader, but if the users
@@ -2358,3 +2351,14 @@ static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, struct
2358 2351
2359 return 0; 2352 return 0;
2360} 2353}
2354
2355static struct inode_operations proc_task_inode_operations = {
2356 .lookup = proc_task_lookup,
2357 .getattr = proc_task_getattr,
2358 .setattr = proc_setattr,
2359};
2360
2361static struct file_operations proc_task_operations = {
2362 .read = generic_read_dir,
2363 .readdir = proc_task_readdir,
2364};