Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 37851
b: refs/heads/master
c: 444ceed
h: refs/heads/master
i:
  37849: 3f4bfcc
  37847: fee948e
v: v3
  • Loading branch information
Eric W. Biederman authored and Linus Torvalds committed Oct 2, 2006
1 parent 16c6ce6 commit 24125a2
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 112 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: 801199ce805a2412bbcd9bfe213092ec656013dd
refs/heads/master: 444ceed8d186631fdded5e3f24dc20b93d0d3fda
269 changes: 158 additions & 111 deletions trunk/fs/proc/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1254,21 +1254,15 @@ static struct dentry_operations tid_fd_dentry_operations =
.d_delete = pid_delete_dentry,
};

/* SMP-safe */
static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
static struct dentry *proc_fd_instantiate(struct inode *dir,
struct dentry *dentry, struct task_struct *task, void *ptr)
{
struct task_struct *task = get_proc_task(dir);
unsigned fd = name_to_int(dentry);
struct dentry *result = ERR_PTR(-ENOENT);
struct file * file;
struct files_struct * files;
struct inode *inode;
struct proc_inode *ei;

if (!task)
goto out_no_task;
if (fd == ~0U)
goto out;
unsigned fd = *(unsigned *)ptr;
struct file *file;
struct files_struct *files;
struct inode *inode;
struct proc_inode *ei;
struct dentry *error = ERR_PTR(-ENOENT);

inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_FD_DIR+fd);
if (!inode)
Expand All @@ -1277,7 +1271,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
ei->fd = fd;
files = get_files_struct(task);
if (!files)
goto out_unlock;
goto out_iput;
inode->i_mode = S_IFLNK;

/*
Expand All @@ -1287,34 +1281,52 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
spin_lock(&files->file_lock);
file = fcheck_files(files, fd);
if (!file)
goto out_unlock2;
goto out_unlock;
if (file->f_mode & 1)
inode->i_mode |= S_IRUSR | S_IXUSR;
if (file->f_mode & 2)
inode->i_mode |= S_IWUSR | S_IXUSR;
spin_unlock(&files->file_lock);
put_files_struct(files);

inode->i_op = &proc_pid_link_inode_operations;
inode->i_size = 64;
ei->op.proc_get_link = proc_fd_link;
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))
result = NULL;
out:
put_task_struct(task);
out_no_task:
return result;
error = NULL;

out_unlock2:
out:
return error;
out_unlock:
spin_unlock(&files->file_lock);
put_files_struct(files);
out_unlock:
out_iput:
iput(inode);
goto out;
}

/* SMP-safe */
static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
{
struct task_struct *task = get_proc_task(dir);
unsigned fd = name_to_int(dentry);
struct dentry *result = ERR_PTR(-ENOENT);

if (!task)
goto out_no_task;
if (fd == ~0U)
goto out;

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

static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
{
struct dentry *dentry = filp->f_dentry;
Expand Down Expand Up @@ -1395,6 +1407,36 @@ static struct inode_operations proc_fd_inode_operations = {
.setattr = proc_setattr,
};

static struct dentry *proc_pident_instantiate(struct inode *dir,
struct dentry *dentry, struct task_struct *task, void *ptr)
{
struct pid_entry *p = ptr;
struct inode *inode;
struct proc_inode *ei;
struct dentry *error = ERR_PTR(-EINVAL);

inode = proc_pid_make_inode(dir->i_sb, task, p->type);
if (!inode)
goto out;

ei = PROC_I(inode);
inode->i_mode = p->mode;
if (S_ISDIR(inode->i_mode))
inode->i_nlink = 2; /* Use getattr to fix if necessary */
if (p->iop)
inode->i_op = p->iop;
if (p->fop)
inode->i_fop = p->fop;
ei->op = p->op;
dentry->d_op = &pid_dentry_operations;
d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */
if (pid_revalidate(dentry, NULL))
error = NULL;
out:
return error;
}

/* SMP-safe */
static struct dentry *proc_pident_lookup(struct inode *dir,
struct dentry *dentry,
Expand All @@ -1404,7 +1446,6 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
struct dentry *error;
struct task_struct *task = get_proc_task(dir);
struct pid_entry *p;
struct proc_inode *ei;

error = ERR_PTR(-ENOENT);
inode = NULL;
Expand All @@ -1425,25 +1466,7 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
if (!p->name)
goto out;

error = ERR_PTR(-EINVAL);
inode = proc_pid_make_inode(dir->i_sb, task, p->type);
if (!inode)
goto out;

ei = PROC_I(inode);
inode->i_mode = p->mode;
if (S_ISDIR(inode->i_mode))
inode->i_nlink = 2; /* Use getattr to fix if necessary */
if (p->iop)
inode->i_op = p->iop;
if (p->fop)
inode->i_fop = p->fop;
ei->op = p->op;
dentry->d_op = &pid_dentry_operations;
d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */
if (pid_revalidate(dentry, NULL))
error = NULL;
error = proc_pident_instantiate(dir, dentry, task, p);
out:
put_task_struct(task);
out_no_task:
Expand Down Expand Up @@ -1709,29 +1732,13 @@ static struct dentry_operations proc_base_dentry_operations =
.d_delete = pid_delete_dentry,
};

static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
static struct dentry *proc_base_instantiate(struct inode *dir,
struct dentry *dentry, struct task_struct *task, void *ptr)
{
struct pid_entry *p = ptr;
struct inode *inode;
struct dentry *error;
struct task_struct *task = get_proc_task(dir);
struct pid_entry *p;
struct proc_inode *ei;

error = ERR_PTR(-ENOENT);
inode = NULL;

if (!task)
goto out_no_task;

/* Lookup the directory entry */
for (p = proc_base_stuff; p->name; p++) {
if (p->len != dentry->d_name.len)
continue;
if (!memcmp(dentry->d_name.name, p->name, p->len))
break;
}
if (!p->name)
goto out;
struct dentry *error = ERR_PTR(-EINVAL);

/* Allocate the inode */
error = ERR_PTR(-ENOMEM);
Expand Down Expand Up @@ -1767,14 +1774,41 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
d_add(dentry, inode);
error = NULL;
out:
put_task_struct(task);
out_no_task:
return error;
out_iput:
iput(inode);
goto out;
}

static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
{
struct dentry *error;
struct task_struct *task = get_proc_task(dir);
struct pid_entry *p;

error = ERR_PTR(-ENOENT);

if (!task)
goto out_no_task;

/* Lookup the directory entry */
for (p = proc_base_stuff; p->name; p++) {
if (p->len != dentry->d_name.len)
continue;
if (!memcmp(dentry->d_name.name, p->name, p->len))
break;
}
if (!p->name)
goto out;

error = proc_base_instantiate(dir, dentry, task, p);

out:
put_task_struct(task);
out_no_task:
return error;
}

/*
* Thread groups
*/
Expand Down Expand Up @@ -1915,12 +1949,40 @@ void proc_flush_task(struct task_struct *task)
return;
}

struct dentry *proc_pid_instantiate(struct inode *dir,
struct dentry * dentry, struct task_struct *task, void *ptr)
{
struct dentry *error = ERR_PTR(-ENOENT);
struct inode *inode;

inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
if (!inode)
goto out;

inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
inode->i_op = &proc_tgid_base_inode_operations;
inode->i_fop = &proc_tgid_base_operations;
inode->i_flags|=S_IMMUTABLE;
inode->i_nlink = 4;
#ifdef CONFIG_SECURITY
inode->i_nlink += 1;
#endif

dentry->d_op = &pid_dentry_operations;

d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */
if (pid_revalidate(dentry, NULL))
error = NULL;
out:
return error;
}

/* SMP-safe */
struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
{
struct dentry *result = ERR_PTR(-ENOENT);
struct task_struct *task;
struct inode *inode;
unsigned tgid;

result = proc_base_lookup(dir, dentry);
Expand All @@ -1939,28 +2001,7 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
if (!task)
goto out;

inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
if (!inode)
goto out_put_task;

inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
inode->i_op = &proc_tgid_base_inode_operations;
inode->i_fop = &proc_tgid_base_operations;
inode->i_flags|=S_IMMUTABLE;
#ifdef CONFIG_SECURITY
inode->i_nlink = 5;
#else
inode->i_nlink = 4;
#endif

dentry->d_op = &pid_dentry_operations;

d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */
if (pid_revalidate(dentry, NULL))
result = NULL;

out_put_task:
result = proc_pid_instantiate(dir, dentry, task, NULL);
put_task_struct(task);
out:
return result;
Expand Down Expand Up @@ -2107,13 +2148,40 @@ static struct inode_operations proc_tid_base_inode_operations = {
.setattr = proc_setattr,
};

static struct dentry *proc_task_instantiate(struct inode *dir,
struct dentry *dentry, struct task_struct *task, void *ptr)
{
struct dentry *error = ERR_PTR(-ENOENT);
struct inode *inode;
inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO);

if (!inode)
goto out;
inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
inode->i_op = &proc_tid_base_inode_operations;
inode->i_fop = &proc_tid_base_operations;
inode->i_flags|=S_IMMUTABLE;
inode->i_nlink = 3;
#ifdef CONFIG_SECURITY
inode->i_nlink += 1;
#endif

dentry->d_op = &pid_dentry_operations;

d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */
if (pid_revalidate(dentry, NULL))
error = NULL;
out:
return error;
}

/* SMP-safe */
static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
{
struct dentry *result = ERR_PTR(-ENOENT);
struct task_struct *task;
struct task_struct *leader = get_proc_task(dir);
struct inode *inode;
unsigned tid;

if (!leader)
Expand All @@ -2133,28 +2201,7 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry
if (leader->tgid != task->tgid)
goto out_drop_task;

inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO);


if (!inode)
goto out_drop_task;
inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
inode->i_op = &proc_tid_base_inode_operations;
inode->i_fop = &proc_tid_base_operations;
inode->i_flags|=S_IMMUTABLE;
#ifdef CONFIG_SECURITY
inode->i_nlink = 4;
#else
inode->i_nlink = 3;
#endif

dentry->d_op = &pid_dentry_operations;

d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */
if (pid_revalidate(dentry, NULL))
result = NULL;

result = proc_task_instantiate(dir, dentry, task, NULL);
out_drop_task:
put_task_struct(task);
out:
Expand Down

0 comments on commit 24125a2

Please sign in to comment.