]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] uml: fix major & minor handling in hostfs
authorPaolo \'Blaisorblade\' Giarrusso <blaisorblade_spam@yahoo.it>
Fri, 8 Oct 2004 00:35:15 +0000 (17:35 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Fri, 8 Oct 2004 00:35:15 +0000 (17:35 -0700)
Currently hostfs passes the rdev value from stat() on the host as rdev
value to return to stat() on the guest; but we cannot pass rdev as is
because glibc and the kernel disagree about its definition.  So we must
decode it in a major/minor couple with glibc macros and re-encode it in
kernelspace code.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
fs/hostfs/hostfs.h
fs/hostfs/hostfs_kern.c
fs/hostfs/hostfs_user.c

index da7849df52b329569bfb69bbf93d07b270a48a63..416761fce324c2b93fd4a5624d6ff619fada3543 100644 (file)
@@ -38,7 +38,7 @@ extern int stat_file(const char *path, unsigned long long *inode_out,
                     int *blksize_out, unsigned long long *blocks_out);
 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 int file_type(const char *path, int *rdev);
+extern int file_type(const char *path, int *maj, int *min);
 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);
index bca1dc8f38f2114ed2c2edeee7dd585f45e72d31..7d42da0a304d46b6f6c7338353584ffe49f88e14 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/buffer_head.h>
 #include <linux/root_dev.h>
 #include <linux/statfs.h>
+#include <linux/kdev_t.h>
 #include <asm/uaccess.h>
 #include "hostfs.h"
 #include "kern_util.h"
@@ -230,7 +231,7 @@ static int read_inode(struct inode *ino)
        if(name == NULL)
                goto out;
 
-       if(file_type(name, NULL) == OS_TYPE_SYMLINK){
+       if(file_type(name, NULL, NULL) == OS_TYPE_SYMLINK){
                name = follow_link(name);
                if(IS_ERR(name)){
                        err = PTR_ERR(name);
@@ -523,13 +524,17 @@ static struct address_space_operations hostfs_aops = {
 static int init_inode(struct inode *inode, struct dentry *dentry)
 {
        char *name;
-       int type, err = -ENOMEM, rdev;
+       int type, err = -ENOMEM;
+       int maj, min;
+       dev_t rdev = 0;
 
        if(dentry){
                name = dentry_name(dentry, 0);
                if(name == NULL)
                        goto out;
-               type = file_type(name, &rdev);
+               type = file_type(name, &maj, &min);
+               /*Reencode maj and min with the kernel encoding.*/
+               rdev = MKDEV(maj, min);
                kfree(name);
        }
        else type = OS_TYPE_DIR;
index 31ae92babf318b12517e9cbbc3b6fad110a21180..16974dc07e5a6c5dd1a5ec91832b52848f24814c 100644 (file)
@@ -54,14 +54,18 @@ int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
        return(0);
 }
 
-int file_type(const char *path, int *rdev)
+int file_type(const char *path, int *maj, int *min)
 {
        struct stat64 buf;
 
        if(lstat64(path, &buf) < 0)
                return(-errno);
-       if(rdev != NULL)
-               *rdev = buf.st_rdev;
+       /*We cannot pass rdev as is because glibc and the kernel disagree
+        *about its definition.*/
+       if(maj != NULL)
+               *maj = major(buf.st_rdev);
+       if(min != NULL)
+               *min = minor(buf.st_rdev);
 
        if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
        else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);