/*
 *  inode.c
 *
 *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
 *  Copyright (C) 1997 by Volker Lendecke
 *
 *  Please add a note about your changes to smbfs in the ChangeLog file.
 */

#include <linux/module.h>
#include <linux/time.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/file.h>
#include <linux/dcache.h>
#include <linux/smp_lock.h>
#include <linux/nls.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
#include <linux/net.h>
#include <linux/vfs.h>
#include <linux/highuid.h>
#include <linux/sched.h>
#include <linux/smb_fs.h>
#include <linux/smbno.h>
#include <linux/smb_mount.h>

#include <asm/system.h>
#include <asm/uaccess.h>

#include "smb_debug.h"
#include "getopt.h"
#include "proto.h"

/* Always pick a default string */
#ifdef CONFIG_SMB_NLS_REMOTE
#define SMB_NLS_REMOTE CONFIG_SMB_NLS_REMOTE
#else
#define SMB_NLS_REMOTE ""
#endif

#define SMB_TTL_DEFAULT 1000

static void smb_delete_inode(struct inode *);
static void smb_put_super(struct super_block *);
static int  smb_statfs(struct dentry *, struct kstatfs *);
static int  smb_show_options(struct seq_file *, struct vfsmount *);

static struct kmem_cache *smb_inode_cachep;

static struct inode *smb_alloc_inode(struct super_block *sb)
{
	struct smb_inode_info *ei;
	ei = (struct smb_inode_info *)kmem_cache_alloc(smb_inode_cachep, GFP_KERNEL);
	if (!ei)
		return NULL;
	return &ei->vfs_inode;
}

static void smb_destroy_inode(struct inode *inode)
{
	kmem_cache_free(smb_inode_cachep, SMB_I(inode));
}

static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
{
	struct smb_inode_info *ei = (struct smb_inode_info *) foo;

	inode_init_once(&ei->vfs_inode);
}
 
static int init_inodecache(void)
{
	smb_inode_cachep = kmem_cache_create("smb_inode_cache",
					     sizeof(struct smb_inode_info),
					     0, (SLAB_RECLAIM_ACCOUNT|
						SLAB_MEM_SPREAD),
					     init_once, NULL);
	if (smb_inode_cachep == NULL)
		return -ENOMEM;
	return 0;
}

static void destroy_inodecache(void)
{
	kmem_cache_destroy(smb_inode_cachep);
}

static int smb_remount(struct super_block *sb, int *flags, char *data)
{
	*flags |= MS_NODIRATIME;
	return 0;
}

static const struct super_operations smb_sops =
{
	.alloc_inode	= smb_alloc_inode,
	.destroy_inode	= smb_destroy_inode,
	.drop_inode	= generic_delete_inode,
	.delete_inode	= smb_delete_inode,
	.put_super	= smb_put_super,
	.statfs		= smb_statfs,
	.show_options	= smb_show_options,
	.remount_fs	= smb_remount,
};


/* We are always generating a new inode here */
struct inode *
smb_iget(struct super_block *sb, struct smb_fattr *fattr)
{
	struct smb_sb_info *server = SMB_SB(sb);
	struct inode *result;

	DEBUG1("smb_iget: %p\n", fattr);

	result = new_inode(sb);
	if (!result)
		return result;
	result->i_ino = fattr->f_ino;
	SMB_I(result)->open = 0;
	SMB_I(result)->fileid = 0;
	SMB_I(result)->access = 0;
	SMB_I(result)->flags = 0;
	SMB_I(result)->closed = 0;
	SMB_I(result)->openers = 0;
	smb_set_inode_attr(result, fattr);
	if (S_ISREG(result->i_mode)) {
		result->i_op = &smb_file_inode_operations;
		result->i_fop = &smb_file_operations;
		result->i_data.a_ops = &smb_file_aops;
	} else if (S_ISDIR(result->i_mode)) {
		if (server->opt.capabilities & SMB_CAP_UNIX)
			result->i_op = &smb_dir_inode_operations_unix;
		else
			result->i_op = &smb_dir_inode_operations;
		result->i_fop = &smb_dir_operations;
	} else if (S_ISLNK(result->i_mode)) {
		result->i_op = &smb_link_inode_operations;
	} else {
		init_special_inode(result, result->i_mode, fattr->f_rdev);
	}
	insert_inode_hash(result);
	return result;
}

/*
 * Copy the inode data to a smb_fattr structure.
 */
void
smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr)
{
	memset(fattr, 0, sizeof(struct smb_fattr));
	fattr->f_mode	= inode->i_mode;
	fattr->f_nlink	= inode->i_nlink;
	fattr->f_ino	= inode->i_ino;
	fattr->f_uid	= inode->i_uid;
	fattr->f_gid	= inode->i_gid;
	fattr->f_size	= inode->i_size;
	fattr->f_mtime	= inode->i_mtime;
	fattr->f_ctime	= inode->i_ctime;
	fattr->f_atime	= inode->i_atime;
	fattr->f_blocks	= inode->i_blocks;

	fattr->attr	= SMB_I(inode)->attr;
	/*
	 * Keep the attributes in sync with the inode permissions.
	 */
	if (fattr->f_mode & S_IWUSR)
		fattr->attr &= ~aRONLY;
	else
		fattr->attr |= aRONLY;
}

/*
 * Update the inode, possibly causing it to invalidate its pages if mtime/size
 * is different from last time.
 */
void
smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr)
{
	struct smb_inode_info *ei = SMB_I(inode);

	/*
	 * A size change should have a different mtime, or same mtime
	 * but different size.
	 */
	time_t last_time = inode->i_mtime.tv_sec;
	loff_t last_sz = inode->i_size;

	inode->i_mode	= fattr->f_mode;
	inode->i_nlink	= fattr->f_nlink;
	inode->i_uid	= fattr->f_uid;
	inode->i_gid	= fattr->f_gid;
	inode->i_ctime	= fattr->f_ctime;
	inode->i_blocks = fattr->f_blocks;
	inode->i_size	= fattr->f_size;
	inode->i_mtime	= fattr->f_mtime;
	inode->i_atime	= fattr->f_atime;
	ei->attr = fattr->attr;

	/*
	 * Update the "last time refreshed" field for revalidation.
	 */
	ei->oldmtime = jiffies;

	if (inode->i_mtime.tv_sec != last_time || inode->i_size != last_sz) {
		VERBOSE("%ld changed, old=%ld, new=%ld, oz=%ld, nz=%ld\n",
			inode->i_ino,
			(long) last_time, (long) inode->i_mtime.tv_sec,
			(long) last_sz, (long) inode->i_size);

		if (!S_ISDIR(inode->i_mode))
			invalidate_remote_inode(inode);
	}
}

/*
 * This is called if the connection has gone bad ...
 * try to kill off all the current inodes.
 */
void
smb_invalidate_inodes(struct smb_sb_info *server)
{
	VERBOSE("\n");
	shrink_dcache_sb(SB_of(server));
	invalidate_inodes(SB_of(server));
}

/*
 * This is called to update the inode attributes after
 * we've made changes to a file or directory.
 */
static int
smb_refresh_inode(struct dentry *dentry)
{
	struct inode *inode = dentry->d_inode;
	int error;
	struct smb_fattr fattr;

	error = smb_proc_getattr(dentry, &fattr);
	if (!error) {
		smb_renew_times(dentry);
		/*
		 * Check whether the type part of the mode changed,
		 * and don't update the attributes if it did.
		 *
		 * And don't dick with the root inode
		 */
		if (inode->i_ino == 2)
			return error;
		if (S_ISLNK(inode->i_mode))
			return error;	/* VFS will deal with it */

		if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT)) {
			smb_set_inode_attr(inode, &fattr);
		} else {
			/*
			 * Big trouble! The inode has become a new object,
			 * so any operations attempted on it are invalid.
			 *
			 * To limit damage, mark the inode as bad so that
			 * subsequent lookup validations will fail.
			 */
			PARANOIA("%s/%s changed mode, %07o to %07o\n",
				 DENTRY_PATH(dentry),
				 inode->i_mode, fattr.f_mode);

			fattr.f_mode = inode->i_mode; /* save mode */
			make_bad_inode(inode);
			inode->i_mode = fattr.f_mode; /* restore mode */
			/*
			 * No need to worry about unhashing the dentry: the
			 * lookup validation will see that the inode is bad.
			 * But we do want to invalidate the caches ...
			 */
			if (!S_ISDIR(inode->i_mode))
				invalidate_remote_inode(inode);
			else
				smb_invalid_dir_cache(inode);
			error = -EIO;
		}
	}
	return error;
}

/*
 * This is called when we want to check whether the inode
 * has changed on the server.  If it has changed, we must
 * invalidate our local caches.
 */
int
smb_revalidate_inode(struct dentry *dentry)
{
	struct smb_sb_info *s = server_from_dentry(dentry);
	struct inode *inode = dentry->d_inode;
	int error = 0;

	DEBUG1("smb_revalidate_inode\n");
	lock_kernel();

	/*
	 * Check whether we've recently refreshed the inode.
	 */
	if (time_before(jiffies, SMB_I(inode)->oldmtime + SMB_MAX_AGE(s))) {
		VERBOSE("up-to-date, ino=%ld, jiffies=%lu, oldtime=%lu\n",
			inode->i_ino, jiffies, SMB_I(inode)->oldmtime);
		goto out;
	}

	error = smb_refresh_inode(dentry);
out:
	unlock_kernel();
	return error;
}

/*
 * This routine is called when i_nlink == 0 and i_count goes to 0.
 * All blocking cleanup operations need to go here to avoid races.
 */
static void
smb_delete_inode(struct inode *ino)
{
	DEBUG1("ino=%ld\n", ino->i_ino);
	truncate_inode_pages(&ino->i_data, 0);
	lock_kernel();
	if (smb_close(ino))
		PARANOIA("could not close inode %ld\n", ino->i_ino);
	unlock_kernel();
	clear_inode(ino);
}

static struct option opts[] = {
	{ "version",	0, 'v' },
	{ "win95",	SMB_MOUNT_WIN95, 1 },
	{ "oldattr",	SMB_MOUNT_OLDATTR, 1 },
	{ "dirattr",	SMB_MOUNT_DIRATTR, 1 },
	{ "case",	SMB_MOUNT_CASE, 1 },
	{ "uid",	0, 'u' },
	{ "gid",	0, 'g' },
	{ "file_mode",	0, 'f' },
	{ "dir_mode",	0, 'd' },
	{ "iocharset",	0, 'i' },
	{ "codepage",	0, 'c' },
	{ "ttl",	0, 't' },
	{ NULL,		0, 0}
};

static int
parse_options(struct smb_mount_data_kernel *mnt, char *options)
{
	int c;
	unsigned long flags;
	unsigned long value;
	char *optarg;
	char *optopt;

	flags = 0;
	while ( (c = smb_getopt("smbfs", &options, opts,
				&optopt, &optarg, &flags, &value)) > 0) {

		VERBOSE("'%s' -> '%s'\n", optopt, optarg ? optarg : "<none>");
		switch (c) {
		case 1:
			/* got a "flag" option */
			break;
		case 'v':
			if (value != SMB_MOUNT_VERSION) {
			printk ("smbfs: Bad mount version %ld, expected %d\n",
				value, SMB_MOUNT_VERSION);
				return 0;
			}
			mnt->version = value;
			break;
		case 'u':
			mnt->uid = value;
			flags |= SMB_MOUNT_UID;
			break;
		case 'g':
			mnt->gid = value;
			flags |= SMB_MOUNT_GID;
			break;
		case 'f':
			mnt->file_mode = (value & S_IRWXUGO) | S_IFREG;
			flags |= SMB_MOUNT_FMODE;
			break;
		case 'd':
			mnt->dir_mode = (value & S_IRWXUGO) | S_IFDIR;
			flags |= SMB_MOUNT_DMODE;
			break;
		case 'i':
			strlcpy(mnt->codepage.local_name, optarg, 
				SMB_NLS_MAXNAMELEN);
			break;
		case 'c':
			strlcpy(mnt->codepage.remote_name, optarg,
				SMB_NLS_MAXNAMELEN);
			break;
		case 't':
			mnt->ttl = value;
			break;
		default:
			printk ("smbfs: Unrecognized mount option %s\n",
				optopt);
			return -1;
		}
	}
	mnt->flags = flags;
	return c;
}

/*
 * smb_show_options() is for displaying mount options in /proc/mounts.
 * It tries to avoid showing settings that were not changed from their
 * defaults.
 */
static int
smb_show_options(struct seq_file *s, struct vfsmount *m)
{
	struct smb_mount_data_kernel *mnt = SMB_SB(m->mnt_sb)->mnt;
	int i;

	for (i = 0; opts[i].name != NULL; i++)
		if (mnt->flags & opts[i].flag)
			seq_printf(s, ",%s", opts[i].name);

	if (mnt->flags & SMB_MOUNT_UID)
		seq_printf(s, ",uid=%d", mnt->uid);
	if (mnt->flags & SMB_MOUNT_GID)
		seq_printf(s, ",gid=%d", mnt->gid);
	if (mnt->mounted_uid != 0)
		seq_printf(s, ",mounted_uid=%d", mnt->mounted_uid);

	/* 
	 * Defaults for file_mode and dir_mode are unknown to us; they
	 * depend on the current umask of the user doing the mount.
	 */
	if (mnt->flags & SMB_MOUNT_FMODE)
		seq_printf(s, ",file_mode=%04o", mnt->file_mode & S_IRWXUGO);
	if (mnt->flags & SMB_MOUNT_DMODE)
		seq_printf(s, ",dir_mode=%04o", mnt->dir_mode & S_IRWXUGO);

	if (strcmp(mnt->codepage.local_name, CONFIG_NLS_DEFAULT))
		seq_printf(s, ",iocharset=%s", mnt->codepage.local_name);
	if (strcmp(mnt->codepage.remote_name, SMB_NLS_REMOTE))
		seq_printf(s, ",codepage=%s", mnt->codepage.remote_name);

	if (mnt->ttl != SMB_TTL_DEFAULT)
		seq_printf(s, ",ttl=%d", mnt->ttl);

	return 0;
}

static void
smb_unload_nls(struct smb_sb_info *server)
{
	if (server->remote_nls) {
		unload_nls(server->remote_nls);
		server->remote_nls = NULL;
	}
	if (server->local_nls) {
		unload_nls(server->local_nls);
		server->local_nls = NULL;
	}
}

static void
smb_put_super(struct super_block *sb)
{
	struct smb_sb_info *server = SMB_SB(sb);

	smb_lock_server(server);
	server->state = CONN_INVALID;
	smbiod_unregister_server(server);

	smb_close_socket(server);

	if (server->conn_pid)
		kill_pid(server->conn_pid, SIGTERM, 1);

	kfree(server->ops);
	smb_unload_nls(server);
	sb->s_fs_info = NULL;
	smb_unlock_server(server);
	put_pid(server->conn_pid);
	kfree(server);
}

static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
{
	struct smb_sb_info *server;
	struct smb_mount_data_kernel *mnt;
	struct smb_mount_data *oldmnt;
	struct inode *root_inode;
	struct smb_fattr root;
	int ver;
	void *mem;

	if (!raw_data)
		goto out_no_data;

	oldmnt = (struct smb_mount_data *) raw_data;
	ver = oldmnt->version;
	if (ver != SMB_MOUNT_OLDVERSION && cpu_to_be32(ver) != SMB_MOUNT_ASCII)
		goto out_wrong_data;

	sb->s_flags |= MS_NODIRATIME;
	sb->s_blocksize = 1024;	/* Eh...  Is this correct? */
	sb->s_blocksize_bits = 10;
	sb->s_magic = SMB_SUPER_MAGIC;
	sb->s_op = &smb_sops;
	sb->s_time_gran = 100;

	server = kzalloc(sizeof(struct smb_sb_info), GFP_KERNEL);
	if (!server)
		goto out_no_server;
	sb->s_fs_info = server;

	server->super_block = sb;
	server->mnt = NULL;
	server->sock_file = NULL;
	init_waitqueue_head(&server->conn_wq);
	init_MUTEX(&server->sem);
	INIT_LIST_HEAD(&server->entry);
	INIT_LIST_HEAD(&server->xmitq);
	INIT_LIST_HEAD(&server->recvq);
	server->conn_error = 0;
	server->conn_pid = NULL;
	server->state = CONN_INVALID; /* no connection yet */
	server->generation = 0;

	/* Allocate the global temp buffer and some superblock helper structs */
	/* FIXME: move these to the smb_sb_info struct */
	VERBOSE("alloc chunk = %d\n", sizeof(struct smb_ops) +
		sizeof(struct smb_mount_data_kernel));
	mem = kmalloc(sizeof(struct smb_ops) +
		      sizeof(struct smb_mount_data_kernel), GFP_KERNEL);
	if (!mem)
		goto out_no_mem;

	server->ops = mem;
	smb_install_null_ops(server->ops);
	server->mnt = mem + sizeof(struct smb_ops);

	/* Setup NLS stuff */
	server->remote_nls = NULL;
	server->local_nls = NULL;

	mnt = server->mnt;

	memset(mnt, 0, sizeof(struct smb_mount_data_kernel));
	strlcpy(mnt->codepage.local_name, CONFIG_NLS_DEFAULT,
		SMB_NLS_MAXNAMELEN);
	strlcpy(mnt->codepage.remote_name, SMB_NLS_REMOTE,
		SMB_NLS_MAXNAMELEN);

	mnt->ttl = SMB_TTL_DEFAULT;
	if (ver == SMB_MOUNT_OLDVERSION) {
		mnt->version = oldmnt->version;

		SET_UID(mnt->uid, oldmnt->uid);
		SET_GID(mnt->gid, oldmnt->gid);

		mnt->file_mode = (oldmnt->file_mode & S_IRWXUGO) | S_IFREG;
		mnt->dir_mode = (oldmnt->dir_mode & S_IRWXUGO) | S_IFDIR;

		mnt->flags = (oldmnt->file_mode >> 9) | SMB_MOUNT_UID |
			SMB_MOUNT_GID | SMB_MOUNT_FMODE | SMB_MOUNT_DMODE;
	} else {
		mnt->file_mode = S_IRWXU | S_IRGRP | S_IXGRP |
				S_IROTH | S_IXOTH | S_IFREG;
		mnt->dir_mode = S_IRWXU | S_IRGRP | S_IXGRP |
				S_IROTH | S_IXOTH | S_IFDIR;
		if (parse_options(mnt, raw_data))
			goto out_bad_option;
	}
	mnt->mounted_uid = current->uid;
	smb_setcodepage(server, &mnt->codepage);

	/*
	 * Display the enabled options
	 * Note: smb_proc_getattr uses these in 2.4 (but was changed in 2.2)
	 */
	if (mnt->flags & SMB_MOUNT_OLDATTR)
		printk("SMBFS: Using core getattr (Win 95 speedup)\n");
	else if (mnt->flags & SMB_MOUNT_DIRATTR)
		printk("SMBFS: Using dir ff getattr\n");

	if (smbiod_register_server(server) < 0) {
		printk(KERN_ERR "smbfs: failed to start smbiod\n");
		goto out_no_smbiod;
	}

	/*
	 * Keep the super block locked while we get the root inode.
	 */
	smb_init_root_dirent(server, &root, sb);
	root_inode = smb_iget(sb, &root);
	if (!root_inode)
		goto out_no_root;

	sb->s_root = d_alloc_root(root_inode);
	if (!sb->s_root)
		goto out_no_root;

	smb_new_dentry(sb->s_root);

	return 0;

out_no_root:
	iput(root_inode);
out_no_smbiod:
	smb_unload_nls(server);
out_bad_option:
	kfree(mem);
out_no_mem:
	if (!server->mnt)
		printk(KERN_ERR "smb_fill_super: allocation failure\n");
	sb->s_fs_info = NULL;
	kfree(server);
	goto out_fail;
out_wrong_data:
	printk(KERN_ERR "smbfs: mount_data version %d is not supported\n", ver);
	goto out_fail;
out_no_data:
	printk(KERN_ERR "smb_fill_super: missing data argument\n");
out_fail:
	return -EINVAL;
out_no_server:
	printk(KERN_ERR "smb_fill_super: cannot allocate struct smb_sb_info\n");
	return -ENOMEM;
}

static int
smb_statfs(struct dentry *dentry, struct kstatfs *buf)
{
	int result;
	
	lock_kernel();

	result = smb_proc_dskattr(dentry, buf);

	unlock_kernel();

	buf->f_type = SMB_SUPER_MAGIC;
	buf->f_namelen = SMB_MAXPATHLEN;
	return result;
}

int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
{
	int err = smb_revalidate_inode(dentry);
	if (!err)
		generic_fillattr(dentry->d_inode, stat);
	return err;
}

int
smb_notify_change(struct dentry *dentry, struct iattr *attr)
{
	struct inode *inode = dentry->d_inode;
	struct smb_sb_info *server = server_from_dentry(dentry);
	unsigned int mask = (S_IFREG | S_IFDIR | S_IRWXUGO);
	int error, changed, refresh = 0;
	struct smb_fattr fattr;

	lock_kernel();

	error = smb_revalidate_inode(dentry);
	if (error)
		goto out;

	if ((error = inode_change_ok(inode, attr)) < 0)
		goto out;

	error = -EPERM;
	if ((attr->ia_valid & ATTR_UID) && (attr->ia_uid != server->mnt->uid))
		goto out;

	if ((attr->ia_valid & ATTR_GID) && (attr->ia_uid != server->mnt->gid))
		goto out;

	if ((attr->ia_valid & ATTR_MODE) && (attr->ia_mode & ~mask))
		goto out;

	if ((attr->ia_valid & ATTR_SIZE) != 0) {
		VERBOSE("changing %s/%s, old size=%ld, new size=%ld\n",
			DENTRY_PATH(dentry),
			(long) inode->i_size, (long) attr->ia_size);

		filemap_write_and_wait(inode->i_mapping);

		error = smb_open(dentry, O_WRONLY);
		if (error)
			goto out;
		error = server->ops->truncate(inode, attr->ia_size);
		if (error)
			goto out;
		error = vmtruncate(inode, attr->ia_size);
		if (error)
			goto out;
		refresh = 1;
	}

	if (server->opt.capabilities & SMB_CAP_UNIX) {
		/* For now we don't want to set the size with setattr_unix */
		attr->ia_valid &= ~ATTR_SIZE;
		/* FIXME: only call if we actually want to set something? */
		error = smb_proc_setattr_unix(dentry, attr, 0, 0);
		if (!error)
			refresh = 1;

		goto out;
	}

	/*
	 * Initialize the fattr and check for changed fields.
	 * Note: CTIME under SMB is creation time rather than
	 * change time, so we don't attempt to change it.
	 */
	smb_get_inode_attr(inode, &fattr);

	changed = 0;
	if ((attr->ia_valid & ATTR_MTIME) != 0) {
		fattr.f_mtime = attr->ia_mtime;
		changed = 1;
	}
	if ((attr->ia_valid & ATTR_ATIME) != 0) {
		fattr.f_atime = attr->ia_atime;
		/* Earlier protocols don't have an access time */
		if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2)
			changed = 1;
	}
	if (changed) {
		error = smb_proc_settime(dentry, &fattr);
		if (error)
			goto out;
		refresh = 1;
	}

	/*
	 * Check for mode changes ... we're extremely limited in
	 * what can be set for SMB servers: just the read-only bit.
	 */
	if ((attr->ia_valid & ATTR_MODE) != 0) {
		VERBOSE("%s/%s mode change, old=%x, new=%x\n",
			DENTRY_PATH(dentry), fattr.f_mode, attr->ia_mode);
		changed = 0;
		if (attr->ia_mode & S_IWUSR) {
			if (fattr.attr & aRONLY) {
				fattr.attr &= ~aRONLY;
				changed = 1;
			}
		} else {
			if (!(fattr.attr & aRONLY)) {
				fattr.attr |= aRONLY;
				changed = 1;
			}
		}
		if (changed) {
			error = smb_proc_setattr(dentry, &fattr);
			if (error)
				goto out;
			refresh = 1;
		}
	}
	error = 0;

out:
	if (refresh)
		smb_refresh_inode(dentry);
	unlock_kernel();
	return error;
}

static int smb_get_sb(struct file_system_type *fs_type,
	int flags, const char *dev_name, void *data, struct vfsmount *mnt)
{
	return get_sb_nodev(fs_type, flags, data, smb_fill_super, mnt);
}

static struct file_system_type smb_fs_type = {
	.owner		= THIS_MODULE,
	.name		= "smbfs",
	.get_sb		= smb_get_sb,
	.kill_sb	= kill_anon_super,
	.fs_flags	= FS_BINARY_MOUNTDATA,
};

static int __init init_smb_fs(void)
{
	int err;
	DEBUG1("registering ...\n");

	err = init_inodecache();
	if (err)
		goto out_inode;
	err = smb_init_request_cache();
	if (err)
		goto out_request;
	err = register_filesystem(&smb_fs_type);
	if (err)
		goto out;
	return 0;
out:
	smb_destroy_request_cache();
out_request:
	destroy_inodecache();
out_inode:
	return err;
}

static void __exit exit_smb_fs(void)
{
	DEBUG1("unregistering ...\n");
	unregister_filesystem(&smb_fs_type);
	smb_destroy_request_cache();
	destroy_inodecache();
}

module_init(init_smb_fs)
module_exit(exit_smb_fs)
MODULE_LICENSE("GPL");
