// SPDX-License-Identifier: GPL-2.0-or-later
/* AFS dynamic root handling
 *
 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 */

#include <linux/fs.h>
#include <linux/namei.h>
#include <linux/dns_resolver.h>
#include "internal.h"

#define AFS_MIN_DYNROOT_CELL_INO 4 /* Allow for ., .., @cell, .@cell */
#define AFS_MAX_DYNROOT_CELL_INO ((unsigned int)INT_MAX)

static struct dentry *afs_lookup_atcell(struct inode *dir, struct dentry *dentry, ino_t ino);

/*
 * iget5() comparator for inode created by autocell operations
 */
static int afs_iget5_pseudo_test(struct inode *inode, void *opaque)
{
	struct afs_fid *fid = opaque;

	return inode->i_ino == fid->vnode;
}

/*
 * iget5() inode initialiser
 */
static int afs_iget5_pseudo_set(struct inode *inode, void *opaque)
{
	struct afs_super_info *as = AFS_FS_S(inode->i_sb);
	struct afs_vnode *vnode = AFS_FS_I(inode);
	struct afs_fid *fid = opaque;

	vnode->volume		= as->volume;
	vnode->fid		= *fid;
	inode->i_ino		= fid->vnode;
	inode->i_generation	= fid->unique;
	return 0;
}

/*
 * Create an inode for an autocell dynamic automount dir.
 */
static struct inode *afs_iget_pseudo_dir(struct super_block *sb, ino_t ino)
{
	struct afs_vnode *vnode;
	struct inode *inode;
	struct afs_fid fid = { .vnode = ino, .unique = 1, };

	_enter("");

	inode = iget5_locked(sb, fid.vnode,
			     afs_iget5_pseudo_test, afs_iget5_pseudo_set, &fid);
	if (!inode) {
		_leave(" = -ENOMEM");
		return ERR_PTR(-ENOMEM);
	}

	_debug("GOT INODE %p { ino=%lu, vl=%llx, vn=%llx, u=%x }",
	       inode, inode->i_ino, fid.vid, fid.vnode, fid.unique);

	vnode = AFS_FS_I(inode);

	if (inode_state_read_once(inode) & I_NEW) {
		netfs_inode_init(&vnode->netfs, NULL, false);
		simple_inode_init_ts(inode);
		set_nlink(inode, 2);
		inode->i_size		= 0;
		inode->i_mode		= S_IFDIR | 0555;
		inode->i_op		= &afs_autocell_inode_operations;
		inode->i_uid		= GLOBAL_ROOT_UID;
		inode->i_gid		= GLOBAL_ROOT_GID;
		inode->i_blocks		= 0;
		inode->i_generation	= 0;
		inode->i_flags		|= S_AUTOMOUNT | S_NOATIME;

		set_bit(AFS_VNODE_PSEUDODIR, &vnode->flags);
		set_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags);

		unlock_new_inode(inode);
	}
	_leave(" = %p", inode);
	return inode;
}

/*
 * Try to automount the mountpoint with pseudo directory, if the autocell
 * option is set.
 */
static struct dentry *afs_dynroot_lookup_cell(struct inode *dir, struct dentry *dentry,
					      unsigned int flags)
{
	struct afs_cell *cell = NULL;
	struct afs_net *net = afs_d2net(dentry);
	struct inode *inode = NULL;
	const char *name = dentry->d_name.name;
	size_t len = dentry->d_name.len;
	bool dotted = false;
	int ret = -ENOENT;

	/* Names prefixed with a dot are R/W mounts. */
	if (name[0] == '.') {
		name++;
		len--;
		dotted = true;
	}

	cell = afs_lookup_cell(net, name, len, NULL,
			       AFS_LOOKUP_CELL_DYNROOT,
			       afs_cell_trace_use_lookup_dynroot);
	if (IS_ERR(cell)) {
		ret = PTR_ERR(cell);
		goto out_no_cell;
	}

	inode = afs_iget_pseudo_dir(dir->i_sb, cell->dynroot_ino * 2 + dotted);
	if (IS_ERR(inode)) {
		ret = PTR_ERR(inode);
		goto out;
	}

	dentry->d_fsdata = cell;
	return d_splice_alias(inode, dentry);

out:
	afs_unuse_cell(cell, afs_cell_trace_unuse_lookup_dynroot);
out_no_cell:
	if (!inode)
		return d_splice_alias(inode, dentry);
	return ret == -ENOENT ? NULL : ERR_PTR(ret);
}

/*
 * Look up an entry in a dynroot directory.
 */
static struct dentry *afs_dynroot_lookup(struct inode *dir, struct dentry *dentry,
					 unsigned int flags)
{
	_enter("%pd", dentry);

	if (flags & LOOKUP_CREATE)
		return ERR_PTR(-EOPNOTSUPP);

	if (dentry->d_name.len >= AFSNAMEMAX) {
		_leave(" = -ENAMETOOLONG");
		return ERR_PTR(-ENAMETOOLONG);
	}

	if (dentry->d_name.len == 5 &&
	    memcmp(dentry->d_name.name, "@cell", 5) == 0)
		return afs_lookup_atcell(dir, dentry, 2);

	if (dentry->d_name.len == 6 &&
	    memcmp(dentry->d_name.name, ".@cell", 6) == 0)
		return afs_lookup_atcell(dir, dentry, 3);

	return afs_dynroot_lookup_cell(dir, dentry, flags);
}

const struct inode_operations afs_dynroot_inode_operations = {
	.lookup		= afs_dynroot_lookup,
};

static void afs_dynroot_d_release(struct dentry *dentry)
{
	struct afs_cell *cell = dentry->d_fsdata;

	afs_unuse_cell(cell, afs_cell_trace_unuse_dynroot_mntpt);
}

/*
 * Keep @cell symlink dentries around, but only keep cell autodirs when they're
 * being used.
 */
static int afs_dynroot_delete_dentry(const struct dentry *dentry)
{
	const struct qstr *name = &dentry->d_name;

	if (name->len == 5 && memcmp(name->name, "@cell", 5) == 0)
		return 0;
	if (name->len == 6 && memcmp(name->name, ".@cell", 6) == 0)
		return 0;
	return 1;
}

const struct dentry_operations afs_dynroot_dentry_operations = {
	.d_delete	= afs_dynroot_delete_dentry,
	.d_release	= afs_dynroot_d_release,
	.d_automount	= afs_d_automount,
};

static void afs_atcell_delayed_put_cell(void *arg)
{
	struct afs_cell *cell = arg;

	afs_put_cell(cell, afs_cell_trace_put_atcell);
}

/*
 * Read @cell or .@cell symlinks.
 */
static const char *afs_atcell_get_link(struct dentry *dentry, struct inode *inode,
				       struct delayed_call *done)
{
	struct afs_vnode *vnode = AFS_FS_I(inode);
	struct afs_cell *cell;
	struct afs_net *net = afs_i2net(inode);
	const char *name;
	bool dotted = vnode->fid.vnode == 3;

	if (!rcu_access_pointer(net->ws_cell))
		return ERR_PTR(-ENOENT);

	if (!dentry) {
		/* We're in RCU-pathwalk. */
		cell = rcu_dereference(net->ws_cell);
		if (dotted)
			name = cell->name - 1;
		else
			name = cell->name;
		/* Shouldn't need to set a delayed call. */
		return name;
	}

	down_read(&net->cells_lock);

	cell = rcu_dereference_protected(net->ws_cell, lockdep_is_held(&net->cells_lock));
	if (dotted)
		name = cell->name - 1;
	else
		name = cell->name;
	afs_get_cell(cell, afs_cell_trace_get_atcell);
	set_delayed_call(done, afs_atcell_delayed_put_cell, cell);

	up_read(&net->cells_lock);
	return name;
}

static const struct inode_operations afs_atcell_inode_operations = {
	.get_link	= afs_atcell_get_link,
};

/*
 * Create an inode for the @cell or .@cell symlinks.
 */
static struct dentry *afs_lookup_atcell(struct inode *dir, struct dentry *dentry, ino_t ino)
{
	struct afs_vnode *vnode;
	struct inode *inode;
	struct afs_fid fid = { .vnode = ino, .unique = 1, };

	inode = iget5_locked(dir->i_sb, fid.vnode,
			     afs_iget5_pseudo_test, afs_iget5_pseudo_set, &fid);
	if (!inode)
		return ERR_PTR(-ENOMEM);

	vnode = AFS_FS_I(inode);

	if (inode_state_read_once(inode) & I_NEW) {
		netfs_inode_init(&vnode->netfs, NULL, false);
		simple_inode_init_ts(inode);
		set_nlink(inode, 1);
		inode->i_size		= 0;
		inode->i_mode		= S_IFLNK | 0555;
		inode->i_op		= &afs_atcell_inode_operations;
		inode->i_uid		= GLOBAL_ROOT_UID;
		inode->i_gid		= GLOBAL_ROOT_GID;
		inode->i_blocks		= 0;
		inode->i_generation	= 0;
		inode->i_flags		|= S_NOATIME;

		unlock_new_inode(inode);
	}
	return d_splice_alias(inode, dentry);
}

/*
 * Transcribe the cell database into readdir content under the RCU read lock.
 * Each cell produces two entries, one prefixed with a dot and one not.
 */
static int afs_dynroot_readdir_cells(struct afs_net *net, struct dir_context *ctx)
{
	const struct afs_cell *cell;
	loff_t newpos;

	_enter("%llu", ctx->pos);

	for (;;) {
		unsigned int ix = ctx->pos >> 1;

		cell = idr_get_next(&net->cells_dyn_ino, &ix);
		if (!cell)
			return 0;
		if (READ_ONCE(cell->state) == AFS_CELL_REMOVING ||
		    READ_ONCE(cell->state) == AFS_CELL_DEAD) {
			ctx->pos += 2;
			ctx->pos &= ~1;
			continue;
		}

		newpos = ix << 1;
		if (newpos > ctx->pos)
			ctx->pos = newpos;

		_debug("pos %llu -> cell %u", ctx->pos, cell->dynroot_ino);

		if ((ctx->pos & 1) == 0) {
			if (!dir_emit(ctx, cell->name, cell->name_len,
				      cell->dynroot_ino, DT_DIR))
				return 0;
			ctx->pos++;
		}
		if ((ctx->pos & 1) == 1) {
			if (!dir_emit(ctx, cell->name - 1, cell->name_len + 1,
				      cell->dynroot_ino + 1, DT_DIR))
				return 0;
			ctx->pos++;
		}
	}
	return 0;
}

/*
 * Read the AFS dynamic root directory.  This produces a list of cellnames,
 * dotted and undotted, along with @cell and .@cell links if configured.
 */
static int afs_dynroot_readdir(struct file *file, struct dir_context *ctx)
{
	struct afs_net *net = afs_d2net(file->f_path.dentry);
	int ret = 0;

	if (!dir_emit_dots(file, ctx))
		return 0;

	if (ctx->pos == 2) {
		if (rcu_access_pointer(net->ws_cell) &&
		    !dir_emit(ctx, "@cell", 5, 2, DT_LNK))
			return 0;
		ctx->pos = 3;
	}
	if (ctx->pos == 3) {
		if (rcu_access_pointer(net->ws_cell) &&
		    !dir_emit(ctx, ".@cell", 6, 3, DT_LNK))
			return 0;
		ctx->pos = 4;
	}

	if ((unsigned long long)ctx->pos <= AFS_MAX_DYNROOT_CELL_INO) {
		down_read(&net->cells_lock);
		ret = afs_dynroot_readdir_cells(net, ctx);
		up_read(&net->cells_lock);
	}
	return ret;
}

static const struct file_operations afs_dynroot_file_operations = {
	.llseek		= generic_file_llseek,
	.read		= generic_read_dir,
	.iterate_shared	= afs_dynroot_readdir,
	.fsync		= noop_fsync,
};

/*
 * Create an inode for a dynamic root directory.
 */
struct inode *afs_dynroot_iget_root(struct super_block *sb)
{
	struct afs_super_info *as = AFS_FS_S(sb);
	struct afs_vnode *vnode;
	struct inode *inode;
	struct afs_fid fid = { .vid = 0, .vnode = 1, .unique = 1,};

	if (as->volume)
		fid.vid = as->volume->vid;

	inode = iget5_locked(sb, fid.vnode,
			     afs_iget5_pseudo_test, afs_iget5_pseudo_set, &fid);
	if (!inode)
		return ERR_PTR(-ENOMEM);

	vnode = AFS_FS_I(inode);

	/* there shouldn't be an existing inode */
	if (inode_state_read_once(inode) & I_NEW) {
		netfs_inode_init(&vnode->netfs, NULL, false);
		simple_inode_init_ts(inode);
		set_nlink(inode, 2);
		inode->i_size		= 0;
		inode->i_mode		= S_IFDIR | 0555;
		inode->i_op		= &afs_dynroot_inode_operations;
		inode->i_fop		= &afs_dynroot_file_operations;
		inode->i_uid		= GLOBAL_ROOT_UID;
		inode->i_gid		= GLOBAL_ROOT_GID;
		inode->i_blocks		= 0;
		inode->i_generation	= 0;
		inode->i_flags		|= S_NOATIME;

		set_bit(AFS_VNODE_PSEUDODIR, &vnode->flags);
		unlock_new_inode(inode);
	}
	_leave(" = %p", inode);
	return inode;
}
