Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 54593
b: refs/heads/master
c: 2793274
h: refs/heads/master
i:
  54591: 6aa9cac
v: v3
  • Loading branch information
Miklos Szeredi authored and Linus Torvalds committed May 8, 2007
1 parent 3cde073 commit 5bb5a2a
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c5141e6d64ab5c48a5e31413c7a6cdda84ac1d52
refs/heads/master: 2793274298c4423d79701e9a8190f2940bf3c785
132 changes: 114 additions & 18 deletions trunk/fs/proc/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1238,7 +1238,10 @@ static unsigned name_to_int(struct dentry *dentry)
return ~0U;
}

static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
#define PROC_FDINFO_MAX 64

static int proc_fd_info(struct inode *inode, struct dentry **dentry,
struct vfsmount **mnt, char *info)
{
struct task_struct *task = get_proc_task(inode);
struct files_struct *files = NULL;
Expand All @@ -1257,8 +1260,16 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm
spin_lock(&files->file_lock);
file = fcheck_files(files, fd);
if (file) {
*mnt = mntget(file->f_path.mnt);
*dentry = dget(file->f_path.dentry);
if (mnt)
*mnt = mntget(file->f_path.mnt);
if (dentry)
*dentry = dget(file->f_path.dentry);
if (info)
snprintf(info, PROC_FDINFO_MAX,
"pos:\t%lli\n"
"flags:\t0%o\n",
(long long) file->f_pos,
file->f_flags);
spin_unlock(&files->file_lock);
put_files_struct(files);
return 0;
Expand All @@ -1269,6 +1280,12 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm
return -ENOENT;
}

static int proc_fd_link(struct inode *inode, struct dentry **dentry,
struct vfsmount **mnt)
{
return proc_fd_info(inode, dentry, mnt, NULL);
}

static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
{
struct inode *inode = dentry->d_inode;
Expand Down Expand Up @@ -1364,7 +1381,9 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
goto out;
}

static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
static struct dentry *proc_lookupfd_common(struct inode *dir,
struct dentry *dentry,
instantiate_t instantiate)
{
struct task_struct *task = get_proc_task(dir);
unsigned fd = name_to_int(dentry);
Expand All @@ -1375,23 +1394,15 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
if (fd == ~0U)
goto out;

result = proc_fd_instantiate(dir, dentry, task, &fd);
result = instantiate(dir, dentry, task, &fd);
out:
put_task_struct(task);
out_no_task:
return result;
}

static int proc_fd_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
struct task_struct *task, int fd)
{
char name[PROC_NUMBUF];
int len = snprintf(name, sizeof(name), "%d", fd);
return proc_fill_cache(filp, dirent, filldir, name, len,
proc_fd_instantiate, task, &fd);
}

static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
static int proc_readfd_common(struct file * filp, void * dirent,
filldir_t filldir, instantiate_t instantiate)
{
struct dentry *dentry = filp->f_path.dentry;
struct inode *inode = dentry->d_inode;
Expand Down Expand Up @@ -1427,12 +1438,17 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
for (fd = filp->f_pos-2;
fd < fdt->max_fds;
fd++, filp->f_pos++) {
char name[PROC_NUMBUF];
int len;

if (!fcheck_files(files, fd))
continue;
rcu_read_unlock();

if (proc_fd_fill_cache(filp, dirent, filldir, p, fd) < 0) {
len = snprintf(name, sizeof(name), "%d", fd);
if (proc_fill_cache(filp, dirent, filldir,
name, len, instantiate,
p, &fd) < 0) {
rcu_read_lock();
break;
}
Expand All @@ -1447,6 +1463,32 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
return retval;
}

static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
struct nameidata *nd)
{
return proc_lookupfd_common(dir, dentry, proc_fd_instantiate);
}

static int proc_readfd(struct file *filp, void *dirent, filldir_t filldir)
{
return proc_readfd_common(filp, dirent, filldir, proc_fd_instantiate);
}

static ssize_t proc_fdinfo_read(struct file *file, char __user *buf,
size_t len, loff_t *ppos)
{
char tmp[PROC_FDINFO_MAX];
int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, NULL, tmp);
if (!err)
err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp));
return err;
}

static const struct file_operations proc_fdinfo_file_operations = {
.open = nonseekable_open,
.read = proc_fdinfo_read,
};

static const struct file_operations proc_fd_operations = {
.read = generic_read_dir,
.readdir = proc_readfd,
Expand Down Expand Up @@ -1478,6 +1520,58 @@ static const struct inode_operations proc_fd_inode_operations = {
.setattr = proc_setattr,
};

static struct dentry *proc_fdinfo_instantiate(struct inode *dir,
struct dentry *dentry, struct task_struct *task, const void *ptr)
{
unsigned fd = *(unsigned *)ptr;
struct inode *inode;
struct proc_inode *ei;
struct dentry *error = ERR_PTR(-ENOENT);

inode = proc_pid_make_inode(dir->i_sb, task);
if (!inode)
goto out;
ei = PROC_I(inode);
ei->fd = fd;
inode->i_mode = S_IFREG | S_IRUSR;
inode->i_fop = &proc_fdinfo_file_operations;
dentry->d_op = &tid_fd_dentry_operations;
d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */
if (tid_fd_revalidate(dentry, NULL))
error = NULL;

out:
return error;
}

static struct dentry *proc_lookupfdinfo(struct inode *dir,
struct dentry *dentry,
struct nameidata *nd)
{
return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
}

static int proc_readfdinfo(struct file *filp, void *dirent, filldir_t filldir)
{
return proc_readfd_common(filp, dirent, filldir,
proc_fdinfo_instantiate);
}

static const struct file_operations proc_fdinfo_operations = {
.read = generic_read_dir,
.readdir = proc_readfdinfo,
};

/*
* proc directories can do almost nothing..
*/
static const struct inode_operations proc_fdinfo_inode_operations = {
.lookup = proc_lookupfdinfo,
.setattr = proc_setattr,
};


static struct dentry *proc_pident_instantiate(struct inode *dir,
struct dentry *dentry, struct task_struct *task, const void *ptr)
{
Expand Down Expand Up @@ -1888,6 +1982,7 @@ static const struct inode_operations proc_task_inode_operations;
static const struct pid_entry tgid_base_stuff[] = {
DIR("task", S_IRUGO|S_IXUGO, task),
DIR("fd", S_IRUSR|S_IXUSR, fd),
DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo),
INF("environ", S_IRUSR, pid_environ),
INF("auxv", S_IRUSR, pid_auxv),
INF("status", S_IRUGO, pid_status),
Expand Down Expand Up @@ -2041,7 +2136,7 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
inode->i_op = &proc_tgid_base_inode_operations;
inode->i_fop = &proc_tgid_base_operations;
inode->i_flags|=S_IMMUTABLE;
inode->i_nlink = 4;
inode->i_nlink = 5;
#ifdef CONFIG_SECURITY
inode->i_nlink += 1;
#endif
Expand Down Expand Up @@ -2171,6 +2266,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
*/
static const struct pid_entry tid_base_stuff[] = {
DIR("fd", S_IRUSR|S_IXUSR, fd),
DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo),
INF("environ", S_IRUSR, pid_environ),
INF("auxv", S_IRUSR, pid_auxv),
INF("status", S_IRUGO, pid_status),
Expand Down Expand Up @@ -2251,7 +2347,7 @@ static struct dentry *proc_task_instantiate(struct inode *dir,
inode->i_op = &proc_tid_base_inode_operations;
inode->i_fop = &proc_tid_base_operations;
inode->i_flags|=S_IMMUTABLE;
inode->i_nlink = 3;
inode->i_nlink = 4;
#ifdef CONFIG_SECURITY
inode->i_nlink += 1;
#endif
Expand Down

0 comments on commit 5bb5a2a

Please sign in to comment.