// SPDX-License-Identifier: MIT
/*
 * VirtualBox Guest Shared Folders support: Utility functions.
 * Mainly conversion from/to VirtualBox/Linux data structures.
 *
 * Copyright (C) 2006-2018 Oracle Corporation
 */

#include <linux/namei.h>
#include <linux/nls.h>
#include <linux/sizes.h>
#include <linux/vfs.h>
#include "vfsmod.h"

struct inode *vboxsf_new_inode(struct super_block *sb)
{
	struct vboxsf_sbi *sbi = VBOXSF_SBI(sb);
	struct inode *inode;
	unsigned long flags;
	int cursor, ret;
	u32 gen;

	inode = new_inode(sb);
	if (!inode)
		return ERR_PTR(-ENOMEM);

	idr_preload(GFP_KERNEL);
	spin_lock_irqsave(&sbi->ino_idr_lock, flags);
	cursor = idr_get_cursor(&sbi->ino_idr);
	ret = idr_alloc_cyclic(&sbi->ino_idr, inode, 1, 0, GFP_ATOMIC);
	if (ret >= 0 && ret < cursor)
		sbi->next_generation++;
	gen = sbi->next_generation;
	spin_unlock_irqrestore(&sbi->ino_idr_lock, flags);
	idr_preload_end();

	if (ret < 0) {
		iput(inode);
		return ERR_PTR(ret);
	}

	inode->i_ino = ret;
	inode->i_generation = gen;
	return inode;
}

/* set [inode] attributes based on [info], uid/gid based on [sbi] */
int vboxsf_init_inode(struct vboxsf_sbi *sbi, struct inode *inode,
		       const struct shfl_fsobjinfo *info, bool reinit)
{
	const struct shfl_fsobjattr *attr;
	s64 allocated;
	umode_t mode;

	attr = &info->attr;

#define mode_set(r) ((attr->mode & (SHFL_UNIX_##r)) ? (S_##r) : 0)

	mode = mode_set(IRUSR);
	mode |= mode_set(IWUSR);
	mode |= mode_set(IXUSR);

	mode |= mode_set(IRGRP);
	mode |= mode_set(IWGRP);
	mode |= mode_set(IXGRP);

	mode |= mode_set(IROTH);
	mode |= mode_set(IWOTH);
	mode |= mode_set(IXOTH);

#undef mode_set

	/* We use the host-side values for these */
	inode->i_flags |= S_NOATIME | S_NOCMTIME;
	inode->i_mapping->a_ops = &vboxsf_reg_aops;

	if (SHFL_IS_DIRECTORY(attr->mode)) {
		if (sbi->o.dmode_set)
			mode = sbi->o.dmode;
		mode &= ~sbi->o.dmask;
		mode |= S_IFDIR;
		if (!reinit) {
			inode->i_op = &vboxsf_dir_iops;
			inode->i_fop = &vboxsf_dir_fops;
			/*
			 * XXX: this probably should be set to the number of entries
			 * in the directory plus two (. ..)
			 */
			set_nlink(inode, 1);
		} else if (!S_ISDIR(inode->i_mode))
			return -ESTALE;
		inode->i_mode = mode;
	} else if (SHFL_IS_SYMLINK(attr->mode)) {
		if (sbi->o.fmode_set)
			mode = sbi->o.fmode;
		mode &= ~sbi->o.fmask;
		mode |= S_IFLNK;
		if (!reinit) {
			inode->i_op = &vboxsf_lnk_iops;
			set_nlink(inode, 1);
		} else if (!S_ISLNK(inode->i_mode))
			return -ESTALE;
		inode->i_mode = mode;
	} else {
		if (sbi->o.fmode_set)
			mode = sbi->o.fmode;
		mode &= ~sbi->o.fmask;
		mode |= S_IFREG;
		if (!reinit) {
			inode->i_op = &vboxsf_reg_iops;
			inode->i_fop = &vboxsf_reg_fops;
			set_nlink(inode, 1);
		} else if (!S_ISREG(inode->i_mode))
			return -ESTALE;
		inode->i_mode = mode;
	}

	inode->i_uid = sbi->o.uid;
	inode->i_gid = sbi->o.gid;

	inode->i_size = info->size;
	inode->i_blkbits = 12;
	/* i_blocks always in units of 512 bytes! */
	allocated = info->allocated + 511;
	do_div(allocated, 512);
	inode->i_blocks = allocated;

	inode->i_atime = ns_to_timespec64(
				 info->access_time.ns_relative_to_unix_epoch);
	inode->i_ctime = ns_to_timespec64(
				 info->change_time.ns_relative_to_unix_epoch);
	inode->i_mtime = ns_to_timespec64(
			   info->modification_time.ns_relative_to_unix_epoch);
	return 0;
}

int vboxsf_create_at_dentry(struct dentry *dentry,
			    struct shfl_createparms *params)
{
	struct vboxsf_sbi *sbi = VBOXSF_SBI(dentry->d_sb);
	struct shfl_string *path;
	int err;

	path = vboxsf_path_from_dentry(sbi, dentry);
	if (IS_ERR(path))
		return PTR_ERR(path);

	err = vboxsf_create(sbi->root, path, params);
	__putname(path);

	return err;
}

int vboxsf_stat(struct vboxsf_sbi *sbi, struct shfl_string *path,
		struct shfl_fsobjinfo *info)
{
	struct shfl_createparms params = {};
	int err;

	params.handle = SHFL_HANDLE_NIL;
	params.create_flags = SHFL_CF_LOOKUP | SHFL_CF_ACT_FAIL_IF_NEW;

	err = vboxsf_create(sbi->root, path, &params);
	if (err)
		return err;

	if (params.result != SHFL_FILE_EXISTS)
		return -ENOENT;

	if (info)
		*info = params.info;

	return 0;
}

int vboxsf_stat_dentry(struct dentry *dentry, struct shfl_fsobjinfo *info)
{
	struct vboxsf_sbi *sbi = VBOXSF_SBI(dentry->d_sb);
	struct shfl_string *path;
	int err;

	path = vboxsf_path_from_dentry(sbi, dentry);
	if (IS_ERR(path))
		return PTR_ERR(path);

	err = vboxsf_stat(sbi, path, info);
	__putname(path);
	return err;
}

int vboxsf_inode_revalidate(struct dentry *dentry)
{
	struct vboxsf_sbi *sbi;
	struct vboxsf_inode *sf_i;
	struct shfl_fsobjinfo info;
	struct timespec64 prev_mtime;
	struct inode *inode;
	int err;

	if (!dentry || !d_really_is_positive(dentry))
		return -EINVAL;

	inode = d_inode(dentry);
	prev_mtime = inode->i_mtime;
	sf_i = VBOXSF_I(inode);
	sbi = VBOXSF_SBI(dentry->d_sb);
	if (!sf_i->force_restat) {
		if (time_before(jiffies, dentry->d_time + sbi->o.ttl))
			return 0;
	}

	err = vboxsf_stat_dentry(dentry, &info);
	if (err)
		return err;

	dentry->d_time = jiffies;
	sf_i->force_restat = 0;
	err = vboxsf_init_inode(sbi, inode, &info, true);
	if (err)
		return err;

	/*
	 * If the file was changed on the host side we need to invalidate the
	 * page-cache for it.  Note this also gets triggered by our own writes,
	 * this is unavoidable.
	 */
	if (timespec64_compare(&inode->i_mtime, &prev_mtime) > 0)
		invalidate_inode_pages2(inode->i_mapping);

	return 0;
}

int vboxsf_getattr(struct user_namespace *mnt_userns, const struct path *path,
		   struct kstat *kstat, u32 request_mask, unsigned int flags)
{
	int err;
	struct dentry *dentry = path->dentry;
	struct inode *inode = d_inode(dentry);
	struct vboxsf_inode *sf_i = VBOXSF_I(inode);

	switch (flags & AT_STATX_SYNC_TYPE) {
	case AT_STATX_DONT_SYNC:
		err = 0;
		break;
	case AT_STATX_FORCE_SYNC:
		sf_i->force_restat = 1;
		fallthrough;
	default:
		err = vboxsf_inode_revalidate(dentry);
	}
	if (err)
		return err;

	generic_fillattr(&init_user_ns, d_inode(dentry), kstat);
	return 0;
}

int vboxsf_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
		   struct iattr *iattr)
{
	struct vboxsf_inode *sf_i = VBOXSF_I(d_inode(dentry));
	struct vboxsf_sbi *sbi = VBOXSF_SBI(dentry->d_sb);
	struct shfl_createparms params = {};
	struct shfl_fsobjinfo info = {};
	u32 buf_len;
	int err;

	params.handle = SHFL_HANDLE_NIL;
	params.create_flags = SHFL_CF_ACT_OPEN_IF_EXISTS |
			      SHFL_CF_ACT_FAIL_IF_NEW |
			      SHFL_CF_ACCESS_ATTR_WRITE;

	/* this is at least required for Posix hosts */
	if (iattr->ia_valid & ATTR_SIZE)
		params.create_flags |= SHFL_CF_ACCESS_WRITE;

	err = vboxsf_create_at_dentry(dentry, &params);
	if (err || params.result != SHFL_FILE_EXISTS)
		return err ? err : -ENOENT;

#define mode_set(r) ((iattr->ia_mode & (S_##r)) ? SHFL_UNIX_##r : 0)

	/*
	 * Setting the file size and setting the other attributes has to
	 * be handled separately.
	 */
	if (iattr->ia_valid & (ATTR_MODE | ATTR_ATIME | ATTR_MTIME)) {
		if (iattr->ia_valid & ATTR_MODE) {
			info.attr.mode = mode_set(IRUSR);
			info.attr.mode |= mode_set(IWUSR);
			info.attr.mode |= mode_set(IXUSR);
			info.attr.mode |= mode_set(IRGRP);
			info.attr.mode |= mode_set(IWGRP);
			info.attr.mode |= mode_set(IXGRP);
			info.attr.mode |= mode_set(IROTH);
			info.attr.mode |= mode_set(IWOTH);
			info.attr.mode |= mode_set(IXOTH);

			if (iattr->ia_mode & S_IFDIR)
				info.attr.mode |= SHFL_TYPE_DIRECTORY;
			else
				info.attr.mode |= SHFL_TYPE_FILE;
		}

		if (iattr->ia_valid & ATTR_ATIME)
			info.access_time.ns_relative_to_unix_epoch =
					    timespec64_to_ns(&iattr->ia_atime);

		if (iattr->ia_valid & ATTR_MTIME)
			info.modification_time.ns_relative_to_unix_epoch =
					    timespec64_to_ns(&iattr->ia_mtime);

		/*
		 * Ignore ctime (inode change time) as it can't be set
		 * from userland anyway.
		 */

		buf_len = sizeof(info);
		err = vboxsf_fsinfo(sbi->root, params.handle,
				    SHFL_INFO_SET | SHFL_INFO_FILE, &buf_len,
				    &info);
		if (err) {
			vboxsf_close(sbi->root, params.handle);
			return err;
		}

		/* the host may have given us different attr then requested */
		sf_i->force_restat = 1;
	}

#undef mode_set

	if (iattr->ia_valid & ATTR_SIZE) {
		memset(&info, 0, sizeof(info));
		info.size = iattr->ia_size;
		buf_len = sizeof(info);
		err = vboxsf_fsinfo(sbi->root, params.handle,
				    SHFL_INFO_SET | SHFL_INFO_SIZE, &buf_len,
				    &info);
		if (err) {
			vboxsf_close(sbi->root, params.handle);
			return err;
		}

		/* the host may have given us different attr then requested */
		sf_i->force_restat = 1;
	}

	vboxsf_close(sbi->root, params.handle);

	/* Update the inode with what the host has actually given us. */
	if (sf_i->force_restat)
		vboxsf_inode_revalidate(dentry);

	return 0;
}

/*
 * [dentry] contains string encoded in coding system that corresponds
 * to [sbi]->nls, we must convert it to UTF8 here.
 * Returns a shfl_string allocated through __getname (must be freed using
 * __putname), or an ERR_PTR on error.
 */
struct shfl_string *vboxsf_path_from_dentry(struct vboxsf_sbi *sbi,
					    struct dentry *dentry)
{
	struct shfl_string *shfl_path;
	int path_len, out_len, nb;
	char *buf, *path;
	wchar_t uni;
	u8 *out;

	buf = __getname();
	if (!buf)
		return ERR_PTR(-ENOMEM);

	path = dentry_path_raw(dentry, buf, PATH_MAX);
	if (IS_ERR(path)) {
		__putname(buf);
		return ERR_CAST(path);
	}
	path_len = strlen(path);

	if (sbi->nls) {
		shfl_path = __getname();
		if (!shfl_path) {
			__putname(buf);
			return ERR_PTR(-ENOMEM);
		}

		out = shfl_path->string.utf8;
		out_len = PATH_MAX - SHFLSTRING_HEADER_SIZE - 1;

		while (path_len) {
			nb = sbi->nls->char2uni(path, path_len, &uni);
			if (nb < 0) {
				__putname(shfl_path);
				__putname(buf);
				return ERR_PTR(-EINVAL);
			}
			path += nb;
			path_len -= nb;

			nb = utf32_to_utf8(uni, out, out_len);
			if (nb < 0) {
				__putname(shfl_path);
				__putname(buf);
				return ERR_PTR(-ENAMETOOLONG);
			}
			out += nb;
			out_len -= nb;
		}
		*out = 0;
		shfl_path->length = out - shfl_path->string.utf8;
		shfl_path->size = shfl_path->length + 1;
		__putname(buf);
	} else {
		if ((SHFLSTRING_HEADER_SIZE + path_len + 1) > PATH_MAX) {
			__putname(buf);
			return ERR_PTR(-ENAMETOOLONG);
		}
		/*
		 * dentry_path stores the name at the end of buf, but the
		 * shfl_string string we return must be properly aligned.
		 */
		shfl_path = (struct shfl_string *)buf;
		memmove(shfl_path->string.utf8, path, path_len);
		shfl_path->string.utf8[path_len] = 0;
		shfl_path->length = path_len;
		shfl_path->size = path_len + 1;
	}

	return shfl_path;
}

int vboxsf_nlscpy(struct vboxsf_sbi *sbi, char *name, size_t name_bound_len,
		  const unsigned char *utf8_name, size_t utf8_len)
{
	const char *in;
	char *out;
	size_t out_len;
	size_t out_bound_len;
	size_t in_bound_len;

	in = utf8_name;
	in_bound_len = utf8_len;

	out = name;
	out_len = 0;
	/* Reserve space for terminating 0 */
	out_bound_len = name_bound_len - 1;

	while (in_bound_len) {
		int nb;
		unicode_t uni;

		nb = utf8_to_utf32(in, in_bound_len, &uni);
		if (nb < 0)
			return -EINVAL;

		in += nb;
		in_bound_len -= nb;

		nb = sbi->nls->uni2char(uni, out, out_bound_len);
		if (nb < 0)
			return nb;

		out += nb;
		out_bound_len -= nb;
		out_len += nb;
	}

	*out = 0;

	return 0;
}

static struct vboxsf_dir_buf *vboxsf_dir_buf_alloc(struct list_head *list)
{
	struct vboxsf_dir_buf *b;

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

	b->buf = kmalloc(DIR_BUFFER_SIZE, GFP_KERNEL);
	if (!b->buf) {
		kfree(b);
		return NULL;
	}

	b->entries = 0;
	b->used = 0;
	b->free = DIR_BUFFER_SIZE;
	list_add(&b->head, list);

	return b;
}

static void vboxsf_dir_buf_free(struct vboxsf_dir_buf *b)
{
	list_del(&b->head);
	kfree(b->buf);
	kfree(b);
}

struct vboxsf_dir_info *vboxsf_dir_info_alloc(void)
{
	struct vboxsf_dir_info *p;

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

	INIT_LIST_HEAD(&p->info_list);
	return p;
}

void vboxsf_dir_info_free(struct vboxsf_dir_info *p)
{
	struct list_head *list, *pos, *tmp;

	list = &p->info_list;
	list_for_each_safe(pos, tmp, list) {
		struct vboxsf_dir_buf *b;

		b = list_entry(pos, struct vboxsf_dir_buf, head);
		vboxsf_dir_buf_free(b);
	}
	kfree(p);
}

int vboxsf_dir_read_all(struct vboxsf_sbi *sbi, struct vboxsf_dir_info *sf_d,
			u64 handle)
{
	struct vboxsf_dir_buf *b;
	u32 entries, size;
	int err = 0;
	void *buf;

	/* vboxsf_dirinfo returns 1 on end of dir */
	while (err == 0) {
		b = vboxsf_dir_buf_alloc(&sf_d->info_list);
		if (!b) {
			err = -ENOMEM;
			break;
		}

		buf = b->buf;
		size = b->free;

		err = vboxsf_dirinfo(sbi->root, handle, NULL, 0, 0,
				     &size, buf, &entries);
		if (err < 0)
			break;

		b->entries += entries;
		b->free -= size;
		b->used += size;
	}

	if (b && b->used == 0)
		vboxsf_dir_buf_free(b);

	/* -EILSEQ means the host could not translate a filename, ignore */
	if (err > 0 || err == -EILSEQ)
		err = 0;

	return err;
}
