/*
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*
* Ported the filesystem routines to 2.5.
* 2003-02-10 Petr Baudis <pasky@ucw.cz>
*/
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/statfs.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
#include "hostfs.h"
#include "init.h"
#include "kern.h"
struct hostfs_inode_info {
char *host_filename;
int fd;
fmode_t mode;
struct inode vfs_inode;
};
static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
{
return list_entry(inode, struct hostfs_inode_info, vfs_inode);
}
#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_path.dentry->d_inode)
static int hostfs_d_delete(struct dentry *dentry)
{
return 1;
}
static const struct dentry_operations hostfs_dentry_ops = {
.d_delete = hostfs_d_delete,
};
/* Changed in hostfs_args before the kernel starts running */
static char *root_ino = "";
static int append = 0;
#define HOSTFS_SUPER_MAGIC 0x00c0ffee
static const struct inode_operations hostfs_iops;
static const struct inode_operations hostfs_dir_iops;
static const struct address_space_operations hostfs_link_aops;
#ifndef MODULE
static int __init hostfs_args(char *options, int *add)
{
char *ptr;
ptr = strchr(options, ',');
if (ptr != NULL)
*ptr++ = '\0';
if (*options != '\0')
root_ino = options;
options = ptr;
while (options) {
ptr = strchr(options, ',');
if (ptr != NULL)
*ptr++ = '\0';
if (*options != '\0') {
if (!strcmp(options, "append"))
append = 1;
else printf("hostfs_args - unsupported option - %s\n",
options);
}
options = ptr;
}
return 0;
}
__uml_setup("hostfs=", hostfs_args,
"hostfs=<root dir>,<flags>,...\n"
" This is used to set hostfs parameters. The root directory argument\n"
" is used to confine all hostfs mounts to within the specified directory\n"
" tree on the host. If this isn't specified, then a user inside UML can\n"
" mount anything on the host that's accessible to the user that's running\n"
" it.\n"
" The only flag currently supported is 'append', which specifies that all\n"
" files opened by hostfs will be opened in append mode.\n\n"
);
#endif
static char *dentry_name(struct dentry *dentry, int extra)
{
struct dentry *parent;
char *root, *name;
int len;
len = 0;
parent = dentry;
while (parent->d_parent != parent) {
len += parent->d_name.len + 1;
parent = parent->d_parent;
}
root = HOSTFS_I(parent->d_inode)->host_filename;
len += strlen(root);
name = kmalloc(len + extra + 1, GFP_KERNEL);
if (name == NULL)
return NULL;
name[len] = '\0';
parent = dentry;
while (parent->d_parent != parent) {
len -= parent->d_name.len + 1;
name[len] = '/';
strncpy(&name[len + 1], parent->d_name.name,
parent->d_name.len);
parent = parent->d_parent;
}
strncpy(name, root, strlen(root));
return name;
}
static char *inode_name(struct inode *ino, int extra)
{
struct dentry *dentry;
dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
return dentry_name(dentry, extra);
}
static int read_name(struct inode *ino, char *name)
{