[readdir] introduce ->iterate(), ctx->pos, dir_emit()

New method - ->iterate(file, ctx).  That's the replacement for ->readdir();
it takes callback from ctx->actor, uses ctx->pos instead of file->f_pos and
calls dir_emit(ctx, ...) instead of filldir(data, ...).  It does *not*
update file->f_pos (or look at it, for that matter); iterate_dir() does the
update.

Note that dir_emit() takes the offset from ctx->pos (and eventually
filldir_t will lose that argument).

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro
2013-05-15 18:49:12 -04:00
parent 5c0ba4e076
commit bb6f619b3a
7 changed files with 47 additions and 18 deletions

View File

@@ -240,11 +240,16 @@ struct name_list {
struct list_head list;
};
struct nfs4_dir_ctx {
struct dir_context ctx;
struct list_head names;
};
static int
nfsd4_build_namelist(void *arg, const char *name, int namlen,
loff_t offset, u64 ino, unsigned int d_type)
{
struct list_head *names = arg;
struct nfs4_dir_ctx *ctx = arg;
struct name_list *entry;
if (namlen != HEXDIR_LEN - 1)
@@ -254,7 +259,7 @@ nfsd4_build_namelist(void *arg, const char *name, int namlen,
return -ENOMEM;
memcpy(entry->name, name, HEXDIR_LEN - 1);
entry->name[HEXDIR_LEN - 1] = '\0';
list_add(&entry->list, names);
list_add(&entry->list, &ctx->names);
return 0;
}
@@ -263,10 +268,7 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
{
const struct cred *original_cred;
struct dentry *dir = nn->rec_file->f_path.dentry;
struct {
struct dir_context ctx;
struct list_head names;
} ctx;
struct nfs4_dir_ctx ctx;
int status;
status = nfs4_save_creds(&original_cred);