/*
 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
 * Licensed under the GPL
 *
 * Ported the filesystem routines to 2.5.
 * 2003-02-10 Petr Baudis <pasky@ucw.cz>
 */

#include <linux/stddef.h>
#include <linux/fs.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/blkdev.h>
#include <linux/list.h>
#include <linux/statfs.h>
#include <linux/kdev_t.h>
#include <asm/uaccess.h>
#include "hostfs.h"
#include "kern_util.h"
#include "kern.h"
#include "user_util.h"
#include "init.h"

struct hostfs_inode_info {
	char *host_filename;
	int fd;
	int 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_dentry->d_inode)

int hostfs_d_delete(struct dentry *dentry)
{
	return(1);
}

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 struct inode_operations hostfs_iops;
static struct inode_operations hostfs_dir_iops;
static 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)
{
	/* The non-int inode fields are copied into ints by stat_file and
	 * then copied into the inode because passing the actual pointers
	 * in and having them treated as int * breaks on big-endian machines
	 */
	int err;
	int i_mode, i_nlink, i_blksize;
	unsigned long long i_size;
	unsigned long long i_ino;
	unsigned long long i_blocks;

	err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid,
			&ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime,
			&ino->i_ctime, &i_blksize, &i_blocks);
	if(err)
		return(err);

	ino->i_ino = i_ino;
	ino->i_mode = i_mode;
	ino->i_nlink = i_nlink;
	ino->i_size = i_size;
	ino->i_blksize = i_blksize;
	ino->i_blocks = i_blocks;
	return(0);
}

static char *follow_link(char *link)
{
	int len, n;
	char *name, *resolved, *end;

	len = 64;
	while(1){
		n = -ENOMEM;
		name = kmalloc(len, GFP_KERNEL);
		if(name == NULL)
			goto out;

		n = do_readlink(link, name, len);
		if(n < len)
			break;
		len *= 2;
		kfree(name);
	}
	if(n < 0)
		goto out_free;

	if(*name == '/')
		return(name);

	end = strrchr(link, '/');
	if(end == NULL)
		return(name);

	*(end + 1) = '\0';
	len = strlen(link) + strlen(name) + 1;

	resolved = kmalloc(len, GFP_KERNEL);
	if(resolved == NULL){
		n = -ENOMEM;
		goto out_free;
	}

	sprintf(resolved, "%s%s", link, name);
	kfree(name);
	kfree(link);
	return(resolved);

 out_free:
	kfree(name);
 out:
	return(ERR_PTR(n));
}

static int read_inode(struct inode *ino)
{
	char *name;
	int err = 0;

	/* Unfortunately, we are called from iget() when we don't have a dentry
	 * allocated yet.
	 */
	if(list_empty(&ino->i_dentry))
		goto out;

	err = -ENOMEM;
	name = inode_name(ino, 0);
	if(name == NULL)
		goto out;

	if(file_type(name, NULL, NULL) == OS_TYPE_SYMLINK){
		name = follow_link(name);
		if(IS_ERR(name)){
			err = PTR_ERR(name);
			goto out;
		}
	}

	err = read_name(ino, name);
	kfree(name);
 out:
	return(err);
}

int hostfs_statfs(struct super_block *sb, struct kstatfs *sf)
{
	/* do_statfs uses struct statfs64 internally, but the linux kernel
	 * struct statfs still has 32-bit versions for most of these fields,
	 * so we convert them here
	 */
	int err;
	long long f_blocks;
	long long f_bfree;
	long long f_bavail;
	long long f_files;
	long long f_ffree;

	err = do_statfs(HOSTFS_I(sb->s_root->d_inode)->host_filename,
			&sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
			&f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
			&sf->f_namelen, sf->f_spare);
	if(err) return(err);
	sf->f_blocks = f_blocks;
	sf->f_bfree = f_bfree;
	sf->f_bavail = f_bavail;
	sf->f_files = f_files;
	sf->f_ffree = f_ffree;
	sf->f_type = HOSTFS_SUPER_MAGIC;
	return(0);
}

static struct inode *hostfs_alloc_inode(struct super_block *sb)
{
	struct hostfs_inode_info *hi;

	hi = kmalloc(sizeof(*hi), GFP_KERNEL);
	if(hi == NULL)
		return(NULL);

	*hi = ((struct hostfs_inode_info) { .host_filename	= NULL,
					    .fd			= -1,
					    .mode		= 0 });
	inode_init_once(&hi->vfs_inode);
	return(&hi->vfs_inode);
}

static void hostfs_delete_inode(struct inode *inode)
{
	if(HOSTFS_I(inode)->fd != -1) {
		close_file(&HOSTFS_I(inode)->fd);
		HOSTFS_I(inode)->fd = -1;
	}
	clear_inode(inode);
}

static void hostfs_destroy_inode(struct inode *inode)
{
	if(HOSTFS_I(inode)->host_filename)
		kfree(HOSTFS_I(inode)->host_filename);

	/*XXX: This should not happen, probably. The check is here for
	 * additional safety.*/
	if(HOSTFS_I(inode)->fd != -1) {
		close_file(&HOSTFS_I(inode)->fd);
		printk(KERN_DEBUG "Closing host fd in .destroy_inode\n");
	}

	kfree(HOSTFS_I(inode));
}

static void hostfs_read_inode(struct inode *inode)
{
	read_inode(inode);
}

static struct super_operations hostfs_sbops = {
	.alloc_inode	= hostfs_alloc_inode,
	.drop_inode	= generic_delete_inode,
	.delete_inode   = hostfs_delete_inode,
	.destroy_inode	= hostfs_destroy_inode,
	.read_inode	= hostfs_read_inode,
	.statfs		= hostfs_statfs,
};

int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
{
	void *dir;
	char *name;
	unsigned long long next, ino;
	int error, len;

	name = dentry_name(file->f_dentry, 0);
	if(name == NULL) return(-ENOMEM);
	dir = open_dir(name, &error);
	kfree(name);
	if(dir == NULL) return(-error);
	next = file->f_pos;
	while((name = read_dir(dir, &next, &ino, &len)) != NULL){
		error = (*filldir)(ent, name, len, file->f_pos,
				   ino, DT_UNKNOWN);
		if(error) break;
		file->f_pos = next;
	}
	close_dir(dir);
	return(0);
}

int hostfs_file_open(struct inode *ino, struct file *file)
{
	char *name;
	int mode = 0, r = 0, w = 0, fd;

	mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
	if((mode & HOSTFS_I(ino)->mode) == mode)
		return(0);

	/* The file may already have been opened, but with the wrong access,
	 * so this resets things and reopens the file with the new access.
	 */
	if(HOSTFS_I(ino)->fd != -1){
		close_file(&HOSTFS_I(ino)->fd);
		HOSTFS_I(ino)->fd = -1;
	}

	HOSTFS_I(ino)->mode |= mode;
	if(HOSTFS_I(ino)->mode & FMODE_READ)
		r = 1;
	if(HOSTFS_I(ino)->mode & FMODE_WRITE)
		w = 1;
	if(w)
		r = 1;

	name = dentry_name(file->f_dentry, 0);
	if(name == NULL)
		return(-ENOMEM);

	fd = open_file(name, r, w, append);
	kfree(name);
	if(fd < 0) return(fd);
	FILE_HOSTFS_I(file)->fd = fd;

	return(0);
}

int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
{
	return(0);
}

static struct file_operations hostfs_file_fops = {
	.llseek		= generic_file_llseek,
	.read		= generic_file_read,
	.sendfile	= generic_file_sendfile,
	.aio_read	= generic_file_aio_read,
	.aio_write	= generic_file_aio_write,
	.readv		= generic_file_readv,
	.writev		= generic_file_writev,
	.write		= generic_file_write,
	.mmap		= generic_file_mmap,
	.open		= hostfs_file_open,
	.release	= NULL,
	.fsync		= hostfs_fsync,
};

static struct file_operations hostfs_dir_fops = {
	.llseek		= generic_file_llseek,
	.readdir	= hostfs_readdir,
	.read		= generic_read_dir,
};

int hostfs_writepage(struct page *page, struct writeback_control *wbc)
{
	struct address_space *mapping = page->mapping;
	struct inode *inode = mapping->host;
	char *buffer;
	unsigned long long base;
	int count = PAGE_CACHE_SIZE;
	int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
	int err;

	if (page->index >= end_index)
		count = inode->i_size & (PAGE_CACHE_SIZE-1);

	buffer = kmap(page);
	base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;

	err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
	if(err != count){
		ClearPageUptodate(page);
		goto out;
	}

	if (base > inode->i_size)
		inode->i_size = base;

	if (PageError(page))
		ClearPageError(page);
	err = 0;

 out:
	kunmap(page);

	unlock_page(page);
	return err;
}

int hostfs_readpage(struct file *file, struct page *page)
{
	char *buffer;
	long long start;
	int err = 0;

	start = (long long) page->index << PAGE_CACHE_SHIFT;
	buffer = kmap(page);
	err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
			PAGE_CACHE_SIZE);
	if(err < 0) goto out;

	memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);

	flush_dcache_page(page);
	SetPageUptodate(page);
	if (PageError(page)) ClearPageError(page);
	err = 0;
 out:
	kunmap(page);
	unlock_page(page);
	return(err);
}

int hostfs_prepare_write(struct file *file, struct page *page,
			 unsigned int from, unsigned int to)
{
	char *buffer;
	long long start, tmp;
	int err;

	start = (long long) page->index << PAGE_CACHE_SHIFT;
	buffer = kmap(page);
	if(from != 0){
		tmp = start;
		err = read_file(FILE_HOSTFS_I(file)->fd, &tmp, buffer,
				from);
		if(err < 0) goto out;
	}
	if(to != PAGE_CACHE_SIZE){
		start += to;
		err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer + to,
				PAGE_CACHE_SIZE - to);
		if(err < 0) goto out;
	}
	err = 0;
 out:
	kunmap(page);
	return(err);
}

int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
		 unsigned to)
{
	struct address_space *mapping = page->mapping;
	struct inode *inode = mapping->host;
	char *buffer;
	long long start;
	int err = 0;

	start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
	buffer = kmap(page);
	err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from,
			 to - from);
	if(err > 0) err = 0;
	if(!err && (start > inode->i_size))
		inode->i_size = start;

	kunmap(page);
	return(err);
}

static struct address_space_operations hostfs_aops = {
	.writepage 	= hostfs_writepage,
	.readpage	= hostfs_readpage,
	.set_page_dirty = __set_page_dirty_nobuffers,
	.prepare_write	= hostfs_prepare_write,
	.commit_write	= hostfs_commit_write
};

static int init_inode(struct inode *inode, struct dentry *dentry)
{
	char *name;
	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, &maj, &min);
		/*Reencode maj and min with the kernel encoding.*/
		rdev = MKDEV(maj, min);
		kfree(name);
	}
	else type = OS_TYPE_DIR;

	err = 0;
	if(type == OS_TYPE_SYMLINK)
		inode->i_op = &page_symlink_inode_operations;
	else if(type == OS_TYPE_DIR)
		inode->i_op = &hostfs_dir_iops;
	else inode->i_op = &hostfs_iops;

	if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
	else inode->i_fop = &hostfs_file_fops;

	if(type == OS_TYPE_SYMLINK)
		inode->i_mapping->a_ops = &hostfs_link_aops;
	else inode->i_mapping->a_ops = &hostfs_aops;

	switch (type) {
	case OS_TYPE_CHARDEV:
		init_special_inode(inode, S_IFCHR, rdev);
		break;
	case OS_TYPE_BLOCKDEV:
		init_special_inode(inode, S_IFBLK, rdev);
		break;
	case OS_TYPE_FIFO:
		init_special_inode(inode, S_IFIFO, 0);
		break;
	case OS_TYPE_SOCK:
		init_special_inode(inode, S_IFSOCK, 0);
		break;
	}
 out:
	return(err);
}

int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
                 struct nameidata *nd)
{
	struct inode *inode;
	char *name;
	int error, fd;

	error = -ENOMEM;
	inode = iget(dir->i_sb, 0);
	if(inode == NULL) goto out;

	error = init_inode(inode, dentry);
	if(error)
		goto out_put;

	error = -ENOMEM;
	name = dentry_name(dentry, 0);
	if(name == NULL)
		goto out_put;

	fd = file_create(name,
			 mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR,
			 mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP,
			 mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
	if(fd < 0)
		error = fd;
	else error = read_name(inode, name);

	kfree(name);
	if(error)
		goto out_put;

	HOSTFS_I(inode)->fd = fd;
	HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
	d_instantiate(dentry, inode);
	return(0);

 out_put:
	iput(inode);
 out:
	return(error);
}

struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
                            struct nameidata *nd)
{
	struct inode *inode;
	char *name;
	int err;

	err = -ENOMEM;
	inode = iget(ino->i_sb, 0);
	if(inode == NULL)
		goto out;

	err = init_inode(inode, dentry);
	if(err)
		goto out_put;

	err = -ENOMEM;
	name = dentry_name(dentry, 0);
	if(name == NULL)
		goto out_put;

	err = read_name(inode, name);
	kfree(name);
	if(err == -ENOENT){
		iput(inode);
		inode = NULL;
	}
	else if(err)
		goto out_put;

	d_add(dentry, inode);
	dentry->d_op = &hostfs_dentry_ops;
	return(NULL);

 out_put:
	iput(inode);
 out:
	return(ERR_PTR(err));
}

static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
{
        char *file;
	int len;

	file = inode_name(ino, dentry->d_name.len + 1);
	if(file == NULL) return(NULL);
        strcat(file, "/");
	len = strlen(file);
        strncat(file, dentry->d_name.name, dentry->d_name.len);
	file[len + dentry->d_name.len] = '\0';
        return(file);
}

int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
{
        char *from_name, *to_name;
        int err;

        if((from_name = inode_dentry_name(ino, from)) == NULL)
                return(-ENOMEM);
        to_name = dentry_name(to, 0);
	if(to_name == NULL){
		kfree(from_name);
		return(-ENOMEM);
	}
        err = link_file(to_name, from_name);
        kfree(from_name);
        kfree(to_name);
        return(err);
}

int hostfs_unlink(struct inode *ino, struct dentry *dentry)
{
	char *file;
	int err;

	if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
	if(append)
		return(-EPERM);

	err = unlink_file(file);
	kfree(file);
	return(err);
}

int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
{
	char *file;
	int err;

	if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
	err = make_symlink(file, to);
	kfree(file);
	return(err);
}

int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
{
	char *file;
	int err;

	if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
	err = do_mkdir(file, mode);
	kfree(file);
	return(err);
}

int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
{
	char *file;
	int err;

	if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
	err = do_rmdir(file);
	kfree(file);
	return(err);
}

int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
{
	struct inode *inode;
	char *name;
	int err = -ENOMEM;

	inode = iget(dir->i_sb, 0);
	if(inode == NULL)
		goto out;

	err = init_inode(inode, dentry);
	if(err)
		goto out_put;

	err = -ENOMEM;
	name = dentry_name(dentry, 0);
	if(name == NULL)
		goto out_put;

	init_special_inode(inode, mode, dev);
	err = do_mknod(name, mode, dev);
	if(err)
		goto out_free;

	err = read_name(inode, name);
	kfree(name);
	if(err)
		goto out_put;

	d_instantiate(dentry, inode);
	return(0);

 out_free:
	kfree(name);
 out_put:
	iput(inode);
 out:
	return(err);
}

int hostfs_rename(struct inode *from_ino, struct dentry *from,
		  struct inode *to_ino, struct dentry *to)
{
	char *from_name, *to_name;
	int err;

	if((from_name = inode_dentry_name(from_ino, from)) == NULL)
		return(-ENOMEM);
	if((to_name = inode_dentry_name(to_ino, to)) == NULL){
		kfree(from_name);
		return(-ENOMEM);
	}
	err = rename_file(from_name, to_name);
	kfree(from_name);
	kfree(to_name);
	return(err);
}

void hostfs_truncate(struct inode *ino)
{
	not_implemented();
}

int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
{
	char *name;
	int r = 0, w = 0, x = 0, err;

	if (desired & MAY_READ) r = 1;
	if (desired & MAY_WRITE) w = 1;
	if (desired & MAY_EXEC) x = 1;
	name = inode_name(ino, 0);
	if (name == NULL) return(-ENOMEM);

	if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) ||
			S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
		err = 0;
	else
		err = access_file(name, r, w, x);
	kfree(name);
	if(!err)
		err = generic_permission(ino, desired, NULL);
	return err;
}

int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
{
	struct hostfs_iattr attrs;
	char *name;
	int err;

	err = inode_change_ok(dentry->d_inode, attr);
	if (err)
		return err;

	if(append)
		attr->ia_valid &= ~ATTR_SIZE;

	attrs.ia_valid = 0;
	if(attr->ia_valid & ATTR_MODE){
		attrs.ia_valid |= HOSTFS_ATTR_MODE;
		attrs.ia_mode = attr->ia_mode;
	}
	if(attr->ia_valid & ATTR_UID){
		attrs.ia_valid |= HOSTFS_ATTR_UID;
		attrs.ia_uid = attr->ia_uid;
	}
	if(attr->ia_valid & ATTR_GID){
		attrs.ia_valid |= HOSTFS_ATTR_GID;
		attrs.ia_gid = attr->ia_gid;
	}
	if(attr->ia_valid & ATTR_SIZE){
		attrs.ia_valid |= HOSTFS_ATTR_SIZE;
		attrs.ia_size = attr->ia_size;
	}
	if(attr->ia_valid & ATTR_ATIME){
		attrs.ia_valid |= HOSTFS_ATTR_ATIME;
		attrs.ia_atime = attr->ia_atime;
	}
	if(attr->ia_valid & ATTR_MTIME){
		attrs.ia_valid |= HOSTFS_ATTR_MTIME;
		attrs.ia_mtime = attr->ia_mtime;
	}
	if(attr->ia_valid & ATTR_CTIME){
		attrs.ia_valid |= HOSTFS_ATTR_CTIME;
		attrs.ia_ctime = attr->ia_ctime;
	}
	if(attr->ia_valid & ATTR_ATIME_SET){
		attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
	}
	if(attr->ia_valid & ATTR_MTIME_SET){
		attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
	}
	name = dentry_name(dentry, 0);
	if(name == NULL) return(-ENOMEM);
	err = set_attr(name, &attrs);
	kfree(name);
	if(err)
		return(err);

	return(inode_setattr(dentry->d_inode, attr));
}

int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
	   struct kstat *stat)
{
	generic_fillattr(dentry->d_inode, stat);
	return(0);
}

static struct inode_operations hostfs_iops = {
	.create		= hostfs_create,
	.link		= hostfs_link,
	.unlink		= hostfs_unlink,
	.symlink	= hostfs_symlink,
	.mkdir		= hostfs_mkdir,
	.rmdir		= hostfs_rmdir,
	.mknod		= hostfs_mknod,
	.rename		= hostfs_rename,
	.truncate	= hostfs_truncate,
	.permission	= hostfs_permission,
	.setattr	= hostfs_setattr,
	.getattr	= hostfs_getattr,
};

static struct inode_operations hostfs_dir_iops = {
	.create		= hostfs_create,
	.lookup		= hostfs_lookup,
	.link		= hostfs_link,
	.unlink		= hostfs_unlink,
	.symlink	= hostfs_symlink,
	.mkdir		= hostfs_mkdir,
	.rmdir		= hostfs_rmdir,
	.mknod		= hostfs_mknod,
	.rename		= hostfs_rename,
	.truncate	= hostfs_truncate,
	.permission	= hostfs_permission,
	.setattr	= hostfs_setattr,
	.getattr	= hostfs_getattr,
};

int hostfs_link_readpage(struct file *file, struct page *page)
{
	char *buffer, *name;
	long long start;
	int err;

	start = page->index << PAGE_CACHE_SHIFT;
	buffer = kmap(page);
	name = inode_name(page->mapping->host, 0);
	if(name == NULL) return(-ENOMEM);
	err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
	kfree(name);
	if(err == PAGE_CACHE_SIZE)
		err = -E2BIG;
	else if(err > 0){
		flush_dcache_page(page);
		SetPageUptodate(page);
		if (PageError(page)) ClearPageError(page);
		err = 0;
	}
	kunmap(page);
	unlock_page(page);
	return(err);
}

static struct address_space_operations hostfs_link_aops = {
	.readpage	= hostfs_link_readpage,
};

static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
{
	struct inode *root_inode;
	char *name, *data = d;
	int err;

	sb->s_blocksize = 1024;
	sb->s_blocksize_bits = 10;
	sb->s_magic = HOSTFS_SUPER_MAGIC;
	sb->s_op = &hostfs_sbops;

	if((data == NULL) || (*data == '\0'))
		data = root_ino;

	err = -ENOMEM;
	name = kmalloc(strlen(data) + 1, GFP_KERNEL);
	if(name == NULL)
		goto out;

	strcpy(name, data);

	root_inode = iget(sb, 0);
	if(root_inode == NULL)
		goto out_free;

	err = init_inode(root_inode, NULL);
	if(err)
		goto out_put;

	HOSTFS_I(root_inode)->host_filename = name;

	err = -ENOMEM;
	sb->s_root = d_alloc_root(root_inode);
	if(sb->s_root == NULL)
		goto out_put;

	err = read_inode(root_inode);
	if(err){
                /* No iput in this case because the dput does that for us */
                dput(sb->s_root);
                sb->s_root = NULL;
		goto out_free;
        }

	return(0);

 out_put:
        iput(root_inode);
 out_free:
	kfree(name);
 out:
	return(err);
}

static struct super_block *hostfs_read_sb(struct file_system_type *type,
					     int flags, const char *dev_name,
					     void *data)
{
	return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common));
}

static struct file_system_type hostfs_type = {
	.owner 		= THIS_MODULE,
	.name 		= "hostfs",
	.get_sb 	= hostfs_read_sb,
	.kill_sb	= kill_anon_super,
	.fs_flags 	= 0,
};

static int __init init_hostfs(void)
{
	return(register_filesystem(&hostfs_type));
}

static void __exit exit_hostfs(void)
{
	unregister_filesystem(&hostfs_type);
}

module_init(init_hostfs)
module_exit(exit_hostfs)
MODULE_LICENSE("GPL");

/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * Emacs will notice this stuff at the end of the file and automatically
 * adjust the settings for this buffer only.  This must remain at the end
 * of the file.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-file-style: "linux"
 * End:
 */
