// 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;
	size_t size;
	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++) {
			size = offsetof(struct shfl_dirinfo, name.string) +
			       info->name.size;
			info = (struct shfl_dirinfo *)((uintptr_t)info + size);
		}

		/* 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 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 keep_iterating;

	for (keep_iterating = true; keep_iterating; ctx->pos += 1)
		keep_iterating = vboxsf_dir_emit(dir, ctx);

	return 0;
}

const struct file_operations vboxsf_dir_fops = {
	.open = vboxsf_dir_open,
	.iterate = 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);
	}

	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);

	d_instantiate(dentry, inode);

	return 0;
}

static int vboxsf_dir_create(struct inode *parent, struct dentry *dentry,
			     umode_t mode, int is_dir)
{
	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_ACT_FAIL_IF_EXISTS |
			      SHFL_CF_ACCESS_READWRITE |
			      (is_dir ? SHFL_CF_DIRECTORY : 0);
	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;

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

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

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

	return 0;
}

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

static int vboxsf_dir_mkdir(struct inode *parent, struct dentry *dentry,
			    umode_t mode)
{
	return vboxsf_dir_create(parent, dentry, mode, 1);
}

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 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 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,
	.rmdir   = vboxsf_dir_unlink,
	.unlink  = vboxsf_dir_unlink,
	.rename  = vboxsf_dir_rename,
	.symlink = vboxsf_dir_symlink,
	.getattr = vboxsf_getattr,
	.setattr = vboxsf_setattr,
};
