summaryrefslogtreecommitdiff
path: root/fs/readdir.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-05-15 13:52:59 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 12:46:46 +0400
commit5c0ba4e0762e6dabd14a5c276652e2defec38de7 (patch)
treecc2c94d81a631b0656782e1f8299da3267871964 /fs/readdir.c
parent83a8761142cb38536e9e88dfc2432d331ea4e257 (diff)
downloadlwn-5c0ba4e0762e6dabd14a5c276652e2defec38de7.tar.gz
lwn-5c0ba4e0762e6dabd14a5c276652e2defec38de7.zip
[readdir] introduce iterate_dir() and dir_context
iterate_dir(): new helper, replacing vfs_readdir(). struct dir_context: contains the readdir callback (and will get more stuff in it), embedded into whatever data that callback wants to deal with; eventually, we'll be passing it to ->readdir() replacement instead of (data,filldir) pair. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/readdir.c')
-rw-r--r--fs/readdir.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/fs/readdir.c b/fs/readdir.c
index fee38e04fae4..5b620a2b45e6 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -20,7 +20,7 @@
#include <asm/uaccess.h>
-int vfs_readdir(struct file *file, filldir_t filler, void *buf)
+int iterate_dir(struct file *file, struct dir_context *ctx)
{
struct inode *inode = file_inode(file);
int res = -ENOTDIR;
@@ -37,15 +37,14 @@ int vfs_readdir(struct file *file, filldir_t filler, void *buf)
res = -ENOENT;
if (!IS_DEADDIR(inode)) {
- res = file->f_op->readdir(file, buf, filler);
+ res = file->f_op->readdir(file, ctx, ctx->actor);
file_accessed(file);
}
mutex_unlock(&inode->i_mutex);
out:
return res;
}
-
-EXPORT_SYMBOL(vfs_readdir);
+EXPORT_SYMBOL(iterate_dir);
/*
* Traditional linux readdir() handling..
@@ -66,6 +65,7 @@ struct old_linux_dirent {
};
struct readdir_callback {
+ struct dir_context ctx;
struct old_linux_dirent __user * dirent;
int result;
};
@@ -73,7 +73,7 @@ struct readdir_callback {
static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
u64 ino, unsigned int d_type)
{
- struct readdir_callback * buf = (struct readdir_callback *) __buf;
+ struct readdir_callback *buf = (struct readdir_callback *) __buf;
struct old_linux_dirent __user * dirent;
unsigned long d_ino;
@@ -112,10 +112,11 @@ SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
if (!f.file)
return -EBADF;
+ buf.ctx.actor = fillonedir;
buf.result = 0;
buf.dirent = dirent;
- error = vfs_readdir(f.file, fillonedir, &buf);
+ error = iterate_dir(f.file, &buf.ctx);
if (buf.result)
error = buf.result;
@@ -137,6 +138,7 @@ struct linux_dirent {
};
struct getdents_callback {
+ struct dir_context ctx;
struct linux_dirent __user * current_dir;
struct linux_dirent __user * previous;
int count;
@@ -205,8 +207,9 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd,
buf.previous = NULL;
buf.count = count;
buf.error = 0;
+ buf.ctx.actor = filldir;
- error = vfs_readdir(f.file, filldir, &buf);
+ error = iterate_dir(f.file, &buf.ctx);
if (error >= 0)
error = buf.error;
lastdirent = buf.previous;
@@ -221,6 +224,7 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd,
}
struct getdents_callback64 {
+ struct dir_context ctx;
struct linux_dirent64 __user * current_dir;
struct linux_dirent64 __user * previous;
int count;
@@ -285,8 +289,9 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd,
buf.previous = NULL;
buf.count = count;
buf.error = 0;
+ buf.ctx.actor = filldir64;
- error = vfs_readdir(f.file, filldir64, &buf);
+ error = iterate_dir(f.file, &buf.ctx);
if (error >= 0)
error = buf.error;
lastdirent = buf.previous;