aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert@linux-m68k.org>2012-01-27 13:14:58 -0500
committerRichard Weinberger <richard@nod.at>2012-03-24 19:29:52 -0400
commit3ee6bd8e8dc0c58b9ba5bab7ef8a7a131da346eb (patch)
treeb1050db82803495116ac255a2b6c755622bd1044 /fs
parentc0b79a90b1556a7e51d7a49a655eb60306f6258d (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')
-rw-r--r--fs/hostfs/hostfs.h3
-rw-r--r--fs/hostfs/hostfs_kern.c5
-rw-r--r--fs/hostfs/hostfs_user.c4
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);
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 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);
71extern void close_file(void *stream); 72extern void close_file(void *stream);
72extern int replace_file(int oldfd, int fd); 73extern int replace_file(int oldfd, int fd);
73extern void close_dir(void *stream); 74extern 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
100char *read_dir(void *stream, unsigned long long *pos, 100char *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}