Commit 0be49a5c authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] (5/5) sane procfs/dcache interaction

 - sane retention policy for /proc/<pid>/fd/* - ->d_revalidate() says
   "kill it" if descriptor is not opened anymore (in addition to checks
   for task being dead) and we allow dentries of /proc/<pid>/fd/<n> to
   stay around.
parent b991a4bf
......@@ -88,6 +88,11 @@ static inline struct task_struct *proc_task(struct inode *inode)
return PROC_I(inode)->task;
}
static inline int proc_type(struct inode *inode)
{
return PROC_I(inode)->type;
}
ssize_t proc_pid_read_maps(struct task_struct*,struct file*,char*,size_t,loff_t*);
int proc_pid_stat(struct task_struct*,char*);
int proc_pid_status(struct task_struct*,char*);
......@@ -99,7 +104,7 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm
struct task_struct *task = proc_task(inode);
struct files_struct *files;
struct file *file;
int fd = (inode->i_ino & 0xffff) - PROC_PID_FD_DIR;
int fd = proc_type(inode) - PROC_PID_FD_DIR;
task_lock(task);
files = task->files;
......@@ -735,6 +740,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
*/
get_task_struct(task);
ei->task = task;
ei->type = ino;
inode->i_uid = 0;
inode->i_gid = 0;
if (ino == PROC_PID_INO || task_dumpable(task)) {
......@@ -753,11 +759,6 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
/* dentry stuff */
static int pid_fd_revalidate(struct dentry * dentry, int flags)
{
return 0;
}
/*
* Exceptional case: normally we are not allowed to unhash a busy
* directory. In this case, however, we can do it - no aliasing problems
......@@ -771,6 +772,31 @@ static int pid_revalidate(struct dentry * dentry, int flags)
return 0;
}
static int pid_fd_revalidate(struct dentry * dentry, int flags)
{
struct task_struct *task = proc_task(dentry->d_inode);
int fd = proc_type(dentry->d_inode) - PROC_PID_FD_DIR;
struct files_struct *files;
task_lock(task);
files = task->files;
if (files)
atomic_inc(&files->count);
task_unlock(task);
if (files) {
read_lock(&files->file_lock);
if (fcheck_files(files, fd)) {
read_unlock(&files->file_lock);
put_files_struct(files);
return 1;
}
read_unlock(&files->file_lock);
put_files_struct(files);
}
d_drop(dentry);
return 0;
}
static void pid_base_iput(struct dentry *dentry, struct inode *inode)
{
struct task_struct *task = proc_task(inode);
......@@ -781,11 +807,6 @@ static void pid_base_iput(struct dentry *dentry, struct inode *inode)
iput(inode);
}
static int pid_fd_delete_dentry(struct dentry * dentry)
{
return 1;
}
static int pid_delete_dentry(struct dentry * dentry)
{
return proc_task(dentry->d_inode)->pid == 0;
......@@ -794,7 +815,7 @@ static int pid_delete_dentry(struct dentry * dentry)
static struct dentry_operations pid_fd_dentry_operations =
{
d_revalidate: pid_fd_revalidate,
d_delete: pid_fd_delete_dentry,
d_delete: pid_delete_dentry,
};
static struct dentry_operations pid_dentry_operations =
......@@ -879,8 +900,8 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
return NULL;
out_unlock2:
put_files_struct(files);
read_unlock(&files->file_lock);
put_files_struct(files);
out_unlock:
iput(inode);
out:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment