um: hostfs: Reduce number of syscalls in readdir

Currently hostfs issues every time a seekdir(), in fact
it has to do this only upon the first call.
Also telldir() can be omitted as we can obtain the directory
offset from readdir().

Signed-off-by: Richard Weinberger <richard@nod.at>
This commit is contained in:
Richard Weinberger 2015-03-24 15:47:38 +01:00
parent a98a6d864d
commit 0c9bd6365d
3 changed files with 12 additions and 4 deletions

View File

@ -66,7 +66,8 @@ extern int stat_file(const char *path, struct hostfs_stat *p, int fd);
extern int access_file(char *path, int r, int w, int x); extern int access_file(char *path, int r, int w, int x);
extern int open_file(char *path, int r, int w, int append); extern int open_file(char *path, int r, int w, int append);
extern void *open_dir(char *path, int *err_out); extern void *open_dir(char *path, int *err_out);
extern char *read_dir(void *stream, unsigned long long *pos, extern void seek_dir(void *stream, unsigned long long pos);
extern char *read_dir(void *stream, unsigned long long *pos_out,
unsigned long long *ino_out, int *len_out, unsigned long long *ino_out, int *len_out,
unsigned int *type_out); unsigned int *type_out);
extern void close_file(void *stream); extern void close_file(void *stream);

View File

@ -292,6 +292,7 @@ static int hostfs_readdir(struct file *file, struct dir_context *ctx)
if (dir == NULL) if (dir == NULL)
return -error; return -error;
next = ctx->pos; next = ctx->pos;
seek_dir(dir, next);
while ((name = read_dir(dir, &next, &ino, &len, &type)) != NULL) { while ((name = read_dir(dir, &next, &ino, &len, &type)) != NULL) {
if (!dir_emit(ctx, name, len, ino, type)) if (!dir_emit(ctx, name, len, ino, type))
break; break;

View File

@ -97,21 +97,27 @@ void *open_dir(char *path, int *err_out)
return dir; return dir;
} }
char *read_dir(void *stream, unsigned long long *pos, void seek_dir(void *stream, unsigned long long pos)
{
DIR *dir = stream;
seekdir(dir, pos);
}
char *read_dir(void *stream, unsigned long long *pos_out,
unsigned long long *ino_out, int *len_out, unsigned long long *ino_out, int *len_out,
unsigned int *type_out) unsigned int *type_out)
{ {
DIR *dir = stream; DIR *dir = stream;
struct dirent *ent; struct dirent *ent;
seekdir(dir, *pos);
ent = readdir(dir); ent = readdir(dir);
if (ent == NULL) if (ent == NULL)
return NULL; return NULL;
*len_out = strlen(ent->d_name); *len_out = strlen(ent->d_name);
*ino_out = ent->d_ino; *ino_out = ent->d_ino;
*type_out = ent->d_type; *type_out = ent->d_type;
*pos = telldir(dir); *pos_out = ent->d_off;
return ent->d_name; return ent->d_name;
} }