// SPDX-License-Identifier: MIT
/*
 * VirtualBox Guest Shared Folders support: Directory inode and file operations
 *
 * Copyright (C) 2006-2018 Oracle Corporation
 */

#include <linux/namei.h>
#include <linux/vbox_utils.h>
#include "vfsmod.h"

static int vboxsf_dir_open(struct inode *inode, struct file *file)
{
	struct vboxsf_sbi *sbi = VBOXSF_SBI(inode->i_sb);
	struct shfl_createparms params = {};
	struct vboxsf_dir_info *sf_d;
	int err;

	sf_d = vboxsf_dir_info_alloc();
	if (!sf_d)
		return -ENOMEM;

	params.handle = SHFL_HANDLE_NIL;
	params.create_flags = SHFL_CF_DIRECTORY | SHFL_CF_ACT_OPEN_IF_EXISTS |
			      SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACCESS_READ;

	err = vboxsf_create_at_dentry(file_dentry(file), &params);
	if (err)
		goto err_free_dir_info;

	if (params.result != SHFL_FILE_EXISTS) {
		err = -ENOENT;
		goto err_close;
	}

	err = vboxsf_dir_read_all(sbi, sf_d, params.handle);
	if (err)
		goto err_close;

	vboxsf_close(sbi->root, params.handle);
	file->private_data = sf_d;
	return 0;

err_close:
	vboxsf_close(sbi->root, params.handle);
err_free_dir_info:
	vboxsf_dir_info_free(sf_d);
	return err;
}

static int vboxsf_dir_release(struct inode *inode, struct file *file)
{
	if (file->private_data)
		vboxsf_dir_info_free(file->private_data);

	return 0;
}

static unsigned int vboxsf_get_d_type(u32 mode)
{
	unsigned int d_type;

	switch (mode & SHFL_TYPE_MASK) {
	case SHFL_TYPE_FIFO:
		d_type = DT_FIFO;
		break;
	case SHFL_TYPE_DEV_CHAR:
		d_type = DT_CHR;
		break;
	case SHFL_TYPE_DIRECTORY:
		d_type = DT_DIR;
		break;
	case SHFL_TYPE_DEV_BLOCK:
		d_type = DT_BLK;
		break;
	case SHFL_TYPE_FILE:
		d_type = DT_REG;
		break;
	case SHFL_TYPE_SYMLINK:
		d_type = DT_LNK;
		break;
	case SHFL_TYPE_SOCKET:
		d_type = DT_SOCK;
		break;
	case SHFL_TYPE_WHITEOUT:
		d_type = DT_WHT;
		break;
	default:
		d_type = DT_UNKNOWN;
		break;
	}
	return d_type;
}

static bool vboxsf_dir_emit(struct file *dir, struct dir_context *ctx)
{
	struct vboxsf_sbi *sbi = VBOXSF_SBI(file_inode(dir)->i_sb);
	struct vboxsf_dir_info *sf_d = dir->private_data;
	struct shfl_dirinfo *info;
	struct vboxsf_dir_buf *b;
	unsigned int d_type;
	loff_t i, cur = 0;
	ino_t fake_ino;
	void *end;
	int err;

	list_for_each_entry(b, &sf_d->info_list, head) {
try_next_entry:
		if (ctx->pos >= cur + b->entries) {
			cur += b->entries;
			continue;
		}

		/*
		 * Note the vboxsf_dir_info objects we are iterating over here
		 * are variable sized, so the info pointer may end up being
		 * unaligned. This is how we get the data from the host.
		 * Since vboxsf is only supported on x86 machines this is not
		 * a problem.
		 */
		for (i = 0, info = b->buf; i < ctx->pos - cur; i++) {
			end = &info->name.string.utf8[info->name.size];
			/* Only happens if the host gives us corrupt data */
			if (WARN_ON(end > (b->buf + b->used)))
				return false;
			info = end;
		}

		end = &info->name.string.utf8[info->name.size];
		if (WARN_ON(end > (b->buf + b->used)))
			return false;

		/* Info now points to the right entry, emit it. */
		d_type = vboxsf_get_d_type(info->info.attr.mode);

		/*
		 * On 32-bit systems pos is 64-bit signed, while ino is 32-bit
		 * unsigned so fake_ino may overflow, check for this.
		 */
		if ((ino_t)(ctx->pos + 1) != (u64)(ctx->pos + 1)) {
			vbg_err("vboxsf: fake ino overflow, truncating dir\n");
			return false;
		}
		fake_ino = ctx->pos + 1;

		if (sbi->nls) {
			char d_name[NAME_MAX];

			err = vboxsf_nlscpy(sbi, d_name, NAME_MAX,
					    info->name.string.utf8,
					    info->name.length);
			if (err) {
				/* skip erroneous entry and proceed */
				ctx->pos += 1;
				goto try_next_entry;
			}

			return dir_emit(ctx, d_name, strlen(d_name),
					fake_ino, d_type);
		}

		return dir_emit(ctx, info->name.string.utf8, info->name.length,
				fake_ino, d_type);
	}

	return false;
}

static int vboxsf_dir_iterate(struct file *dir, struct dir_context *ctx)
{
	bool emitted;

	do {
		emitted = vboxsf_dir_emit(dir, ctx);
		if (emitted)
			ctx->pos += 1;
	} while (emitted);

	return 0;
}

WRAP_DIR_ITER(vboxsf_dir_iterate) // FIXME!
const struct file_operations vboxsf_dir_fops = {
	.open = vboxsf_dir_open,
	.iterate_shared = shared_vboxsf_dir_iterate,
	.release = vboxsf_dir_release,
	.read = generic_read_dir,
	.llseek = generic_file_llseek,
};

/*
 * This is called during name resolution/lookup to check if the @dentry in
 * the cache is still valid. the job is handled by vboxsf_inode_revalidate.
 */
static int vboxsf_dentry_revalidate(struct dentry *dentry, unsigned int flags)
{
	if (flags & LOOKUP_RCU)
		return -ECHILD;

	if (d_really_is_positive(dentry))
		return vboxsf_inode_revalidate(dentry) == 0;
	else
		return vboxsf_stat_dentry(dentry, NULL) == -ENOENT;
}

const struct dentry_operations vboxsf_dentry_ops = {
	.d_revalidate = vboxsf_dentry_revalidate
};

/* iops */

static struct dentry *vboxsf_dir_lookup(struct inode *parent,
					struct dentry *dentry,
					unsigned int flags)
{
	struct vboxsf_sbi *sbi = VBOXSF_SBI(parent->i_sb);
	struct shfl_fsobjinfo fsinfo;
	struct inode *inode;
	int err;

	dentry->d_time = jiffies;

	err = vboxsf_stat_dentry(dentry, &fsinfo);
	if (err) {
		inode = (err == -ENOENT) ? NULL : ERR_PTR(err);
	} else {
		inode = vboxsf_new_inode(parent->i_sb);
		if (!IS_ERR(inode))
			vboxsf_init_inode(sbi, inode, &fsinfo, false);
	}

	return d_splice_alias(inode, dentry);
}

static int vboxsf_dir_instantiate(struct inode *parent, struct dentry *dentry,
				  struct shfl_fsobjinfo *info)
{
	struct vboxsf_sbi *sbi = VBOXSF_SBI(parent->i_sb);
	struct vboxsf_inode *sf_i;
	struct inode *inode;

	inode = vboxsf_new_inode(parent->i_sb);
	if (IS_ERR(inode))
		return PTR_ERR(inode);

	sf_i = VBOXSF_I(inode);
	/* The host may have given us different attr then requested */
	sf_i->force_restat = 1;
	vboxsf_init_inode(sbi, inode, info, false);

	d_instantiate(dentry, inode);

	return 0;
}

static int vboxsf_dir_create(struct inode *parent, struct dentry *dentry,
			     umode_t mode, bool is_dir, bool excl, u64 *handle_ret)
{
	struct vboxsf_inode *sf_parent_i = VBOXSF_I(parent);
	struct vboxsf_sbi *sbi = VBOXSF_SBI(parent->i_sb);
	struct shfl_createparms params = {};
	int err;

	params.handle = SHFL_HANDLE_NIL;
	params.create_flags = SHFL_CF_ACT_CREATE_IF_NEW | SHFL_CF_ACCESS_READWRITE;
	if (is_dir)
		params.create_flags |= SHFL_CF_DIRECTORY;
	if (excl)
		params.create_flags |= SHFL_CF_ACT_FAIL_IF_EXISTS;

	params.info.attr.mode = (mode & 0777) |
				(is_dir ? SHFL_TYPE_DIRECTORY : SHFL_TYPE_FILE);
	params.info.attr.additional = SHFLFSOBJATTRADD_NOTHING;

	err = vboxsf_create_at_dentry(dentry, &params);
	if (err)
		return err;

	if (params.result != SHFL_FILE_CREATED)
		return -EPERM;

	err = vboxsf_dir_instantiate(parent, dentry, &params.info);
	if (err)
		goto out;

	/* parent directory access/change time changed */
	sf_parent_i->force_restat = 1;

out:
	if (err == 0 && handle_ret)
		*handle_ret = params.handle;
	else
		vboxsf_close(sbi->root, params.handle);

	return err;
}

static int vboxsf_dir_mkfile(struct mnt_idmap *idmap,
			     struct inode *parent, struct dentry *dentry,
			     umode_t mode, bool excl)
{
	return vboxsf_dir_create(parent, dentry, mode, false, excl, NULL);
}

static int vboxsf_dir_mkdir(struct mnt_idmap *idmap,
			    struct inode *parent, struct dentry *dentry,
			    umode_t mode)
{
	return vboxsf_dir_create(parent, dentry, mode, true, true, NULL);
}

static int vboxsf_dir_atomic_open(struct inode *parent, struct dentry *dentry,
				  struct file *file, unsigned int flags, umode_t mode)
{
	struct vboxsf_sbi *sbi = VBOXSF_SBI(parent->i_sb);
	struct vboxsf_handle *sf_handle;
	struct dentry *res = NULL;
	u64 handle;
	int err;

	if (d_in_lookup(dentry)) {
		res = vboxsf_dir_lookup(parent, dentry, 0);
		if (IS_ERR(res))
			return PTR_ERR(res);

		if (res)
			dentry = res;
	}

	/* Only creates */
	if (!(flags & O_CREAT) || d_really_is_positive(dentry))
		return finish_no_open(file, res);

	err = vboxsf_dir_create(parent, dentry, mode, false, flags & O_EXCL, &handle);
	if (err)
		goto out;

	sf_handle = vboxsf_create_sf_handle(d_inode(dentry), handle, SHFL_CF_ACCESS_READWRITE);
	if (IS_ERR(sf_handle)) {
		vboxsf_close(sbi->root, handle);
		err = PTR_ERR(sf_handle);
		goto out;
	}

	err = finish_open(file, dentry, generic_file_open);
	if (err) {
		/* This also closes the handle passed to vboxsf_create_sf_handle() */
		vboxsf_release_sf_handle(d_inode(dentry), sf_handle);
		goto out;
	}

	file->private_data = sf_handle;
	file->f_mode |= FMODE_CREATED;
out:
	dput(res);
	return err;
}

static int vboxsf_dir_unlink(struct inode *parent, struct dentry *dentry)
{
	struct vboxsf_sbi *sbi = VBOXSF_SBI(parent->i_sb);
	struct vboxsf_inode *sf_parent_i = VBOXSF_I(parent);
	struct inode *inode = d_inode(dentry);
	struct shfl_string *path;
	u32 flags;
	int err;

	if (S_ISDIR(inode->i_mode))
		flags = SHFL_REMOVE_DIR;
	else
		flags = SHFL_REMOVE_FILE;

	if (S_ISLNK(inode->i_mode))
		flags |= SHFL_REMOVE_SYMLINK;

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

	err = vboxsf_remove(sbi->root, path, flags);
	__putname(path);
	if (err)
		return err;

	/* parent directory access/change time changed */
	sf_parent_i->force_restat = 1;

	return 0;
}

static int vboxsf_dir_rename(struct mnt_idmap *idmap,
			     struct inode *old_parent,
			     struct dentry *old_dentry,
			     struct inode *new_parent,
			     struct dentry *new_dentry,
			     unsigned int flags)
{
	struct vboxsf_sbi *sbi = VBOXSF_SBI(old_parent->i_sb);
	struct vboxsf_inode *sf_old_parent_i = VBOXSF_I(old_parent);
	struct vboxsf_inode *sf_new_parent_i = VBOXSF_I(new_parent);
	u32 shfl_flags = SHFL_RENAME_FILE | SHFL_RENAME_REPLACE_IF_EXISTS;
	struct shfl_string *old_path, *new_path;
	int err;

	if (flags)
		return -EINVAL;

	old_path = vboxsf_path_from_dentry(sbi, old_dentry);
	if (IS_ERR(old_path))
		return PTR_ERR(old_path);

	new_path = vboxsf_path_from_dentry(sbi, new_dentry);
	if (IS_ERR(new_path)) {
		err = PTR_ERR(new_path);
		goto err_put_old_path;
	}

	if (d_inode(old_dentry)->i_mode & S_IFDIR)
		shfl_flags = 0;

	err = vboxsf_rename(sbi->root, old_path, new_path, shfl_flags);
	if (err == 0) {
		/* parent directories access/change time changed */
		sf_new_parent_i->force_restat = 1;
		sf_old_parent_i->force_restat = 1;
	}

	__putname(new_path);
err_put_old_path:
	__putname(old_path);
	return err;
}

static int vboxsf_dir_symlink(struct mnt_idmap *idmap,
			      struct inode *parent, struct dentry *dentry,
			      const char *symname)
{
	struct vboxsf_inode *sf_parent_i = VBOXSF_I(parent);
	struct vboxsf_sbi *sbi = VBOXSF_SBI(parent->i_sb);
	int symname_size = strlen(symname) + 1;
	struct shfl_string *path, *ssymname;
	struct shfl_fsobjinfo info;
	int err;

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

	ssymname = kmalloc(SHFLSTRING_HEADER_SIZE + symname_size, GFP_KERNEL);
	if (!ssymname) {
		__putname(path);
		return -ENOMEM;
	}
	ssymname->length = symname_size - 1;
	ssymname->size = symname_size;
	memcpy(ssymname->string.utf8, symname, symname_size);

	err = vboxsf_symlink(sbi->root, path, ssymname, &info);
	kfree(ssymname);
	__putname(path);
	if (err) {
		/* -EROFS means symlinks are note support -> -EPERM */
		return (err == -EROFS) ? -EPERM : err;
	}

	err = vboxsf_dir_instantiate(parent, dentry, &info);
	if (err)
		return err;

	/* parent directory access/change time changed */
	sf_parent_i->force_restat = 1;
	return 0;
}

const struct inode_operations vboxsf_dir_iops = {
	.lookup  = vboxsf_dir_lookup,
	.create  = vboxsf_dir_mkfile,
	.mkdir   = vboxsf_dir_mkdir,
	.atomic_open = vboxsf_dir_atomic_open,
	.rmdir   = vboxsf_dir_unlink,
	.unlink  = vboxsf_dir_unlink,
	.rename  = vboxsf_dir_rename,
	.symlink = vboxsf_dir_symlink,
	.getattr = vboxsf_getattr,
	.setattr = vboxsf_setattr,
};
