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) ...@@ -88,6 +88,11 @@ static inline struct task_struct *proc_task(struct inode *inode)
return PROC_I(inode)->task; 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*); 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_stat(struct task_struct*,char*);
int proc_pid_status(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 ...@@ -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 task_struct *task = proc_task(inode);
struct files_struct *files; struct files_struct *files;
struct file *file; 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); task_lock(task);
files = task->files; files = task->files;
...@@ -735,6 +740,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st ...@@ -735,6 +740,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
*/ */
get_task_struct(task); get_task_struct(task);
ei->task = task; ei->task = task;
ei->type = ino;
inode->i_uid = 0; inode->i_uid = 0;
inode->i_gid = 0; inode->i_gid = 0;
if (ino == PROC_PID_INO || task_dumpable(task)) { 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 ...@@ -753,11 +759,6 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
/* dentry stuff */ /* 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 * Exceptional case: normally we are not allowed to unhash a busy
* directory. In this case, however, we can do it - no aliasing problems * 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) ...@@ -771,6 +772,31 @@ static int pid_revalidate(struct dentry * dentry, int flags)
return 0; 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) static void pid_base_iput(struct dentry *dentry, struct inode *inode)
{ {
struct task_struct *task = proc_task(inode); struct task_struct *task = proc_task(inode);
...@@ -781,11 +807,6 @@ static void pid_base_iput(struct dentry *dentry, struct inode *inode) ...@@ -781,11 +807,6 @@ static void pid_base_iput(struct dentry *dentry, struct inode *inode)
iput(inode); iput(inode);
} }
static int pid_fd_delete_dentry(struct dentry * dentry)
{
return 1;
}
static int pid_delete_dentry(struct dentry * dentry) static int pid_delete_dentry(struct dentry * dentry)
{ {
return proc_task(dentry->d_inode)->pid == 0; return proc_task(dentry->d_inode)->pid == 0;
...@@ -794,7 +815,7 @@ static int pid_delete_dentry(struct dentry * dentry) ...@@ -794,7 +815,7 @@ static int pid_delete_dentry(struct dentry * dentry)
static struct dentry_operations pid_fd_dentry_operations = static struct dentry_operations pid_fd_dentry_operations =
{ {
d_revalidate: pid_fd_revalidate, d_revalidate: pid_fd_revalidate,
d_delete: pid_fd_delete_dentry, d_delete: pid_delete_dentry,
}; };
static struct dentry_operations pid_dentry_operations = static struct dentry_operations pid_dentry_operations =
...@@ -879,8 +900,8 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry) ...@@ -879,8 +900,8 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
return NULL; return NULL;
out_unlock2: out_unlock2:
put_files_struct(files);
read_unlock(&files->file_lock); read_unlock(&files->file_lock);
put_files_struct(files);
out_unlock: out_unlock:
iput(inode); iput(inode);
out: 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