// SPDX-License-Identifier: MIT
/*
 * VirtualBox Guest Shared Folders support: Virtual File System.
 *
 * Module initialization/finalization
 * File system registration/deregistration
 * Superblock reading
 * Few utility functions
 *
 * Copyright (C) 2006-2018 Oracle Corporation
 */

#include <linux/idr.h>
#include <linux/fs_parser.h>
#include <linux/magic.h>
#include <linux/module.h>
#include <linux/nls.h>
#include <linux/statfs.h>
#include <linux/vbox_utils.h>
#include "vfsmod.h"

#define VBOXSF_SUPER_MAGIC 0x786f4256 /* 'VBox' little endian */

#define VBSF_MOUNT_SIGNATURE_BYTE_0 ('\000')
#define VBSF_MOUNT_SIGNATURE_BYTE_1 ('\377')
#define VBSF_MOUNT_SIGNATURE_BYTE_2 ('\376')
#define VBSF_MOUNT_SIGNATURE_BYTE_3 ('\375')

static int follow_symlinks;
module_param(follow_symlinks, int, 0444);
MODULE_PARM_DESC(follow_symlinks,
		 "Let host resolve symlinks rather than showing them");

static DEFINE_IDA(vboxsf_bdi_ida);
static DEFINE_MUTEX(vboxsf_setup_mutex);
static bool vboxsf_setup_done;
static struct super_operations vboxsf_super_ops; /* forward declaration */
static struct kmem_cache *vboxsf_inode_cachep;

static char * const vboxsf_default_nls = CONFIG_NLS_DEFAULT;

enum  { opt_nls, opt_uid, opt_gid, opt_ttl, opt_dmode, opt_fmode,
	opt_dmask, opt_fmask };

static const struct fs_parameter_spec vboxsf_fs_parameters[] = {
	fsparam_string	("nls",		opt_nls),
	fsparam_u32	("uid",		opt_uid),
	fsparam_u32	("gid",		opt_gid),
	fsparam_u32	("ttl",		opt_ttl),
	fsparam_u32oct	("dmode",	opt_dmode),
	fsparam_u32oct	("fmode",	opt_fmode),
	fsparam_u32oct	("dmask",	opt_dmask),
	fsparam_u32oct	("fmask",	opt_fmask),
	{}
};

static int vboxsf_parse_param(struct fs_context *fc, struct fs_parameter *param)
{
	struct vboxsf_fs_context *ctx = fc->fs_private;
	struct fs_parse_result result;
	kuid_t uid;
	kgid_t gid;
	int opt;

	opt = fs_parse(fc, vboxsf_fs_parameters, param, &result);
	if (opt < 0)
		return opt;

	switch (opt) {
	case opt_nls:
		if (ctx->nls_name || fc->purpose != FS_CONTEXT_FOR_MOUNT) {
			vbg_err("vboxsf: Cannot reconfigure nls option\n");
			return -EINVAL;
		}
		ctx->nls_name = param->string;
		param->string = NULL;
		break;
	case opt_uid:
		uid = make_kuid(current_user_ns(), result.uint_32);
		if (!uid_valid(uid))
			return -EINVAL;
		ctx->o.uid = uid;
		break;
	case opt_gid:
		gid = make_kgid(current_user_ns(), result.uint_32);
		if (!gid_valid(gid))
			return -EINVAL;
		ctx->o.gid = gid;
		break;
	case opt_ttl:
		ctx->o.ttl = msecs_to_jiffies(result.uint_32);
		break;
	case opt_dmode:
		if (result.uint_32 & ~0777)
			return -EINVAL;
		ctx->o.dmode = result.uint_32;
		ctx->o.dmode_set = true;
		break;
	case opt_fmode:
		if (result.uint_32 & ~0777)
			return -EINVAL;
		ctx->o.fmode = result.uint_32;
		ctx->o.fmode_set = true;
		break;
	case opt_dmask:
		if (result.uint_32 & ~07777)
			return -EINVAL;
		ctx->o.dmask = result.uint_32;
		break;
	case opt_fmask:
		if (result.uint_32 & ~07777)
			return -EINVAL;
		ctx->o.fmask = result.uint_32;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int vboxsf_fill_super(struct super_block *sb, struct fs_context *fc)
{
	struct vboxsf_fs_context *ctx = fc->fs_private;
	struct shfl_string *folder_name, root_path;
	struct vboxsf_sbi *sbi;
	struct dentry *droot;
	struct inode *iroot;
	char *nls_name;
	size_t size;
	int err;

	if (!fc->source)
		return -EINVAL;

	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
	if (!sbi)
		return -ENOMEM;

	sbi->o = ctx->o;
	idr_init(&sbi->ino_idr);
	spin_lock_init(&sbi->ino_idr_lock);
	sbi->next_generation = 1;
	sbi->bdi_id = -1;

	/* Load nls if not utf8 */
	nls_name = ctx->nls_name ? ctx->nls_name : vboxsf_default_nls;
	if (strcmp(nls_name, "utf8") != 0) {
		if (nls_name == vboxsf_default_nls)
			sbi->nls = load_nls_default();
		else
			sbi->nls = load_nls(nls_name);

		if (!sbi->nls) {
			vbg_err("vboxsf: Count not load '%s' nls\n", nls_name);
			err = -EINVAL;
			goto fail_free;
		}
	}

	sbi->bdi_id = ida_simple_get(&vboxsf_bdi_ida, 0, 0, GFP_KERNEL);
	if (sbi->bdi_id < 0) {
		err = sbi->bdi_id;
		goto fail_free;
	}

	err = super_setup_bdi_name(sb, "vboxsf-%s.%d", fc->source, sbi->bdi_id);
	if (err)
		goto fail_free;

	/* Turn source into a shfl_string and map the folder */
	size = strlen(fc->source) + 1;
	folder_name = kmalloc(SHFLSTRING_HEADER_SIZE + size, GFP_KERNEL);
	if (!folder_name) {
		err = -ENOMEM;
		goto fail_free;
	}
	folder_name->size = size;
	folder_name->length = size - 1;
	strlcpy(folder_name->string.utf8, fc->source, size);
	err = vboxsf_map_folder(folder_name, &sbi->root);
	kfree(folder_name);
	if (err) {
		vbg_err("vboxsf: Host rejected mount of '%s' with error %d\n",
			fc->source, err);
		goto fail_free;
	}

	root_path.length = 1;
	root_path.size = 2;
	root_path.string.utf8[0] = '/';
	root_path.string.utf8[1] = 0;
	err = vboxsf_stat(sbi, &root_path, &sbi->root_info);
	if (err)
		goto fail_unmap;

	sb->s_magic = VBOXSF_SUPER_MAGIC;
	sb->s_blocksize = 1024;
	sb->s_maxbytes = MAX_LFS_FILESIZE;
	sb->s_op = &vboxsf_super_ops;
	sb->s_d_op = &vboxsf_dentry_ops;

	iroot = iget_locked(sb, 0);
	if (!iroot) {
		err = -ENOMEM;
		goto fail_unmap;
	}
	vboxsf_init_inode(sbi, iroot, &sbi->root_info);
	unlock_new_inode(iroot);

	droot = d_make_root(iroot);
	if (!droot) {
		err = -ENOMEM;
		goto fail_unmap;
	}

	sb->s_root = droot;
	sb->s_fs_info = sbi;
	return 0;

fail_unmap:
	vboxsf_unmap_folder(sbi->root);
fail_free:
	if (sbi->bdi_id >= 0)
		ida_simple_remove(&vboxsf_bdi_ida, sbi->bdi_id);
	if (sbi->nls)
		unload_nls(sbi->nls);
	idr_destroy(&sbi->ino_idr);
	kfree(sbi);
	return err;
}

static void vboxsf_inode_init_once(void *data)
{
	struct vboxsf_inode *sf_i = data;

	mutex_init(&sf_i->handle_list_mutex);
	inode_init_once(&sf_i->vfs_inode);
}

static struct inode *vboxsf_alloc_inode(struct super_block *sb)
{
	struct vboxsf_inode *sf_i;

	sf_i = kmem_cache_alloc(vboxsf_inode_cachep, GFP_NOFS);
	if (!sf_i)
		return NULL;

	sf_i->force_restat = 0;
	INIT_LIST_HEAD(&sf_i->handle_list);

	return &sf_i->vfs_inode;
}

static void vboxsf_free_inode(struct inode *inode)
{
	struct vboxsf_sbi *sbi = VBOXSF_SBI(inode->i_sb);
	unsigned long flags;

	spin_lock_irqsave(&sbi->ino_idr_lock, flags);
	idr_remove(&sbi->ino_idr, inode->i_ino);
	spin_unlock_irqrestore(&sbi->ino_idr_lock, flags);
	kmem_cache_free(vboxsf_inode_cachep, VBOXSF_I(inode));
}

static void vboxsf_put_super(struct super_block *sb)
{
	struct vboxsf_sbi *sbi = VBOXSF_SBI(sb);

	vboxsf_unmap_folder(sbi->root);
	if (sbi->bdi_id >= 0)
		ida_simple_remove(&vboxsf_bdi_ida, sbi->bdi_id);
	if (sbi->nls)
		unload_nls(sbi->nls);

	/*
	 * vboxsf_free_inode uses the idr, make sure all delayed rcu free
	 * inodes are flushed.
	 */
	rcu_barrier();
	idr_destroy(&sbi->ino_idr);
	kfree(sbi);
}

static int vboxsf_statfs(struct dentry *dentry, struct kstatfs *stat)
{
	struct super_block *sb = dentry->d_sb;
	struct shfl_volinfo shfl_volinfo;
	struct vboxsf_sbi *sbi;
	u32 buf_len;
	int err;

	sbi = VBOXSF_SBI(sb);
	buf_len = sizeof(shfl_volinfo);
	err = vboxsf_fsinfo(sbi->root, 0, SHFL_INFO_GET | SHFL_INFO_VOLUME,
			    &buf_len, &shfl_volinfo);
	if (err)
		return err;

	stat->f_type = VBOXSF_SUPER_MAGIC;
	stat->f_bsize = shfl_volinfo.bytes_per_allocation_unit;

	do_div(shfl_volinfo.total_allocation_bytes,
	       shfl_volinfo.bytes_per_allocation_unit);
	stat->f_blocks = shfl_volinfo.total_allocation_bytes;

	do_div(shfl_volinfo.available_allocation_bytes,
	       shfl_volinfo.bytes_per_allocation_unit);
	stat->f_bfree  = shfl_volinfo.available_allocation_bytes;
	stat->f_bavail = shfl_volinfo.available_allocation_bytes;

	stat->f_files = 1000;
	/*
	 * Don't return 0 here since the guest may then think that it is not
	 * possible to create any more files.
	 */
	stat->f_ffree = 1000000;
	stat->f_fsid.val[0] = 0;
	stat->f_fsid.val[1] = 0;
	stat->f_namelen = 255;
	return 0;
}

static struct super_operations vboxsf_super_ops = {
	.alloc_inode	= vboxsf_alloc_inode,
	.free_inode	= vboxsf_free_inode,
	.put_super	= vboxsf_put_super,
	.statfs		= vboxsf_statfs,
};

static int vboxsf_setup(void)
{
	int err;

	mutex_lock(&vboxsf_setup_mutex);

	if (vboxsf_setup_done)
		goto success;

	vboxsf_inode_cachep =
		kmem_cache_create("vboxsf_inode_cache",
				  sizeof(struct vboxsf_inode), 0,
				  (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD |
				   SLAB_ACCOUNT),
				  vboxsf_inode_init_once);
	if (!vboxsf_inode_cachep) {
		err = -ENOMEM;
		goto fail_nomem;
	}

	err = vboxsf_connect();
	if (err) {
		vbg_err("vboxsf: err %d connecting to guest PCI-device\n", err);
		vbg_err("vboxsf: make sure you are inside a VirtualBox VM\n");
		vbg_err("vboxsf: and check dmesg for vboxguest errors\n");
		goto fail_free_cache;
	}

	err = vboxsf_set_utf8();
	if (err) {
		vbg_err("vboxsf_setutf8 error %d\n", err);
		goto fail_disconnect;
	}

	if (!follow_symlinks) {
		err = vboxsf_set_symlinks();
		if (err)
			vbg_warn("vboxsf: Unable to show symlinks: %d\n", err);
	}

	vboxsf_setup_done = true;
success:
	mutex_unlock(&vboxsf_setup_mutex);
	return 0;

fail_disconnect:
	vboxsf_disconnect();
fail_free_cache:
	kmem_cache_destroy(vboxsf_inode_cachep);
fail_nomem:
	mutex_unlock(&vboxsf_setup_mutex);
	return err;
}

static int vboxsf_parse_monolithic(struct fs_context *fc, void *data)
{
	char *options = data;

	if (options && options[0] == VBSF_MOUNT_SIGNATURE_BYTE_0 &&
		       options[1] == VBSF_MOUNT_SIGNATURE_BYTE_1 &&
		       options[2] == VBSF_MOUNT_SIGNATURE_BYTE_2 &&
		       options[3] == VBSF_MOUNT_SIGNATURE_BYTE_3) {
		vbg_err("vboxsf: Old binary mount data not supported, remove obsolete mount.vboxsf and/or update your VBoxService.\n");
		return -EINVAL;
	}

	return generic_parse_monolithic(fc, data);
}

static int vboxsf_get_tree(struct fs_context *fc)
{
	int err;

	err = vboxsf_setup();
	if (err)
		return err;

	return get_tree_nodev(fc, vboxsf_fill_super);
}

static int vboxsf_reconfigure(struct fs_context *fc)
{
	struct vboxsf_sbi *sbi = VBOXSF_SBI(fc->root->d_sb);
	struct vboxsf_fs_context *ctx = fc->fs_private;
	struct inode *iroot = fc->root->d_sb->s_root->d_inode;

	/* Apply changed options to the root inode */
	sbi->o = ctx->o;
	vboxsf_init_inode(sbi, iroot, &sbi->root_info);

	return 0;
}

static void vboxsf_free_fc(struct fs_context *fc)
{
	struct vboxsf_fs_context *ctx = fc->fs_private;

	kfree(ctx->nls_name);
	kfree(ctx);
}

static const struct fs_context_operations vboxsf_context_ops = {
	.free			= vboxsf_free_fc,
	.parse_param		= vboxsf_parse_param,
	.parse_monolithic	= vboxsf_parse_monolithic,
	.get_tree		= vboxsf_get_tree,
	.reconfigure		= vboxsf_reconfigure,
};

static int vboxsf_init_fs_context(struct fs_context *fc)
{
	struct vboxsf_fs_context *ctx;

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	current_uid_gid(&ctx->o.uid, &ctx->o.gid);

	fc->fs_private = ctx;
	fc->ops = &vboxsf_context_ops;
	return 0;
}

static struct file_system_type vboxsf_fs_type = {
	.owner			= THIS_MODULE,
	.name			= "vboxsf",
	.init_fs_context	= vboxsf_init_fs_context,
	.kill_sb		= kill_anon_super
};

/* Module initialization/finalization handlers */
static int __init vboxsf_init(void)
{
	return register_filesystem(&vboxsf_fs_type);
}

static void __exit vboxsf_fini(void)
{
	unregister_filesystem(&vboxsf_fs_type);

	mutex_lock(&vboxsf_setup_mutex);
	if (vboxsf_setup_done) {
		vboxsf_disconnect();
		/*
		 * Make sure all delayed rcu free inodes are flushed
		 * before we destroy the cache.
		 */
		rcu_barrier();
		kmem_cache_destroy(vboxsf_inode_cachep);
	}
	mutex_unlock(&vboxsf_setup_mutex);
}

module_init(vboxsf_init);
module_exit(vboxsf_fini);

MODULE_DESCRIPTION("Oracle VM VirtualBox Module for Host File System Access");
MODULE_AUTHOR("Oracle Corporation");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_FS("vboxsf");
