// 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/pagemap.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_set_ctime_to_ts(inode,
			      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 mnt_idmap *idmap, 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(&nop_mnt_idmap, request_mask, d_inode(dentry), kstat);
	return 0;
}

int vboxsf_setattr(struct mnt_idmap *idmap, 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;
}
