[readdir] convert procfs

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro
2013-05-16 12:07:31 -04:00
parent 68c6147113
commit f0c3b5093a
9 changed files with 283 additions and 488 deletions

View File

@@ -219,74 +219,58 @@ out_no_task:
return result;
}
static int proc_readfd_common(struct file * filp, void * dirent,
filldir_t filldir, instantiate_t instantiate)
static int proc_readfd_common(struct file *file, struct dir_context *ctx,
instantiate_t instantiate)
{
struct dentry *dentry = filp->f_path.dentry;
struct inode *inode = dentry->d_inode;
struct task_struct *p = get_proc_task(inode);
struct task_struct *p = get_proc_task(file_inode(file));
struct files_struct *files;
unsigned int fd, ino;
int retval;
unsigned int fd;
retval = -ENOENT;
if (!p)
goto out_no_task;
retval = 0;
return -ENOENT;
fd = filp->f_pos;
switch (fd) {
case 0:
if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
goto out;
filp->f_pos++;
case 1:
ino = parent_ino(dentry);
if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
goto out;
filp->f_pos++;
default:
files = get_files_struct(p);
if (!files)
goto out;
rcu_read_lock();
for (fd = filp->f_pos - 2;
fd < files_fdtable(files)->max_fds;
fd++, filp->f_pos++) {
char name[PROC_NUMBUF];
int len;
int rv;
if (!dir_emit_dots(file, ctx))
goto out;
if (!dir_emit_dots(file, ctx))
goto out;
files = get_files_struct(p);
if (!files)
goto out;
if (!fcheck_files(files, fd))
continue;
rcu_read_unlock();
rcu_read_lock();
for (fd = ctx->pos - 2;
fd < files_fdtable(files)->max_fds;
fd++, ctx->pos++) {
char name[PROC_NUMBUF];
int len;
len = snprintf(name, sizeof(name), "%d", fd);
rv = proc_fill_cache(filp, dirent, filldir,
name, len, instantiate, p,
(void *)(unsigned long)fd);
if (rv < 0)
goto out_fd_loop;
rcu_read_lock();
}
rcu_read_unlock();
out_fd_loop:
put_files_struct(files);
if (!fcheck_files(files, fd))
continue;
rcu_read_unlock();
len = snprintf(name, sizeof(name), "%d", fd);
if (!proc_fill_cache(file, ctx,
name, len, instantiate, p,
(void *)(unsigned long)fd))
goto out_fd_loop;
rcu_read_lock();
}
rcu_read_unlock();
out_fd_loop:
put_files_struct(files);
out:
put_task_struct(p);
out_no_task:
return retval;
return 0;
}
static int proc_readfd(struct file *filp, void *dirent, filldir_t filldir)
static int proc_readfd(struct file *file, struct dir_context *ctx)
{
return proc_readfd_common(filp, dirent, filldir, proc_fd_instantiate);
return proc_readfd_common(file, ctx, proc_fd_instantiate);
}
const struct file_operations proc_fd_operations = {
.read = generic_read_dir,
.readdir = proc_readfd,
.iterate = proc_readfd,
.llseek = default_llseek,
};
@@ -351,9 +335,9 @@ proc_lookupfdinfo(struct inode *dir, struct dentry *dentry, unsigned int flags)
return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
}
static int proc_readfdinfo(struct file *filp, void *dirent, filldir_t filldir)
static int proc_readfdinfo(struct file *file, struct dir_context *ctx)
{
return proc_readfd_common(filp, dirent, filldir,
return proc_readfd_common(file, ctx,
proc_fdinfo_instantiate);
}
@@ -364,6 +348,6 @@ const struct inode_operations proc_fdinfo_inode_operations = {
const struct file_operations proc_fdinfo_operations = {
.read = generic_read_dir,
.readdir = proc_readfdinfo,
.iterate = proc_readfdinfo,
.llseek = default_llseek,
};