summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2015-03-24 15:47:38 +0100
committerRichard Weinberger <richard@nod.at>2015-04-13 21:01:07 +0200
commit0c9bd6365d0b278728359843b8303047ddedb831 (patch)
tree086abfcb95b657832d2e318ca5c3fa47822c8689
parenta98a6d864d3b84219a6ec6213b00c260fb52f9f4 (diff)
downloadlinux-0c9bd6365d0b278728359843b8303047ddedb831.tar.gz
linux-0c9bd6365d0b278728359843b8303047ddedb831.tar.bz2
linux-0c9bd6365d0b278728359843b8303047ddedb831.zip
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>
-rw-r--r--fs/hostfs/hostfs.h3
-rw-r--r--fs/hostfs/hostfs_kern.c1
-rw-r--r--fs/hostfs/hostfs_user.c12
3 files changed, 12 insertions, 4 deletions
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
index 493262e43443..91e19f9dffe5 100644
--- a/fs/hostfs/hostfs.h
+++ b/fs/hostfs/hostfs.h
@@ -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 open_file(char *path, int r, int w, int append);
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 int *type_out);
extern void close_file(void *stream);
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index e77da44a235c..d0a2f68a0eea 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -292,6 +292,7 @@ static int hostfs_readdir(struct file *file, struct dir_context *ctx)
if (dir == NULL)
return -error;
next = ctx->pos;
+ seek_dir(dir, next);
while ((name = read_dir(dir, &next, &ino, &len, &type)) != NULL) {
if (!dir_emit(ctx, name, len, ino, type))
break;
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
index 34ab81b21c93..9c1e0f019880 100644
--- a/fs/hostfs/hostfs_user.c
+++ b/fs/hostfs/hostfs_user.c
@@ -97,21 +97,27 @@ void *open_dir(char *path, int *err_out)
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 int *type_out)
{
DIR *dir = stream;
struct dirent *ent;
- seekdir(dir, *pos);
ent = readdir(dir);
if (ent == NULL)
return NULL;
*len_out = strlen(ent->d_name);
*ino_out = ent->d_ino;
*type_out = ent->d_type;
- *pos = telldir(dir);
+ *pos_out = ent->d_off;
return ent->d_name;
}