/*
 * Copyright (c) 1998-2014 Erez Zadok
 * Copyright (c) 2009	   Shrikar Archak
 * Copyright (c) 2003-2014 Stony Brook University
 * Copyright (c) 2003-2014 The Research Foundation of SUNY
 * Copyright (C) 2013-2014 Motorola Mobility, LLC
 * Copyright (C) 2017      Google, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include "esdfs.h"
#include <linux/fsnotify.h>

static int esdfs_create(struct inode *dir, struct dentry *dentry,
			 umode_t mode, bool want_excl)
{
	int err;
	struct dentry *lower_dentry;
	struct dentry *lower_parent_dentry = NULL;
	struct path lower_path;
	struct inode *lower_inode;
	int mask;
	const struct cred *creds;

	/*
	 * Need to recheck derived permissions unified mode to prevent certain
	 * applications from creating files at the root.
	 */
	if (test_opt(ESDFS_SB(dir->i_sb), DERIVE_UNIFIED) &&
	    esdfs_check_derived_permission(dir, ESDFS_MAY_CREATE) != 0)
		return -EACCES;

	if (test_opt(ESDFS_SB(dir->i_sb), ACCESS_DISABLE))
		return -ENOENT;

	creds = esdfs_override_creds(ESDFS_SB(dir->i_sb), ESDFS_I(dir), &mask);
	if (!creds)
		return -ENOMEM;

	esdfs_get_lower_path(dentry, &lower_path);
	lower_dentry = lower_path.dentry;
	lower_parent_dentry = lock_parent(lower_dentry);

	esdfs_set_lower_mode(ESDFS_SB(dir->i_sb), ESDFS_I(dir), &mode);

	lower_inode = esdfs_lower_inode(dir);
	err = vfs_create(lower_inode, lower_dentry, mode, want_excl);
	if (err)
		goto out;

	err = esdfs_interpose(dentry, dir->i_sb, &lower_path,
				ESDFS_I(dir)->userid);
	if (err)
		goto out;
	fsstack_copy_attr_times(dir, esdfs_lower_inode(dir));
	fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);
	esdfs_derive_lower_ownership(dentry, dentry->d_name.name);

out:
	unlock_dir(lower_parent_dentry);
	esdfs_put_lower_path(dentry, &lower_path);
	esdfs_revert_creds(creds, &mask);
	return err;
}

static int esdfs_unlink(struct inode *dir, struct dentry *dentry)
{
	int err;
	struct dentry *lower_dentry;
	struct inode *lower_dir_inode;
	struct dentry *lower_dir_dentry;
	struct path lower_path;
	const struct cred *creds;

	creds = esdfs_override_creds(ESDFS_SB(dir->i_sb), ESDFS_I(dir), NULL);
	if (!creds)
		return -ENOMEM;

	if (test_opt(ESDFS_SB(dir->i_sb), ACCESS_DISABLE)) {
		esdfs_revert_creds(creds, NULL);
		return -ENOENT;
	}

	esdfs_get_lower_path(dentry, &lower_path);
	lower_dentry = lower_path.dentry;
	dget(lower_dentry);

	lower_dir_dentry = lock_parent(lower_dentry);

	/* d_parent might be changed in vfs_rename */
	if (lower_dir_dentry != lower_dentry->d_parent) {
		err = -ENOENT;
		goto out;
	}

	/* lower_dir_inode might be changed as well
	 * get the new inode with new lower dir dentry
	 */
	lower_dir_inode = lower_dir_dentry->d_inode;

	err = vfs_unlink(lower_dir_inode, lower_dentry, NULL);

	/*
	 * Note: unlinking on top of NFS can cause silly-renamed files.
	 * Trying to delete such files results in EBUSY from NFS
	 * below.  Silly-renamed files will get deleted by NFS later on, so
	 * we just need to detect them here and treat such EBUSY errors as
	 * if the upper file was successfully deleted.
	 */
	if (err == -EBUSY && lower_dentry->d_flags & DCACHE_NFSFS_RENAMED)
		err = 0;
	if (err)
		goto out;
	fsstack_copy_attr_times(dir, lower_dir_inode);
	fsstack_copy_inode_size(dir, lower_dir_inode);
	set_nlink(dentry->d_inode,
		  esdfs_lower_inode(dentry->d_inode)->i_nlink);
	dentry->d_inode->i_ctime = dir->i_ctime;
	d_drop(dentry); /* this is needed, else LTP fails (VFS won't do it) */
out:
	unlock_dir(lower_dir_dentry);
	dput(lower_dentry);
	esdfs_put_lower_path(dentry, &lower_path);
	esdfs_revert_creds(creds, NULL);
	return err;
}

static int esdfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
{
	int err;
	struct dentry *lower_dentry;
	struct dentry *lower_parent_dentry = NULL;
	struct path lower_path;
	int mask;
	const struct cred *creds =
			esdfs_override_creds(ESDFS_SB(dir->i_sb),
					ESDFS_I(dir), &mask);
	if (!creds)
		return -ENOMEM;

	if (test_opt(ESDFS_SB(dir->i_sb), ACCESS_DISABLE)) {
		esdfs_revert_creds(creds, NULL);
		return -ENOENT;
	}

	esdfs_get_lower_path(dentry, &lower_path);
	lower_dentry = lower_path.dentry;
	lower_parent_dentry = lock_parent(lower_dentry);

	mode |= S_IFDIR;
	esdfs_set_lower_mode(ESDFS_SB(dir->i_sb), ESDFS_I(dir), &mode);
	err = vfs_mkdir(lower_parent_dentry->d_inode, lower_dentry, mode);
	if (err)
		goto unlock_lower_parent;

	err = esdfs_interpose(dentry, dir->i_sb, &lower_path,
				ESDFS_I(dir)->userid);
	if (err)
		goto unlock_lower_parent;

	fsstack_copy_attr_times(dir, esdfs_lower_inode(dir));
	fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);
	/* update number of links on parent directory */
	set_nlink(dir, esdfs_lower_inode(dir)->i_nlink);
	esdfs_derive_lower_ownership(dentry, dentry->d_name.name);

	if (ESDFS_DERIVE_PERMS(ESDFS_SB(dir->i_sb))) {
		unlock_dir(lower_parent_dentry);
		err = esdfs_derive_mkdir_contents(dentry);
		goto out;
	}

unlock_lower_parent:
	unlock_dir(lower_parent_dentry);
out:
	esdfs_put_lower_path(dentry, &lower_path);
	esdfs_revert_creds(creds, &mask);
	return err;
}

static int esdfs_rmdir(struct inode *dir, struct dentry *dentry)
{
	struct dentry *lower_dentry;
	struct dentry *lower_dir_dentry;
	int err;
	struct path lower_path;
	const struct cred *creds =
			esdfs_override_creds(ESDFS_SB(dir->i_sb),
					ESDFS_I(dir), NULL);
	if (!creds)
		return -ENOMEM;

	/* Never remove a pseudo link target.  Only the source. */
	if (ESDFS_DENTRY_HAS_STUB(dentry))
		esdfs_get_lower_stub_path(dentry, &lower_path);
	else
		esdfs_get_lower_path(dentry, &lower_path);
	lower_dentry = lower_path.dentry;

	lower_dir_dentry = lock_parent(lower_dentry);

	/* d_parent might be changed in vfs_rename */
	if (lower_dir_dentry != lower_dentry->d_parent) {
		err = -ENOENT;
		goto out;
	}

	err = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
	if (err)
		goto out;

	d_drop(dentry);	/* drop our dentry on success (why not VFS's job?) */
	if (dentry->d_inode)
		clear_nlink(dentry->d_inode);
	fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
	fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode);
	set_nlink(dir, lower_dir_dentry->d_inode->i_nlink);

out:
	unlock_dir(lower_dir_dentry);
	esdfs_put_lower_path(dentry, &lower_path);
	esdfs_revert_creds(creds, NULL);
	return err;
}

/*
 * The locking rules in esdfs_rename are complex.  We could use a simpler
 * superblock-level name-space lock for renames and copy-ups.
 */
static int esdfs_rename(struct inode *old_dir, struct dentry *old_dentry,
			struct inode *new_dir, struct dentry *new_dentry, unsigned int flags)
{
	int err = 0;
	struct esdfs_sb_info *sbi = ESDFS_SB(old_dir->i_sb);
	struct dentry *lower_old_dentry = NULL;
	struct dentry *lower_new_dentry = NULL;
	struct dentry *lower_old_dir_dentry = NULL;
	struct dentry *lower_new_dir_dentry = NULL;
	struct dentry *trap = NULL;
	struct path lower_old_path, lower_new_path;
	int mask;
	const struct cred *creds;

	if (test_opt(sbi, SPECIAL_DOWNLOAD)) {
		if ((ESDFS_I(old_dir)->tree == ESDFS_TREE_DOWNLOAD
			|| ESDFS_I(new_dir)->tree == ESDFS_TREE_DOWNLOAD)
			&& ESDFS_I(old_dir)->tree != ESDFS_I(new_dir)->tree)
			return -EXDEV;
	}

	if (test_opt(sbi, GID_DERIVATION)) {
		if (ESDFS_I(old_dir)->userid != ESDFS_I(new_dir)->userid
			|| ((ESDFS_I(old_dir)->under_obb
			|| ESDFS_I(new_dir)->under_obb)
			&& ESDFS_I(old_dir)->under_obb
				!= ESDFS_I(new_dir)->under_obb))
			return -EXDEV;
	}
	creds = esdfs_override_creds(sbi, ESDFS_I(new_dir), &mask);
	if (!creds)
		return -ENOMEM;

	if (test_opt(ESDFS_SB(old_dir->i_sb), ACCESS_DISABLE)) {
		esdfs_revert_creds(creds, NULL);
		return -ENOENT;
	}

	/* Never rename to or from a pseudo hard link target. */
	if (ESDFS_DENTRY_HAS_STUB(old_dentry))
		esdfs_get_lower_stub_path(old_dentry, &lower_old_path);
	else
		esdfs_get_lower_path(old_dentry, &lower_old_path);
	if (ESDFS_DENTRY_HAS_STUB(new_dentry))
		esdfs_get_lower_stub_path(new_dentry, &lower_new_path);
	else
		esdfs_get_lower_path(new_dentry, &lower_new_path);
	lower_old_dentry = lower_old_path.dentry;
	lower_new_dentry = lower_new_path.dentry;
	esdfs_get_lower_parent(old_dentry, lower_old_dentry,
			       &lower_old_dir_dentry);
	esdfs_get_lower_parent(new_dentry, lower_new_dentry,
			       &lower_new_dir_dentry);

	trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
	/* source should not be ancestor of target */
	if (trap == lower_old_dentry) {
		err = -EINVAL;
		goto out;
	}
	/* target should not be ancestor of source */
	if (trap == lower_new_dentry) {
		err = -ENOTEMPTY;
		goto out;
	}

	err = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
			 lower_new_dir_dentry->d_inode, lower_new_dentry,
			 NULL, flags);
	if (err)
		goto out;

	esdfs_copy_attr(new_dir, lower_new_dir_dentry->d_inode);
	fsstack_copy_inode_size(new_dir, lower_new_dir_dentry->d_inode);
	if (new_dir != old_dir) {
		esdfs_copy_attr(old_dir,
				      lower_old_dir_dentry->d_inode);
		fsstack_copy_inode_size(old_dir,
					lower_old_dir_dentry->d_inode);
	}

	/* Drop any old links */
	if (ESDFS_DENTRY_HAS_STUB(old_dentry))
		d_drop(old_dentry);
	if (ESDFS_DENTRY_HAS_STUB(new_dentry))
		d_drop(new_dentry);
	esdfs_derive_lower_ownership(old_dentry, new_dentry->d_name.name);
out:
	unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
	esdfs_put_lower_parent(old_dentry, &lower_old_dir_dentry);
	esdfs_put_lower_parent(new_dentry, &lower_new_dir_dentry);
	esdfs_put_lower_path(old_dentry, &lower_old_path);
	esdfs_put_lower_path(new_dentry, &lower_new_path);
	esdfs_revert_creds(creds, &mask);
	return err;
}

static int esdfs_permission(struct inode *inode, int mask)
{
	struct inode *lower_inode;
	int err;

	/* First, check the upper permissions */
	err = generic_permission(inode, mask);

	/* Basic checking of the lower inode (can't override creds here) */
	lower_inode = esdfs_lower_inode(inode);
	if (S_ISSOCK(lower_inode->i_mode) ||
	    S_ISLNK(lower_inode->i_mode) ||
	    S_ISBLK(lower_inode->i_mode) ||
	    S_ISCHR(lower_inode->i_mode) ||
	    S_ISFIFO(lower_inode->i_mode))
		err = -EACCES;

	/* Finally, check the derived permissions */
	if (!err && ESDFS_DERIVE_PERMS(ESDFS_SB(inode->i_sb)))
		err = esdfs_check_derived_permission(inode, mask);

	return err;
}

static int esdfs_setattr(struct dentry *dentry, struct iattr *ia)
{
	int err;
	loff_t oldsize;
	loff_t newsize;
	struct dentry *lower_dentry;
	struct inode *inode;
	struct inode *lower_inode;
	struct path lower_path;
	struct iattr lower_ia;
	const struct cred *creds;

	/* We don't allow chmod or chown, so skip those */
	ia->ia_valid &= ~(ATTR_UID | ATTR_GID | ATTR_MODE);
	if (!ia->ia_valid)
		return 0;
	/* Allow touch updating timestamps. A previous permission check ensures
	 * we have write access. Changes to mode, owner, and group are ignored
	 */
	ia->ia_valid |= ATTR_FORCE;

	inode = dentry->d_inode;

	if (test_opt(ESDFS_SB(inode->i_sb), ACCESS_DISABLE))
		return -ENOENT;

	/*
	 * Check if user has permission to change inode.  We don't check if
	 * this user can change the lower inode: that should happen when
	 * calling notify_change on the lower inode.
	 */
	err = setattr_prepare(dentry, ia);
	if (err)
		return err;

	creds = esdfs_override_creds(ESDFS_SB(dentry->d_inode->i_sb),
				ESDFS_I(inode), NULL);
	if (!creds)
		return -ENOMEM;

	esdfs_get_lower_path(dentry, &lower_path);
	lower_dentry = lower_path.dentry;
	lower_inode = esdfs_lower_inode(inode);

	/* prepare our own lower struct iattr (with the lower file) */
	memcpy(&lower_ia, ia, sizeof(lower_ia));
	if (ia->ia_valid & ATTR_FILE)
		lower_ia.ia_file = esdfs_lower_file(ia->ia_file);

	/*
	 * If shrinking, first truncate upper level to cancel writing dirty
	 * pages beyond the new eof; and also if its' maxbytes is more
	 * limiting (fail with -EFBIG before making any change to the lower
	 * level).  There is no need to vmtruncate the upper level
	 * afterwards in the other cases: we fsstack_copy_inode_size from
	 * the lower level.
	 */
	if (ia->ia_valid & ATTR_SIZE) {
		err = inode_newsize_ok(inode, ia->ia_size);
		if (err)
			goto out;
		/*
		 * i_size_write needs locking around it
		 * otherwise i_size_read() may spin forever
		 * (see include/linux/fs.h).
		 * similar to function fsstack_copy_inode_size
		 */
		oldsize = i_size_read(inode);
		newsize = ia->ia_size;

#if BITS_PER_LONG == 32 && defined(CONFIG_SMP)
		spin_lock(&inode->i_lock);
#endif
		i_size_write(inode, newsize);
#if BITS_PER_LONG == 32 && defined(CONFIG_SMP)
		spin_unlock(&inode->i_lock);
#endif
		if (newsize > oldsize)
			pagecache_isize_extended(inode, oldsize, newsize);
		truncate_pagecache(inode, newsize);
		esdfs_truncate_share(inode->i_sb, lower_dentry->d_inode,
					ia->ia_size);
	}

	/*
	 * mode change is for clearing setuid/setgid bits. Allow lower fs
	 * to interpret this in its own way.
	 */
	if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
		lower_ia.ia_valid &= ~ATTR_MODE;

	/* notify the (possibly copied-up) lower inode */
	/*
	 * Note: we use lower_dentry->d_inode, because lower_inode may be
	 * unlinked (no inode->i_sb and i_ino==0.  This happens if someone
	 * tries to open(), unlink(), then ftruncate() a file.
	 */
	inode_lock(lower_dentry->d_inode);
	err = notify_change(lower_dentry, &lower_ia, /* note: lower_ia */
			    NULL);
	inode_unlock(lower_dentry->d_inode);
	if (err)
		goto out;

	/* get attributes from the lower inode */
	esdfs_copy_attr(inode, lower_inode);
	/*
	 * Not running fsstack_copy_inode_size(inode, lower_inode), because
	 * VFS should update our inode size, and notify_change on
	 * lower_inode should update its size.
	 */

out:
	esdfs_put_lower_path(dentry, &lower_path);
	esdfs_revert_creds(creds, NULL);
	return err;
}

static int esdfs_getattr(const struct path *path, struct kstat *stat,
			u32 request_mask, unsigned int flags)
{
	int err;
	struct dentry *dentry = path->dentry;
	struct path lower_path;
	struct kstat lower_stat;
	struct inode *lower_inode;
	struct inode *inode = dentry->d_inode;
	const struct cred *creds =
			esdfs_override_creds(ESDFS_SB(inode->i_sb),
						ESDFS_I(inode), NULL);
	if (!creds)
		return -ENOMEM;

	if (test_opt(ESDFS_SB(inode->i_sb), ACCESS_DISABLE)) {
		esdfs_revert_creds(creds, NULL);
		return -ENOENT;
	}

	esdfs_get_lower_path(dentry, &lower_path);

	/* We need the lower getattr to calculate stat->blocks for us. */
	err = vfs_getattr(&lower_path, &lower_stat, request_mask, flags);
	if (err)
		goto out;

	lower_inode = esdfs_lower_inode(inode);
	esdfs_copy_attr(inode, lower_inode);
	fsstack_copy_inode_size(inode, lower_inode);
	generic_fillattr(inode, stat);

	stat->blocks = lower_stat.blocks;

out:
	esdfs_put_lower_path(dentry, &lower_path);
	esdfs_revert_creds(creds, NULL);
	return err;
}

const struct inode_operations esdfs_symlink_iops = {
	.permission     = esdfs_permission,
	.setattr	= esdfs_setattr,
	.getattr	= esdfs_getattr,
};

const struct inode_operations esdfs_dir_iops = {
	.create		= esdfs_create,
	.lookup		= esdfs_lookup,
	.unlink		= esdfs_unlink,
	.mkdir		= esdfs_mkdir,
	.rmdir		= esdfs_rmdir,
	.rename		= esdfs_rename,
	.permission     = esdfs_permission,
	.setattr	= esdfs_setattr,
	.getattr	= esdfs_getattr,
};

const struct inode_operations esdfs_main_iops = {
	.permission     = esdfs_permission,
	.setattr	= esdfs_setattr,
	.getattr	= esdfs_getattr,
};
