diff options
author | Richard Weinberger <richard@nod.at> | 2015-03-24 10:47:38 -0400 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2015-04-13 15:01:07 -0400 |
commit | 0c9bd6365d0b278728359843b8303047ddedb831 (patch) | |
tree | 086abfcb95b657832d2e318ca5c3fa47822c8689 | |
parent | a98a6d864d3b84219a6ec6213b00c260fb52f9f4 (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.h | 3 | ||||
-rw-r--r-- | fs/hostfs/hostfs_kern.c | 1 | ||||
-rw-r--r-- | fs/hostfs/hostfs_user.c | 12 |
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); | |||
66 | extern int access_file(char *path, int r, int w, int x); | 66 | extern int access_file(char *path, int r, int w, int x); |
67 | extern int open_file(char *path, int r, int w, int append); | 67 | extern int open_file(char *path, int r, int w, int append); |
68 | extern void *open_dir(char *path, int *err_out); | 68 | extern void *open_dir(char *path, int *err_out); |
69 | extern char *read_dir(void *stream, unsigned long long *pos, | 69 | extern void seek_dir(void *stream, unsigned long long pos); |
70 | extern 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); |
72 | extern void close_file(void *stream); | 73 | 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) | |||
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 | ||
100 | char *read_dir(void *stream, unsigned long long *pos, | 100 | void seek_dir(void *stream, unsigned long long pos) |
101 | { | ||
102 | DIR *dir = stream; | ||
103 | |||
104 | seekdir(dir, pos); | ||
105 | } | ||
106 | |||
107 | char *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 | ||