Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f0c3b509 authored by Al Viro's avatar Al Viro
Browse files

[readdir] convert procfs



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 68c61471
Loading
Loading
Loading
Loading
+14 −19
Original line number Diff line number Diff line
@@ -542,8 +542,8 @@ static const struct file_operations hppfs_file_fops = {
};

struct hppfs_dirent {
	void *vfs_dirent;
	filldir_t filldir;
	struct dir_context ctx;
	struct dir_context *caller;
	struct dentry *dentry;
};

@@ -555,34 +555,29 @@ static int hppfs_filldir(void *d, const char *name, int size,
	if (file_removed(dirent->dentry, name))
		return 0;

	return (*dirent->filldir)(dirent->vfs_dirent, name, size, offset,
				  inode, type);
	dirent->caller->pos = dirent->ctx.pos;
	return !dir_emit(dirent->caller, name, size, inode, type);
}

static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
static int hppfs_readdir(struct file *file, struct dir_context *ctx)
{
	struct hppfs_private *data = file->private_data;
	struct file *proc_file = data->proc_file;
	int (*readdir)(struct file *, void *, filldir_t);
	struct hppfs_dirent dirent = ((struct hppfs_dirent)
		                      { .vfs_dirent  	= ent,
					.filldir 	= filldir,
	struct hppfs_dirent d = {
		.ctx.actor	= hppfs_filldir,
		.caller		= ctx,
		.dentry  	= file->f_path.dentry
				      });
	};
	int err;

	readdir = file_inode(proc_file)->i_fop->readdir;

	proc_file->f_pos = file->f_pos;
	err = (*readdir)(proc_file, &dirent, hppfs_filldir);
	file->f_pos = proc_file->f_pos;

	proc_file->f_pos = ctx->pos;
	err = iterate_dir(proc_file, &d.ctx);
	ctx->pos = d.ctx.pos;
	return err;
}

static const struct file_operations hppfs_dir_fops = {
	.owner		= NULL,
	.readdir	= hppfs_readdir,
	.iterate	= hppfs_readdir,
	.open		= hppfs_dir_open,
	.llseek		= default_llseek,
	.release	= hppfs_release,
+133 −230
Original line number Diff line number Diff line
@@ -1681,11 +1681,11 @@ const struct dentry_operations pid_dentry_operations =
 * reported by readdir in sync with the inode numbers reported
 * by stat.
 */
int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
bool proc_fill_cache(struct file *file, struct dir_context *ctx,
	const char *name, int len,
	instantiate_t instantiate, struct task_struct *task, const void *ptr)
{
	struct dentry *child, *dir = filp->f_path.dentry;
	struct dentry *child, *dir = file->f_path.dentry;
	struct inode *inode;
	struct qstr qname;
	ino_t ino = 0;
@@ -1720,7 +1720,7 @@ end_instantiate:
		ino = find_inode_number(dir, &qname);
	if (!ino)
		ino = 1;
	return filldir(dirent, name, len, filp->f_pos, ino, type);
	return dir_emit(ctx, name, len, ino, type);
}

#ifdef CONFIG_CHECKPOINT_RESTORE
@@ -1931,14 +1931,15 @@ static const struct inode_operations proc_map_files_inode_operations = {
};

static int
proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)
proc_map_files_readdir(struct file *file, struct dir_context *ctx)
{
	struct dentry *dentry = filp->f_path.dentry;
	struct inode *inode = dentry->d_inode;
	struct vm_area_struct *vma;
	struct task_struct *task;
	struct mm_struct *mm;
	ino_t ino;
	unsigned long nr_files, pos, i;
	struct flex_array *fa = NULL;
	struct map_files_info info;
	struct map_files_info *p;
	int ret;

	ret = -EPERM;
@@ -1946,7 +1947,7 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)
		goto out;

	ret = -ENOENT;
	task = get_proc_task(inode);
	task = get_proc_task(file_inode(file));
	if (!task)
		goto out;

@@ -1955,23 +1956,8 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)
		goto out_put_task;

	ret = 0;
	switch (filp->f_pos) {
	case 0:
		ino = inode->i_ino;
		if (filldir(dirent, ".", 1, 0, ino, DT_DIR) < 0)
	if (!dir_emit_dots(file, ctx))
		goto out_put_task;
		filp->f_pos++;
	case 1:
		ino = parent_ino(dentry);
		if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
			goto out_put_task;
		filp->f_pos++;
	default:
	{
		unsigned long nr_files, pos, i;
		struct flex_array *fa = NULL;
		struct map_files_info info;
		struct map_files_info *p;

	mm = get_task_mm(task);
	if (!mm)
@@ -1991,7 +1977,7 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)
	 */

	for (vma = mm->mmap, pos = 2; vma; vma = vma->vm_next) {
			if (vma->vm_file && ++pos > filp->f_pos)
		if (vma->vm_file && ++pos > ctx->pos)
			nr_files++;
	}

@@ -2011,7 +1997,7 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)
				vma = vma->vm_next) {
			if (!vma->vm_file)
				continue;
				if (++pos <= filp->f_pos)
			if (++pos <= ctx->pos)
				continue;

			info.mode = vma->vm_file->f_mode;
@@ -2026,20 +2012,17 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)

	for (i = 0; i < nr_files; i++) {
		p = flex_array_get(fa, i);
			ret = proc_fill_cache(filp, dirent, filldir,
		if (!proc_fill_cache(file, ctx,
				      p->name, p->len,
				      proc_map_files_instantiate,
				      task,
					      (void *)(unsigned long)p->mode);
			if (ret)
				      (void *)(unsigned long)p->mode))
			break;
			filp->f_pos++;
		ctx->pos++;
	}
	if (fa)
		flex_array_free(fa);
	mmput(mm);
	}
	}

out_put_task:
	put_task_struct(task);
@@ -2049,7 +2032,7 @@ out:

static const struct file_operations proc_map_files_operations = {
	.read		= generic_read_dir,
	.readdir	= proc_map_files_readdir,
	.iterate	= proc_map_files_readdir,
	.llseek		= default_llseek,
};

@@ -2217,67 +2200,30 @@ out_no_task:
	return error;
}

static int proc_pident_fill_cache(struct file *filp, void *dirent,
	filldir_t filldir, struct task_struct *task, const struct pid_entry *p)
{
	return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
				proc_pident_instantiate, task, p);
}

static int proc_pident_readdir(struct file *filp,
		void *dirent, filldir_t filldir,
static int proc_pident_readdir(struct file *file, struct dir_context *ctx,
		const struct pid_entry *ents, unsigned int nents)
{
	int i;
	struct dentry *dentry = filp->f_path.dentry;
	struct inode *inode = dentry->d_inode;
	struct task_struct *task = get_proc_task(inode);
	const struct pid_entry *p, *last;
	ino_t ino;
	int ret;
	struct task_struct *task = get_proc_task(file_inode(file));
	const struct pid_entry *p;

	ret = -ENOENT;
	if (!task)
		goto out_no_task;
		return -ENOENT;

	ret = 0;
	i = filp->f_pos;
	switch (i) {
	case 0:
		ino = inode->i_ino;
		if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
	if (!dir_emit_dots(file, ctx))
		goto out;
		i++;
		filp->f_pos++;
		/* fall through */
	case 1:
		ino = parent_ino(dentry);
		if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
			goto out;
		i++;
		filp->f_pos++;
		/* fall through */
	default:
		i -= 2;
		if (i >= nents) {
			ret = 1;
			goto out;
		}
		p = ents + i;
		last = &ents[nents - 1];
		while (p <= last) {
			if (proc_pident_fill_cache(filp, dirent, filldir, task, p) < 0)

	if (ctx->pos >= nents + 2)
		goto out;
			filp->f_pos++;
			p++;
		}
	}

	ret = 1;
	for (p = ents + (ctx->pos - 2); p <= ents + nents - 1; p++) {
		if (!proc_fill_cache(file, ctx, p->name, p->len,
				proc_pident_instantiate, task, p))
			break;
		ctx->pos++;
	}
out:
	put_task_struct(task);
out_no_task:
	return ret;
	return 0;
}

#ifdef CONFIG_SECURITY
@@ -2362,16 +2308,15 @@ static const struct pid_entry attr_dir_stuff[] = {
	REG("sockcreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations),
};

static int proc_attr_dir_readdir(struct file * filp,
			     void * dirent, filldir_t filldir)
static int proc_attr_dir_readdir(struct file *file, struct dir_context *ctx)
{
	return proc_pident_readdir(filp,dirent,filldir,
	return proc_pident_readdir(file, ctx, 
				   attr_dir_stuff, ARRAY_SIZE(attr_dir_stuff));
}

static const struct file_operations proc_attr_dir_operations = {
	.read		= generic_read_dir,
	.readdir	= proc_attr_dir_readdir,
	.iterate	= proc_attr_dir_readdir,
	.llseek		= default_llseek,
};

@@ -2725,16 +2670,15 @@ static const struct pid_entry tgid_base_stuff[] = {
#endif
};

static int proc_tgid_base_readdir(struct file * filp,
			     void * dirent, filldir_t filldir)
static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx)
{
	return proc_pident_readdir(filp,dirent,filldir,
	return proc_pident_readdir(file, ctx,
				   tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff));
}

static const struct file_operations proc_tgid_base_operations = {
	.read		= generic_read_dir,
	.readdir	= proc_tgid_base_readdir,
	.iterate	= proc_tgid_base_readdir,
	.llseek		= default_llseek,
};

@@ -2936,58 +2880,42 @@ retry:

#define TGID_OFFSET (FIRST_PROCESS_ENTRY + 1)

static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
	struct tgid_iter iter)
{
	char name[PROC_NUMBUF];
	int len = snprintf(name, sizeof(name), "%d", iter.tgid);
	return proc_fill_cache(filp, dirent, filldir, name, len,
				proc_pid_instantiate, iter.task, NULL);
}

static int fake_filldir(void *buf, const char *name, int namelen,
			loff_t offset, u64 ino, unsigned d_type)
{
	return 0;
}

/* for the /proc/ directory itself, after non-process stuff has been done */
int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
int proc_pid_readdir(struct file *file, struct dir_context *ctx)
{
	struct tgid_iter iter;
	struct pid_namespace *ns;
	filldir_t __filldir;
	loff_t pos = filp->f_pos;
	loff_t pos = ctx->pos;

	if (pos >= PID_MAX_LIMIT + TGID_OFFSET)
		goto out;
		return 0;

	if (pos == TGID_OFFSET - 1) {
		if (proc_fill_cache(filp, dirent, filldir, "self", 4,
					NULL, NULL, NULL) < 0)
			goto out;
		if (!proc_fill_cache(file, ctx, "self", 4, NULL, NULL, NULL))
			return 0;
		iter.tgid = 0;
	} else {
		iter.tgid = pos - TGID_OFFSET;
	}
	iter.task = NULL;
	ns = filp->f_dentry->d_sb->s_fs_info;
	ns = file->f_dentry->d_sb->s_fs_info;
	for (iter = next_tgid(ns, iter);
	     iter.task;
	     iter.tgid += 1, iter = next_tgid(ns, iter)) {
		if (has_pid_permissions(ns, iter.task, 2))
			__filldir = filldir;
		else
			__filldir = fake_filldir;
		char name[PROC_NUMBUF];
		int len;
		if (!has_pid_permissions(ns, iter.task, 2))
			continue;

		filp->f_pos = iter.tgid + TGID_OFFSET;
		if (proc_pid_fill_cache(filp, dirent, __filldir, iter) < 0) {
		len = snprintf(name, sizeof(name), "%d", iter.tgid);
		ctx->pos = iter.tgid + TGID_OFFSET;
		if (!proc_fill_cache(file, ctx, name, len,
				     proc_pid_instantiate, iter.task, NULL)) {
			put_task_struct(iter.task);
			goto out;
			return 0;
		}
	}
	filp->f_pos = PID_MAX_LIMIT + TGID_OFFSET;
out:
	ctx->pos = PID_MAX_LIMIT + TGID_OFFSET;
	return 0;
}

@@ -3075,10 +3003,9 @@ static const struct pid_entry tid_base_stuff[] = {
#endif
};

static int proc_tid_base_readdir(struct file * filp,
			     void * dirent, filldir_t filldir)
static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx)
{
	return proc_pident_readdir(filp,dirent,filldir,
	return proc_pident_readdir(file, ctx,
				   tid_base_stuff, ARRAY_SIZE(tid_base_stuff));
}

@@ -3090,7 +3017,7 @@ static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *den

static const struct file_operations proc_tid_base_operations = {
	.read		= generic_read_dir,
	.readdir	= proc_tid_base_readdir,
	.iterate	= proc_tid_base_readdir,
	.llseek		= default_llseek,
};

@@ -3231,30 +3158,16 @@ static struct task_struct *next_tid(struct task_struct *start)
	return pos;
}

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

/* for the /proc/TGID/task/ directories */
static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir)
static int proc_task_readdir(struct file *file, struct dir_context *ctx)
{
	struct dentry *dentry = filp->f_path.dentry;
	struct inode *inode = dentry->d_inode;
	struct task_struct *leader = NULL;
	struct task_struct *task;
	int retval = -ENOENT;
	ino_t ino;
	int tid;
	struct task_struct *task = get_proc_task(file_inode(file));
	struct pid_namespace *ns;
	int tid;

	task = get_proc_task(inode);
	if (!task)
		goto out_no_task;
		return -ENOENT;
	rcu_read_lock();
	if (pid_alive(task)) {
		leader = task->group_leader;
@@ -3263,46 +3176,36 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi
	rcu_read_unlock();
	put_task_struct(task);
	if (!leader)
		goto out_no_task;
	retval = 0;
		return -ENOENT;

	switch ((unsigned long)filp->f_pos) {
	case 0:
		ino = inode->i_ino;
		if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) < 0)
			goto out;
		filp->f_pos++;
		/* fall through */
	case 1:
		ino = parent_ino(dentry);
		if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) < 0)
	if (!dir_emit_dots(file, ctx))
		goto out;
		filp->f_pos++;
		/* fall through */
	}

	/* f_version caches the tgid value that the last readdir call couldn't
	 * return. lseek aka telldir automagically resets f_version to 0.
	 */
	ns = filp->f_dentry->d_sb->s_fs_info;
	tid = (int)filp->f_version;
	filp->f_version = 0;
	for (task = first_tid(leader, tid, filp->f_pos - 2, ns);
	ns = file->f_dentry->d_sb->s_fs_info;
	tid = (int)file->f_version;
	file->f_version = 0;
	for (task = first_tid(leader, tid, ctx->pos - 2, ns);
	     task;
	     task = next_tid(task), filp->f_pos++) {
	     task = next_tid(task), ctx->pos++) {
		char name[PROC_NUMBUF];
		int len;
		tid = task_pid_nr_ns(task, ns);
		if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) {
		len = snprintf(name, sizeof(name), "%d", tid);
		if (!proc_fill_cache(file, ctx, name, len,
				proc_task_instantiate, task, NULL)) {
			/* returning this tgid failed, save it as the first
			 * pid for the next readir call */
			filp->f_version = (u64)tid;
			file->f_version = (u64)tid;
			put_task_struct(task);
			break;
		}
	}
out:
	put_task_struct(leader);
out_no_task:
	return retval;
	return 0;
}

static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
@@ -3328,6 +3231,6 @@ static const struct inode_operations proc_task_inode_operations = {

static const struct file_operations proc_task_operations = {
	.read		= generic_read_dir,
	.readdir	= proc_task_readdir,
	.iterate	= proc_task_readdir,
	.llseek		= default_llseek,
};
+40 −56
Original line number Diff line number Diff line
@@ -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)
	if (!dir_emit_dots(file, ctx))
		goto out;
			filp->f_pos++;
		case 1:
			ino = parent_ino(dentry);
			if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
	if (!dir_emit_dots(file, ctx))
		goto out;
			filp->f_pos++;
		default:
	files = get_files_struct(p);
	if (!files)
		goto out;

	rcu_read_lock();
			for (fd = filp->f_pos - 2;
	for (fd = ctx->pos - 2;
	     fd < files_fdtable(files)->max_fds;
			     fd++, filp->f_pos++) {
	     fd++, ctx->pos++) {
		char name[PROC_NUMBUF];
		int len;
				int rv;

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

		len = snprintf(name, sizeof(name), "%d", fd);
				rv = proc_fill_cache(filp, dirent, filldir,
		if (!proc_fill_cache(file, ctx,
				     name, len, instantiate, p,
						     (void *)(unsigned long)fd);
				if (rv < 0)
				     (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,
};
+38 −62
Original line number Diff line number Diff line
@@ -233,40 +233,21 @@ struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry,
 * value of the readdir() call, as long as it's non-negative
 * for success..
 */
int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent,
		filldir_t filldir)
int proc_readdir_de(struct proc_dir_entry *de, struct file *file,
		    struct dir_context *ctx)
{
	unsigned int ino;
	int i;
	struct inode *inode = file_inode(filp);
	int ret = 0;

	ino = inode->i_ino;
	i = filp->f_pos;
	switch (i) {
		case 0:
			if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
				goto out;
			i++;
			filp->f_pos++;
			/* fall through */
		case 1:
			if (filldir(dirent, "..", 2, i,
				    parent_ino(filp->f_path.dentry),
				    DT_DIR) < 0)
				goto out;
			i++;
			filp->f_pos++;
			/* fall through */
		default:

	if (!dir_emit_dots(file, ctx))
		return 0;

	spin_lock(&proc_subdir_lock);
	de = de->subdir;
			i -= 2;
	i = ctx->pos - 2;
	for (;;) {
		if (!de) {
					ret = 1;
			spin_unlock(&proc_subdir_lock);
					goto out;
			return 0;
		}
		if (!i)
			break;
@@ -276,33 +257,28 @@ int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent,

	do {
		struct proc_dir_entry *next;

				/* filldir passes info to user space */
		pde_get(de);
		spin_unlock(&proc_subdir_lock);
				if (filldir(dirent, de->name, de->namelen, filp->f_pos,
					    de->low_ino, de->mode >> 12) < 0) {
		if (!dir_emit(ctx, de->name, de->namelen,
			    de->low_ino, de->mode >> 12)) {
			pde_put(de);
					goto out;
			return 0;
		}
		spin_lock(&proc_subdir_lock);
				filp->f_pos++;
		ctx->pos++;
		next = de->next;
		pde_put(de);
		de = next;
	} while (de);
	spin_unlock(&proc_subdir_lock);
	}
	ret = 1;
out:
	return ret;	
	return 0;
}

int proc_readdir(struct file *filp, void *dirent, filldir_t filldir)
int proc_readdir(struct file *file, struct dir_context *ctx)
{
	struct inode *inode = file_inode(filp);
	struct inode *inode = file_inode(file);

	return proc_readdir_de(PDE(inode), filp, dirent, filldir);
	return proc_readdir_de(PDE(inode), file, ctx);
}

/*
@@ -313,7 +289,7 @@ int proc_readdir(struct file *filp, void *dirent, filldir_t filldir)
static const struct file_operations proc_dir_operations = {
	.llseek			= generic_file_llseek,
	.read			= generic_read_dir,
	.readdir		= proc_readdir,
	.iterate		= proc_readdir,
};

/*
+4 −4
Original line number Diff line number Diff line
@@ -165,14 +165,14 @@ extern int proc_setattr(struct dentry *, struct iattr *);
extern struct inode *proc_pid_make_inode(struct super_block *, struct task_struct *);
extern int pid_revalidate(struct dentry *, unsigned int);
extern int pid_delete_dentry(const struct dentry *);
extern int proc_pid_readdir(struct file *, void *, filldir_t);
extern int proc_pid_readdir(struct file *, struct dir_context *);
extern struct dentry *proc_pid_lookup(struct inode *, struct dentry *, unsigned int);
extern loff_t mem_lseek(struct file *, loff_t, int);

/* Lookups */
typedef struct dentry *instantiate_t(struct inode *, struct dentry *,
				     struct task_struct *, const void *);
extern int proc_fill_cache(struct file *, void *, filldir_t, const char *, int,
extern bool proc_fill_cache(struct file *, struct dir_context *, const char *, int,
			   instantiate_t, struct task_struct *, const void *);

/*
@@ -183,8 +183,8 @@ extern spinlock_t proc_subdir_lock;
extern struct dentry *proc_lookup(struct inode *, struct dentry *, unsigned int);
extern struct dentry *proc_lookup_de(struct proc_dir_entry *, struct inode *,
				     struct dentry *);
extern int proc_readdir(struct file *, void *, filldir_t);
extern int proc_readdir_de(struct proc_dir_entry *, struct file *, void *, filldir_t);
extern int proc_readdir(struct file *, struct dir_context *);
extern int proc_readdir_de(struct proc_dir_entry *, struct file *, struct dir_context *);

static inline struct proc_dir_entry *pde_get(struct proc_dir_entry *pde)
{
Loading