// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2000-2001 Christoph Hellwig.
 * Copyright (c) 2016 Krzysztof Blaszkowski
 */

/*
 * Veritas filesystem driver - superblock related routines.
 */
#include <linux/init.h>
#include <linux/module.h>

#include <linux/blkdev.h>
#include <linux/fs.h>
#include <linux/buffer_head.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/vfs.h>
#include <linux/fs_context.h>

#include "vxfs.h"
#include "vxfs_extern.h"
#include "vxfs_dir.h"
#include "vxfs_inode.h"


MODULE_AUTHOR("Christoph Hellwig, Krzysztof Blaszkowski");
MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver");
MODULE_LICENSE("Dual BSD/GPL");

static struct kmem_cache *vxfs_inode_cachep;

/**
 * vxfs_put_super - free superblock resources
 * @sbp:	VFS superblock.
 *
 * Description:
 *   vxfs_put_super frees all resources allocated for @sbp
 *   after the last instance of the filesystem is unmounted.
 */

static void
vxfs_put_super(struct super_block *sbp)
{
	struct vxfs_sb_info	*infp = VXFS_SBI(sbp);

	iput(infp->vsi_fship);
	iput(infp->vsi_ilist);
	iput(infp->vsi_stilist);

	brelse(infp->vsi_bp);
	kfree(infp);
}

/**
 * vxfs_statfs - get filesystem information
 * @dentry:	VFS dentry to locate superblock
 * @bufp:	output buffer
 *
 * Description:
 *   vxfs_statfs fills the statfs buffer @bufp with information
 *   about the filesystem described by @dentry.
 *
 * Returns:
 *   Zero.
 *
 * Locking:
 *   No locks held.
 *
 * Notes:
 *   This is everything but complete...
 */
static int
vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp)
{
	struct vxfs_sb_info		*infp = VXFS_SBI(dentry->d_sb);
	struct vxfs_sb *raw_sb = infp->vsi_raw;
	u64 id = huge_encode_dev(dentry->d_sb->s_bdev->bd_dev);

	bufp->f_type = VXFS_SUPER_MAGIC;
	bufp->f_bsize = dentry->d_sb->s_blocksize;
	bufp->f_blocks = fs32_to_cpu(infp, raw_sb->vs_dsize);
	bufp->f_bfree = fs32_to_cpu(infp, raw_sb->vs_free);
	bufp->f_bavail = 0;
	bufp->f_files = 0;
	bufp->f_ffree = fs32_to_cpu(infp, raw_sb->vs_ifree);
	bufp->f_fsid = u64_to_fsid(id);
	bufp->f_namelen = VXFS_NAMELEN;

	return 0;
}

static int vxfs_reconfigure(struct fs_context *fc)
{
	sync_filesystem(fc->root->d_sb);
	fc->sb_flags |= SB_RDONLY;
	return 0;
}

static struct inode *vxfs_alloc_inode(struct super_block *sb)
{
	struct vxfs_inode_info *vi;

	vi = alloc_inode_sb(sb, vxfs_inode_cachep, GFP_KERNEL);
	if (!vi)
		return NULL;
	inode_init_once(&vi->vfs_inode);
	return &vi->vfs_inode;
}

static void vxfs_free_inode(struct inode *inode)
{
	kmem_cache_free(vxfs_inode_cachep, VXFS_INO(inode));
}

static const struct super_operations vxfs_super_ops = {
	.alloc_inode		= vxfs_alloc_inode,
	.free_inode		= vxfs_free_inode,
	.evict_inode		= vxfs_evict_inode,
	.put_super		= vxfs_put_super,
	.statfs			= vxfs_statfs,
};

static int vxfs_try_sb_magic(struct super_block *sbp, struct fs_context *fc,
		unsigned blk, __fs32 magic)
{
	struct buffer_head *bp;
	struct vxfs_sb *rsbp;
	struct vxfs_sb_info *infp = VXFS_SBI(sbp);
	int silent = fc->sb_flags & SB_SILENT;
	int rc = -ENOMEM;

	bp = sb_bread(sbp, blk);
	do {
		if (!bp || !buffer_mapped(bp)) {
			if (!silent) {
				warnf(fc,
				      "vxfs: unable to read disk superblock at %u",
				      blk);
			}
			break;
		}

		rc = -EINVAL;
		rsbp = (struct vxfs_sb *)bp->b_data;
		if (rsbp->vs_magic != magic) {
			if (!silent)
				infof(fc,
				      "vxfs: WRONG superblock magic %08x at %u",
				      rsbp->vs_magic, blk);
			break;
		}

		rc = 0;
		infp->vsi_raw = rsbp;
		infp->vsi_bp = bp;
	} while (0);

	if (rc) {
		infp->vsi_raw = NULL;
		infp->vsi_bp = NULL;
		brelse(bp);
	}

	return rc;
}

/**
 * vxfs_fill_super - read superblock into memory and initialize filesystem
 * @sbp:		VFS superblock (to fill)
 * @fc:			filesytem context
 *
 * Description:
 *   We are called on the first mount of a filesystem to read the
 *   superblock into memory and do some basic setup.
 *
 * Returns:
 *   The superblock on success, else %NULL.
 *
 * Locking:
 *   We are under @sbp->s_lock.
 */
static int vxfs_fill_super(struct super_block *sbp, struct fs_context *fc)
{
	struct vxfs_sb_info	*infp;
	struct vxfs_sb		*rsbp;
	u_long			bsize;
	struct inode *root;
	int ret = -EINVAL;
	int silent = fc->sb_flags & SB_SILENT;
	u32 j;

	sbp->s_flags |= SB_RDONLY;

	infp = kzalloc(sizeof(*infp), GFP_KERNEL);
	if (!infp) {
		warnf(fc, "vxfs: unable to allocate incore superblock");
		return -ENOMEM;
	}

	bsize = sb_min_blocksize(sbp, BLOCK_SIZE);
	if (!bsize) {
		warnf(fc, "vxfs: unable to set blocksize");
		goto out;
	}

	sbp->s_op = &vxfs_super_ops;
	sbp->s_fs_info = infp;
	sbp->s_time_min = 0;
	sbp->s_time_max = U32_MAX;

	if (!vxfs_try_sb_magic(sbp, fc, 1,
			(__force __fs32)cpu_to_le32(VXFS_SUPER_MAGIC))) {
		/* Unixware, x86 */
		infp->byte_order = VXFS_BO_LE;
	} else if (!vxfs_try_sb_magic(sbp, fc, 8,
			(__force __fs32)cpu_to_be32(VXFS_SUPER_MAGIC))) {
		/* HP-UX, parisc */
		infp->byte_order = VXFS_BO_BE;
	} else {
		if (!silent)
			infof(fc, "vxfs: can't find superblock.");
		goto out;
	}

	rsbp = infp->vsi_raw;
	j = fs32_to_cpu(infp, rsbp->vs_version);
	if ((j < 2 || j > 4) && !silent) {
		infof(fc, "vxfs: unsupported VxFS version (%d)", j);
		goto out;
	}

#ifdef DIAGNOSTIC
	printk(KERN_DEBUG "vxfs: supported VxFS version (%d)\n", j);
	printk(KERN_DEBUG "vxfs: blocksize: %d\n",
		fs32_to_cpu(infp, rsbp->vs_bsize));
#endif

	sbp->s_magic = fs32_to_cpu(infp, rsbp->vs_magic);

	infp->vsi_oltext = fs32_to_cpu(infp, rsbp->vs_oltext[0]);
	infp->vsi_oltsize = fs32_to_cpu(infp, rsbp->vs_oltsize);

	j = fs32_to_cpu(infp, rsbp->vs_bsize);
	if (!sb_set_blocksize(sbp, j)) {
		warnf(fc, "vxfs: unable to set final block size");
		goto out;
	}

	if (vxfs_read_olt(sbp, bsize)) {
		warnf(fc, "vxfs: unable to read olt");
		goto out;
	}

	if (vxfs_read_fshead(sbp)) {
		warnf(fc, "vxfs: unable to read fshead");
		goto out;
	}

	root = vxfs_iget(sbp, VXFS_ROOT_INO);
	if (IS_ERR(root)) {
		ret = PTR_ERR(root);
		goto out;
	}
	sbp->s_root = d_make_root(root);
	if (!sbp->s_root) {
		warnf(fc, "vxfs: unable to get root dentry.");
		goto out_free_ilist;
	}

	return 0;
	
out_free_ilist:
	iput(infp->vsi_fship);
	iput(infp->vsi_ilist);
	iput(infp->vsi_stilist);
out:
	brelse(infp->vsi_bp);
	kfree(infp);
	return ret;
}

/*
 * The usual module blurb.
 */
static int vxfs_get_tree(struct fs_context *fc)
{
	return get_tree_bdev(fc, vxfs_fill_super);
}

static const struct fs_context_operations vxfs_context_ops = {
	.get_tree	= vxfs_get_tree,
	.reconfigure	= vxfs_reconfigure,
};

static int vxfs_init_fs_context(struct fs_context *fc)
{
	fc->ops = &vxfs_context_ops;

	return 0;
}

static struct file_system_type vxfs_fs_type = {
	.owner		= THIS_MODULE,
	.name		= "vxfs",
	.kill_sb	= kill_block_super,
	.fs_flags	= FS_REQUIRES_DEV,
	.init_fs_context = vxfs_init_fs_context,
};
MODULE_ALIAS_FS("vxfs"); /* makes mount -t vxfs autoload the module */
MODULE_ALIAS("vxfs");

static int __init
vxfs_init(void)
{
	int rv;

	vxfs_inode_cachep = kmem_cache_create_usercopy("vxfs_inode",
			sizeof(struct vxfs_inode_info), 0,
			SLAB_RECLAIM_ACCOUNT,
			offsetof(struct vxfs_inode_info, vii_immed.vi_immed),
			sizeof_field(struct vxfs_inode_info,
				vii_immed.vi_immed),
			NULL);
	if (!vxfs_inode_cachep)
		return -ENOMEM;
	rv = register_filesystem(&vxfs_fs_type);
	if (rv < 0)
		kmem_cache_destroy(vxfs_inode_cachep);
	return rv;
}

static void __exit
vxfs_cleanup(void)
{
	unregister_filesystem(&vxfs_fs_type);
	/*
	 * Make sure all delayed rcu free inodes are flushed before we
	 * destroy cache.
	 */
	rcu_barrier();
	kmem_cache_destroy(vxfs_inode_cachep);
}

module_init(vxfs_init);
module_exit(vxfs_cleanup);
