aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/proc/base.c133
1 files changed, 111 insertions, 22 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 6d00ccc48c1c..7832efbd43a6 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1674,6 +1674,108 @@ static struct inode_operations proc_self_inode_operations = {
1674}; 1674};
1675 1675
1676/* 1676/*
1677 * proc base
1678 *
1679 * These are the directory entries in the root directory of /proc
1680 * that properly belong to the /proc filesystem, as they describe
1681 * describe something that is process related.
1682 */
1683static struct pid_entry proc_base_stuff[] = {
1684 NOD(PROC_TGID_INO, "self", S_IFLNK|S_IRWXUGO,
1685 &proc_self_inode_operations, NULL, {}),
1686 {}
1687};
1688
1689/*
1690 * Exceptional case: normally we are not allowed to unhash a busy
1691 * directory. In this case, however, we can do it - no aliasing problems
1692 * due to the way we treat inodes.
1693 */
1694static int proc_base_revalidate(struct dentry *dentry, struct nameidata *nd)
1695{
1696 struct inode *inode = dentry->d_inode;
1697 struct task_struct *task = get_proc_task(inode);
1698 if (task) {
1699 put_task_struct(task);
1700 return 1;
1701 }
1702 d_drop(dentry);
1703 return 0;
1704}
1705
1706static struct dentry_operations proc_base_dentry_operations =
1707{
1708 .d_revalidate = proc_base_revalidate,
1709 .d_delete = pid_delete_dentry,
1710};
1711
1712static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
1713{
1714 struct inode *inode;
1715 struct dentry *error;
1716 struct task_struct *task = get_proc_task(dir);
1717 struct pid_entry *p;
1718 struct proc_inode *ei;
1719
1720 error = ERR_PTR(-ENOENT);
1721 inode = NULL;
1722
1723 if (!task)
1724 goto out_no_task;
1725
1726 /* Lookup the directory entry */
1727 for (p = proc_base_stuff; p->name; p++) {
1728 if (p->len != dentry->d_name.len)
1729 continue;
1730 if (!memcmp(dentry->d_name.name, p->name, p->len))
1731 break;
1732 }
1733 if (!p->name)
1734 goto out;
1735
1736 /* Allocate the inode */
1737 error = ERR_PTR(-ENOMEM);
1738 inode = new_inode(dir->i_sb);
1739 if (!inode)
1740 goto out;
1741
1742 /* Initialize the inode */
1743 ei = PROC_I(inode);
1744 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
1745 inode->i_ino = fake_ino(0, p->type);
1746
1747 /*
1748 * grab the reference to the task.
1749 */
1750 ei->pid = get_pid(task_pid(task));
1751 if (!ei->pid)
1752 goto out_iput;
1753
1754 inode->i_uid = 0;
1755 inode->i_gid = 0;
1756 inode->i_mode = p->mode;
1757 if (S_ISDIR(inode->i_mode))
1758 inode->i_nlink = 2;
1759 if (S_ISLNK(inode->i_mode))
1760 inode->i_size = 64;
1761 if (p->iop)
1762 inode->i_op = p->iop;
1763 if (p->fop)
1764 inode->i_fop = p->fop;
1765 ei->op = p->op;
1766 dentry->d_op = &proc_base_dentry_operations;
1767 d_add(dentry, inode);
1768 error = NULL;
1769out:
1770 put_task_struct(task);
1771out_no_task:
1772 return error;
1773out_iput:
1774 iput(inode);
1775 goto out;
1776}
1777
1778/*
1677 * Thread groups 1779 * Thread groups
1678 */ 1780 */
1679static struct file_operations proc_task_operations; 1781static struct file_operations proc_task_operations;
@@ -1819,24 +1921,12 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
1819 struct dentry *result = ERR_PTR(-ENOENT); 1921 struct dentry *result = ERR_PTR(-ENOENT);
1820 struct task_struct *task; 1922 struct task_struct *task;
1821 struct inode *inode; 1923 struct inode *inode;
1822 struct proc_inode *ei;
1823 unsigned tgid; 1924 unsigned tgid;
1824 1925
1825 if (dentry->d_name.len == 4 && !memcmp(dentry->d_name.name,"self",4)) { 1926 result = proc_base_lookup(dir, dentry);
1826 inode = new_inode(dir->i_sb); 1927 if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT)
1827 if (!inode) 1928 goto out;
1828 return ERR_PTR(-ENOMEM); 1929
1829 ei = PROC_I(inode);
1830 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
1831 inode->i_ino = fake_ino(0, PROC_TGID_INO);
1832 ei->pde = NULL;
1833 inode->i_mode = S_IFLNK|S_IRWXUGO;
1834 inode->i_uid = inode->i_gid = 0;
1835 inode->i_size = 64;
1836 inode->i_op = &proc_self_inode_operations;
1837 d_add(dentry, inode);
1838 return NULL;
1839 }
1840 tgid = name_to_int(dentry); 1930 tgid = name_to_int(dentry);
1841 if (tgid == ~0U) 1931 if (tgid == ~0U)
1842 goto out; 1932 goto out;
@@ -1922,12 +2012,11 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
1922 struct task_struct *task; 2012 struct task_struct *task;
1923 int tgid; 2013 int tgid;
1924 2014
1925 if (!nr) { 2015 for (; nr < (ARRAY_SIZE(proc_base_stuff) - 1); filp->f_pos++, nr++) {
1926 ino_t ino = fake_ino(0,PROC_TGID_INO); 2016 struct pid_entry *p = &proc_base_stuff[nr];
1927 if (filldir(dirent, "self", 4, filp->f_pos, ino, DT_LNK) < 0) 2017 if (filldir(dirent, p->name, p->len, filp->f_pos,
1928 return 0; 2018 fake_ino(0, p->type), p->mode >> 12) < 0)
1929 filp->f_pos++; 2019 goto out;
1930 nr++;
1931 } 2020 }
1932 2021
1933 tgid = filp->f_pos - TGID_OFFSET; 2022 tgid = filp->f_pos - TGID_OFFSET;