uml/hostfs: Propagate dirent.d_type to filldir()
authorGeert Uytterhoeven <geert@linux-m68k.org>
Fri, 27 Jan 2012 18:14:58 +0000 (19:14 +0100)
committerRichard Weinberger <richard@nod.at>
Sat, 24 Mar 2012 23:29:52 +0000 (00:29 +0100)
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>
fs/hostfs/hostfs.h
fs/hostfs/hostfs_kern.c
fs/hostfs/hostfs_user.c

index 3cbfa93cd78243506e07f0f7480d73f2704b29bb..1fe731337f0790add39e1d4870f4d9bb8174fb8b 100644 (file)
@@ -67,7 +67,8 @@ 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,
-                     unsigned long long *ino_out, int *len_out);
+                     unsigned long long *ino_out, int *len_out,
+                     unsigned int *type_out);
 extern void close_file(void *stream);
 extern int replace_file(int oldfd, int fd);
 extern void close_dir(void *stream);
index e130bd46d671515762152d071194ce9e9a3bb4a6..dc4222bd6e776d17cde36ee72e74924a243ac5a8 100644 (file)
@@ -283,6 +283,7 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
        char *name;
        unsigned long long next, ino;
        int error, len;
+       unsigned int type;
 
        name = dentry_name(file->f_path.dentry);
        if (name == NULL)
@@ -292,9 +293,9 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
        if (dir == NULL)
                return -error;
        next = file->f_pos;
-       while ((name = read_dir(dir, &next, &ino, &len)) != NULL) {
+       while ((name = read_dir(dir, &next, &ino, &len, &type)) != NULL) {
                error = (*filldir)(ent, name, len, file->f_pos,
-                                  ino, DT_UNKNOWN);
+                                  ino, type);
                if (error) break;
                file->f_pos = next;
        }
index dd7bc38a38251e9c123b08e87d42477f44f302b5..a74ad0d371c2298b84b3dc735990d71ed68aede3 100644 (file)
@@ -98,7 +98,8 @@ void *open_dir(char *path, int *err_out)
 }
 
 char *read_dir(void *stream, unsigned long long *pos,
-              unsigned long long *ino_out, int *len_out)
+              unsigned long long *ino_out, int *len_out,
+              unsigned int *type_out)
 {
        DIR *dir = stream;
        struct dirent *ent;
@@ -109,6 +110,7 @@ char *read_dir(void *stream, unsigned long long *pos,
                return NULL;
        *len_out = strlen(ent->d_name);
        *ino_out = ent->d_ino;
+       *type_out = ent->d_type;
        *pos = telldir(dir);
        return ent->d_name;
 }