diff options
author | Geert Uytterhoeven <geert@linux-m68k.org> | 2012-01-27 13:14:58 -0500 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2012-03-24 19:29:52 -0400 |
commit | 3ee6bd8e8dc0c58b9ba5bab7ef8a7a131da346eb (patch) | |
tree | b1050db82803495116ac255a2b6c755622bd1044 /fs/hostfs | |
parent | c0b79a90b1556a7e51d7a49a655eb60306f6258d (diff) |
uml/hostfs: Propagate dirent.d_type to filldir()
Currently the (optional) d_type member in struct dirent is always
DT_UNKNOWN on hostfs, which may confuse buggy software using readdir().
Make sure to propagate its value from the underlying filesystem if it's
available there.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'fs/hostfs')
-rw-r--r-- | fs/hostfs/hostfs.h | 3 | ||||
-rw-r--r-- | fs/hostfs/hostfs_kern.c | 5 | ||||
-rw-r--r-- | fs/hostfs/hostfs_user.c | 4 |
3 files changed, 8 insertions, 4 deletions
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h index 3cbfa93cd782..1fe731337f07 100644 --- a/fs/hostfs/hostfs.h +++ b/fs/hostfs/hostfs.h | |||
@@ -67,7 +67,8 @@ 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 char *read_dir(void *stream, unsigned long long *pos, |
70 | unsigned long long *ino_out, int *len_out); | 70 | unsigned long long *ino_out, int *len_out, |
71 | unsigned int *type_out); | ||
71 | extern void close_file(void *stream); | 72 | extern void close_file(void *stream); |
72 | extern int replace_file(int oldfd, int fd); | 73 | extern int replace_file(int oldfd, int fd); |
73 | extern void close_dir(void *stream); | 74 | extern void close_dir(void *stream); |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index e130bd46d671..dc4222bd6e77 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -283,6 +283,7 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir) | |||
283 | char *name; | 283 | char *name; |
284 | unsigned long long next, ino; | 284 | unsigned long long next, ino; |
285 | int error, len; | 285 | int error, len; |
286 | unsigned int type; | ||
286 | 287 | ||
287 | name = dentry_name(file->f_path.dentry); | 288 | name = dentry_name(file->f_path.dentry); |
288 | if (name == NULL) | 289 | if (name == NULL) |
@@ -292,9 +293,9 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir) | |||
292 | if (dir == NULL) | 293 | if (dir == NULL) |
293 | return -error; | 294 | return -error; |
294 | next = file->f_pos; | 295 | next = file->f_pos; |
295 | while ((name = read_dir(dir, &next, &ino, &len)) != NULL) { | 296 | while ((name = read_dir(dir, &next, &ino, &len, &type)) != NULL) { |
296 | error = (*filldir)(ent, name, len, file->f_pos, | 297 | error = (*filldir)(ent, name, len, file->f_pos, |
297 | ino, DT_UNKNOWN); | 298 | ino, type); |
298 | if (error) break; | 299 | if (error) break; |
299 | file->f_pos = next; | 300 | file->f_pos = next; |
300 | } | 301 | } |
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c index dd7bc38a3825..a74ad0d371c2 100644 --- a/fs/hostfs/hostfs_user.c +++ b/fs/hostfs/hostfs_user.c | |||
@@ -98,7 +98,8 @@ void *open_dir(char *path, int *err_out) | |||
98 | } | 98 | } |
99 | 99 | ||
100 | char *read_dir(void *stream, unsigned long long *pos, | 100 | char *read_dir(void *stream, unsigned long long *pos, |
101 | unsigned long long *ino_out, int *len_out) | 101 | unsigned long long *ino_out, int *len_out, |
102 | unsigned int *type_out) | ||
102 | { | 103 | { |
103 | DIR *dir = stream; | 104 | DIR *dir = stream; |
104 | struct dirent *ent; | 105 | struct dirent *ent; |
@@ -109,6 +110,7 @@ char *read_dir(void *stream, unsigned long long *pos, | |||
109 | return NULL; | 110 | return NULL; |
110 | *len_out = strlen(ent->d_name); | 111 | *len_out = strlen(ent->d_name); |
111 | *ino_out = ent->d_ino; | 112 | *ino_out = ent->d_ino; |
113 | *type_out = ent->d_type; | ||
112 | *pos = telldir(dir); | 114 | *pos = telldir(dir); |
113 | return ent->d_name; | 115 | return ent->d_name; |
114 | } | 116 | } |