Commit d2a604d8 authored by Paolo \'Blaisorblade\' Giarrusso's avatar Paolo \'Blaisorblade\' Giarrusso Committed by Linus Torvalds

[PATCH] uml: fix major & minor handling in hostfs

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: default avatarPaolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 73e6b229
...@@ -38,7 +38,7 @@ extern int stat_file(const char *path, unsigned long long *inode_out, ...@@ -38,7 +38,7 @@ extern int stat_file(const char *path, unsigned long long *inode_out,
int *blksize_out, unsigned long long *blocks_out); int *blksize_out, unsigned long long *blocks_out);
extern int access_file(char *path, int r, int w, int x); 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 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 void *open_dir(char *path, int *err_out);
extern char *read_dir(void *stream, unsigned long long *pos, 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);
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/root_dev.h> #include <linux/root_dev.h>
#include <linux/statfs.h> #include <linux/statfs.h>
#include <linux/kdev_t.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "hostfs.h" #include "hostfs.h"
#include "kern_util.h" #include "kern_util.h"
...@@ -230,7 +231,7 @@ static int read_inode(struct inode *ino) ...@@ -230,7 +231,7 @@ static int read_inode(struct inode *ino)
if(name == NULL) if(name == NULL)
goto out; goto out;
if(file_type(name, NULL) == OS_TYPE_SYMLINK){ if(file_type(name, NULL, NULL) == OS_TYPE_SYMLINK){
name = follow_link(name); name = follow_link(name);
if(IS_ERR(name)){ if(IS_ERR(name)){
err = PTR_ERR(name); err = PTR_ERR(name);
...@@ -523,13 +524,17 @@ static struct address_space_operations hostfs_aops = { ...@@ -523,13 +524,17 @@ static struct address_space_operations hostfs_aops = {
static int init_inode(struct inode *inode, struct dentry *dentry) static int init_inode(struct inode *inode, struct dentry *dentry)
{ {
char *name; char *name;
int type, err = -ENOMEM, rdev; int type, err = -ENOMEM;
int maj, min;
dev_t rdev = 0;
if(dentry){ if(dentry){
name = dentry_name(dentry, 0); name = dentry_name(dentry, 0);
if(name == NULL) if(name == NULL)
goto out; 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); kfree(name);
} }
else type = OS_TYPE_DIR; else type = OS_TYPE_DIR;
......
...@@ -54,14 +54,18 @@ int stat_file(const char *path, unsigned long long *inode_out, int *mode_out, ...@@ -54,14 +54,18 @@ int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
return(0); return(0);
} }
int file_type(const char *path, int *rdev) int file_type(const char *path, int *maj, int *min)
{ {
struct stat64 buf; struct stat64 buf;
if(lstat64(path, &buf) < 0) if(lstat64(path, &buf) < 0)
return(-errno); return(-errno);
if(rdev != NULL) /*We cannot pass rdev as is because glibc and the kernel disagree
*rdev = buf.st_rdev; *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); if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK); else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment