aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2015-03-24 10:47:38 -0400
committerRichard Weinberger <richard@nod.at>2015-04-13 15:01:07 -0400
commit0c9bd6365d0b278728359843b8303047ddedb831 (patch)
tree086abfcb95b657832d2e318ca5c3fa47822c8689
parenta98a6d864d3b84219a6ec6213b00c260fb52f9f4 (diff)
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);
66extern int access_file(char *path, int r, int w, int x); 66extern int access_file(char *path, int r, int w, int x);
67extern int open_file(char *path, int r, int w, int append); 67extern int open_file(char *path, int r, int w, int append);
68extern void *open_dir(char *path, int *err_out); 68extern void *open_dir(char *path, int *err_out);
69extern char *read_dir(void *stream, unsigned long long *pos, 69extern void seek_dir(void *stream, unsigned long long pos);
70extern char *read_dir(void *stream, unsigned long long *pos_out,
70 unsigned long long *ino_out, int *len_out, 71 unsigned long long *ino_out, int *len_out,
71 unsigned int *type_out); 72 unsigned int *type_out);
72extern void close_file(void *stream); 73extern 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)
292 if (dir == NULL) 292 if (dir == NULL)
293 return -error; 293 return -error;
294 next = ctx->pos; 294 next = ctx->pos;
295 seek_dir(dir, next);
295 while ((name = read_dir(dir, &next, &ino, &len, &type)) != NULL) { 296 while ((name = read_dir(dir, &next, &ino, &len, &type)) != NULL) {
296 if (!dir_emit(ctx, name, len, ino, type)) 297 if (!dir_emit(ctx, name, len, ino, type))
297 break; 298 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)
97 return dir; 97 return dir;
98} 98}
99 99
100char *read_dir(void *stream, unsigned long long *pos, 100void seek_dir(void *stream, unsigned long long pos)
101{
102 DIR *dir = stream;
103
104 seekdir(dir, pos);
105}
106
107char *read_dir(void *stream, unsigned long long *pos_out,
101 unsigned long long *ino_out, int *len_out, 108 unsigned long long *ino_out, int *len_out,
102 unsigned int *type_out) 109 unsigned int *type_out)
103{ 110{
104 DIR *dir = stream; 111 DIR *dir = stream;
105 struct dirent *ent; 112 struct dirent *ent;
106 113
107 seekdir(dir, *pos);
108 ent = readdir(dir); 114 ent = readdir(dir);
109 if (ent == NULL) 115 if (ent == NULL)
110 return NULL; 116 return NULL;
111 *len_out = strlen(ent->d_name); 117 *len_out = strlen(ent->d_name);
112 *ino_out = ent->d_ino; 118 *ino_out = ent->d_ino;
113 *type_out = ent->d_type; 119 *type_out = ent->d_type;
114 *pos = telldir(dir); 120 *pos_out = ent->d_off;
115 return ent->d_name; 121 return ent->d_name;
116} 122}
117 123