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,
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);
......
......@@ -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;
......
......@@ -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);
......
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