[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:
@@ -391,8 +391,7 @@ static int coda_readdir(struct file *coda_file, void *buf, filldir_t filldir)
|
||||
if (!host_file->f_op)
|
||||
return -ENOTDIR;
|
||||
|
||||
if (host_file->f_op->readdir)
|
||||
{
|
||||
if (host_file->f_op->readdir) {
|
||||
/* potemkin case: we were handed a directory inode.
|
||||
* We can't use vfs_readdir because we have to keep the file
|
||||
* position in sync between the coda_file and the host_file.
|
||||
@@ -410,8 +409,20 @@ static int coda_readdir(struct file *coda_file, void *buf, filldir_t filldir)
|
||||
|
||||
coda_file->f_pos = host_file->f_pos;
|
||||
mutex_unlock(&host_inode->i_mutex);
|
||||
}
|
||||
else /* Venus: we must read Venus dirents from a file */
|
||||
} else if (host_file->f_op->iterate) {
|
||||
struct inode *host_inode = file_inode(host_file);
|
||||
struct dir_context *ctx = buf;
|
||||
|
||||
mutex_lock(&host_inode->i_mutex);
|
||||
ret = -ENOENT;
|
||||
if (!IS_DEADDIR(host_inode)) {
|
||||
ret = host_file->f_op->iterate(host_file, ctx);
|
||||
file_accessed(host_file);
|
||||
}
|
||||
mutex_unlock(&host_inode->i_mutex);
|
||||
|
||||
coda_file->f_pos = ctx->pos;
|
||||
} else /* Venus: we must read Venus dirents from a file */
|
||||
ret = coda_venus_readdir(coda_file, buf, filldir);
|
||||
|
||||
return ret;
|
||||
|
Reference in New Issue
Block a user