18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright (c) 2000-2001 Christoph Hellwig.
38c2ecf20Sopenharmony_ci * Copyright (c) 2016 Krzysztof Blaszkowski
48c2ecf20Sopenharmony_ci * All rights reserved.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without
78c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions
88c2ecf20Sopenharmony_ci * are met:
98c2ecf20Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright
108c2ecf20Sopenharmony_ci *    notice, this list of conditions, and the following disclaimer,
118c2ecf20Sopenharmony_ci *    without modification.
128c2ecf20Sopenharmony_ci * 2. The name of the author may not be used to endorse or promote products
138c2ecf20Sopenharmony_ci *    derived from this software without specific prior written permission.
148c2ecf20Sopenharmony_ci *
158c2ecf20Sopenharmony_ci * Alternatively, this software may be distributed under the terms of the
168c2ecf20Sopenharmony_ci * GNU General Public License ("GPL").
178c2ecf20Sopenharmony_ci *
188c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
198c2ecf20Sopenharmony_ci * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
208c2ecf20Sopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
218c2ecf20Sopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
228c2ecf20Sopenharmony_ci * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
238c2ecf20Sopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
248c2ecf20Sopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
258c2ecf20Sopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
268c2ecf20Sopenharmony_ci * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
278c2ecf20Sopenharmony_ci * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
288c2ecf20Sopenharmony_ci * SUCH DAMAGE.
298c2ecf20Sopenharmony_ci */
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci/*
328c2ecf20Sopenharmony_ci * Veritas filesystem driver - superblock related routines.
338c2ecf20Sopenharmony_ci */
348c2ecf20Sopenharmony_ci#include <linux/init.h>
358c2ecf20Sopenharmony_ci#include <linux/module.h>
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#include <linux/blkdev.h>
388c2ecf20Sopenharmony_ci#include <linux/fs.h>
398c2ecf20Sopenharmony_ci#include <linux/buffer_head.h>
408c2ecf20Sopenharmony_ci#include <linux/kernel.h>
418c2ecf20Sopenharmony_ci#include <linux/slab.h>
428c2ecf20Sopenharmony_ci#include <linux/stat.h>
438c2ecf20Sopenharmony_ci#include <linux/vfs.h>
448c2ecf20Sopenharmony_ci#include <linux/mount.h>
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci#include "vxfs.h"
478c2ecf20Sopenharmony_ci#include "vxfs_extern.h"
488c2ecf20Sopenharmony_ci#include "vxfs_dir.h"
498c2ecf20Sopenharmony_ci#include "vxfs_inode.h"
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ciMODULE_AUTHOR("Christoph Hellwig, Krzysztof Blaszkowski");
538c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver");
548c2ecf20Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL");
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_cistatic struct kmem_cache *vxfs_inode_cachep;
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci/**
598c2ecf20Sopenharmony_ci * vxfs_put_super - free superblock resources
608c2ecf20Sopenharmony_ci * @sbp:	VFS superblock.
618c2ecf20Sopenharmony_ci *
628c2ecf20Sopenharmony_ci * Description:
638c2ecf20Sopenharmony_ci *   vxfs_put_super frees all resources allocated for @sbp
648c2ecf20Sopenharmony_ci *   after the last instance of the filesystem is unmounted.
658c2ecf20Sopenharmony_ci */
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_cistatic void
688c2ecf20Sopenharmony_civxfs_put_super(struct super_block *sbp)
698c2ecf20Sopenharmony_ci{
708c2ecf20Sopenharmony_ci	struct vxfs_sb_info	*infp = VXFS_SBI(sbp);
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	iput(infp->vsi_fship);
738c2ecf20Sopenharmony_ci	iput(infp->vsi_ilist);
748c2ecf20Sopenharmony_ci	iput(infp->vsi_stilist);
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	brelse(infp->vsi_bp);
778c2ecf20Sopenharmony_ci	kfree(infp);
788c2ecf20Sopenharmony_ci}
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci/**
818c2ecf20Sopenharmony_ci * vxfs_statfs - get filesystem information
828c2ecf20Sopenharmony_ci * @dentry:	VFS dentry to locate superblock
838c2ecf20Sopenharmony_ci * @bufp:	output buffer
848c2ecf20Sopenharmony_ci *
858c2ecf20Sopenharmony_ci * Description:
868c2ecf20Sopenharmony_ci *   vxfs_statfs fills the statfs buffer @bufp with information
878c2ecf20Sopenharmony_ci *   about the filesystem described by @dentry.
888c2ecf20Sopenharmony_ci *
898c2ecf20Sopenharmony_ci * Returns:
908c2ecf20Sopenharmony_ci *   Zero.
918c2ecf20Sopenharmony_ci *
928c2ecf20Sopenharmony_ci * Locking:
938c2ecf20Sopenharmony_ci *   No locks held.
948c2ecf20Sopenharmony_ci *
958c2ecf20Sopenharmony_ci * Notes:
968c2ecf20Sopenharmony_ci *   This is everything but complete...
978c2ecf20Sopenharmony_ci */
988c2ecf20Sopenharmony_cistatic int
998c2ecf20Sopenharmony_civxfs_statfs(struct dentry *dentry, struct kstatfs *bufp)
1008c2ecf20Sopenharmony_ci{
1018c2ecf20Sopenharmony_ci	struct vxfs_sb_info		*infp = VXFS_SBI(dentry->d_sb);
1028c2ecf20Sopenharmony_ci	struct vxfs_sb *raw_sb = infp->vsi_raw;
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci	bufp->f_type = VXFS_SUPER_MAGIC;
1058c2ecf20Sopenharmony_ci	bufp->f_bsize = dentry->d_sb->s_blocksize;
1068c2ecf20Sopenharmony_ci	bufp->f_blocks = fs32_to_cpu(infp, raw_sb->vs_dsize);
1078c2ecf20Sopenharmony_ci	bufp->f_bfree = fs32_to_cpu(infp, raw_sb->vs_free);
1088c2ecf20Sopenharmony_ci	bufp->f_bavail = 0;
1098c2ecf20Sopenharmony_ci	bufp->f_files = 0;
1108c2ecf20Sopenharmony_ci	bufp->f_ffree = fs32_to_cpu(infp, raw_sb->vs_ifree);
1118c2ecf20Sopenharmony_ci	bufp->f_namelen = VXFS_NAMELEN;
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci	return 0;
1148c2ecf20Sopenharmony_ci}
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_cistatic int vxfs_remount(struct super_block *sb, int *flags, char *data)
1178c2ecf20Sopenharmony_ci{
1188c2ecf20Sopenharmony_ci	sync_filesystem(sb);
1198c2ecf20Sopenharmony_ci	*flags |= SB_RDONLY;
1208c2ecf20Sopenharmony_ci	return 0;
1218c2ecf20Sopenharmony_ci}
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_cistatic struct inode *vxfs_alloc_inode(struct super_block *sb)
1248c2ecf20Sopenharmony_ci{
1258c2ecf20Sopenharmony_ci	struct vxfs_inode_info *vi;
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	vi = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL);
1288c2ecf20Sopenharmony_ci	if (!vi)
1298c2ecf20Sopenharmony_ci		return NULL;
1308c2ecf20Sopenharmony_ci	inode_init_once(&vi->vfs_inode);
1318c2ecf20Sopenharmony_ci	return &vi->vfs_inode;
1328c2ecf20Sopenharmony_ci}
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_cistatic void vxfs_free_inode(struct inode *inode)
1358c2ecf20Sopenharmony_ci{
1368c2ecf20Sopenharmony_ci	kmem_cache_free(vxfs_inode_cachep, VXFS_INO(inode));
1378c2ecf20Sopenharmony_ci}
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_cistatic const struct super_operations vxfs_super_ops = {
1408c2ecf20Sopenharmony_ci	.alloc_inode		= vxfs_alloc_inode,
1418c2ecf20Sopenharmony_ci	.free_inode		= vxfs_free_inode,
1428c2ecf20Sopenharmony_ci	.evict_inode		= vxfs_evict_inode,
1438c2ecf20Sopenharmony_ci	.put_super		= vxfs_put_super,
1448c2ecf20Sopenharmony_ci	.statfs			= vxfs_statfs,
1458c2ecf20Sopenharmony_ci	.remount_fs		= vxfs_remount,
1468c2ecf20Sopenharmony_ci};
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_cistatic int vxfs_try_sb_magic(struct super_block *sbp, int silent,
1498c2ecf20Sopenharmony_ci		unsigned blk, __fs32 magic)
1508c2ecf20Sopenharmony_ci{
1518c2ecf20Sopenharmony_ci	struct buffer_head *bp;
1528c2ecf20Sopenharmony_ci	struct vxfs_sb *rsbp;
1538c2ecf20Sopenharmony_ci	struct vxfs_sb_info *infp = VXFS_SBI(sbp);
1548c2ecf20Sopenharmony_ci	int rc = -ENOMEM;
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci	bp = sb_bread(sbp, blk);
1578c2ecf20Sopenharmony_ci	do {
1588c2ecf20Sopenharmony_ci		if (!bp || !buffer_mapped(bp)) {
1598c2ecf20Sopenharmony_ci			if (!silent) {
1608c2ecf20Sopenharmony_ci				printk(KERN_WARNING
1618c2ecf20Sopenharmony_ci					"vxfs: unable to read disk superblock at %u\n",
1628c2ecf20Sopenharmony_ci					blk);
1638c2ecf20Sopenharmony_ci			}
1648c2ecf20Sopenharmony_ci			break;
1658c2ecf20Sopenharmony_ci		}
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci		rc = -EINVAL;
1688c2ecf20Sopenharmony_ci		rsbp = (struct vxfs_sb *)bp->b_data;
1698c2ecf20Sopenharmony_ci		if (rsbp->vs_magic != magic) {
1708c2ecf20Sopenharmony_ci			if (!silent)
1718c2ecf20Sopenharmony_ci				printk(KERN_NOTICE
1728c2ecf20Sopenharmony_ci					"vxfs: WRONG superblock magic %08x at %u\n",
1738c2ecf20Sopenharmony_ci					rsbp->vs_magic, blk);
1748c2ecf20Sopenharmony_ci			break;
1758c2ecf20Sopenharmony_ci		}
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci		rc = 0;
1788c2ecf20Sopenharmony_ci		infp->vsi_raw = rsbp;
1798c2ecf20Sopenharmony_ci		infp->vsi_bp = bp;
1808c2ecf20Sopenharmony_ci	} while (0);
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	if (rc) {
1838c2ecf20Sopenharmony_ci		infp->vsi_raw = NULL;
1848c2ecf20Sopenharmony_ci		infp->vsi_bp = NULL;
1858c2ecf20Sopenharmony_ci		brelse(bp);
1868c2ecf20Sopenharmony_ci	}
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci	return rc;
1898c2ecf20Sopenharmony_ci}
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci/**
1928c2ecf20Sopenharmony_ci * vxfs_read_super - read superblock into memory and initialize filesystem
1938c2ecf20Sopenharmony_ci * @sbp:		VFS superblock (to fill)
1948c2ecf20Sopenharmony_ci * @dp:			fs private mount data
1958c2ecf20Sopenharmony_ci * @silent:		do not complain loudly when sth is wrong
1968c2ecf20Sopenharmony_ci *
1978c2ecf20Sopenharmony_ci * Description:
1988c2ecf20Sopenharmony_ci *   We are called on the first mount of a filesystem to read the
1998c2ecf20Sopenharmony_ci *   superblock into memory and do some basic setup.
2008c2ecf20Sopenharmony_ci *
2018c2ecf20Sopenharmony_ci * Returns:
2028c2ecf20Sopenharmony_ci *   The superblock on success, else %NULL.
2038c2ecf20Sopenharmony_ci *
2048c2ecf20Sopenharmony_ci * Locking:
2058c2ecf20Sopenharmony_ci *   We are under @sbp->s_lock.
2068c2ecf20Sopenharmony_ci */
2078c2ecf20Sopenharmony_cistatic int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
2088c2ecf20Sopenharmony_ci{
2098c2ecf20Sopenharmony_ci	struct vxfs_sb_info	*infp;
2108c2ecf20Sopenharmony_ci	struct vxfs_sb		*rsbp;
2118c2ecf20Sopenharmony_ci	u_long			bsize;
2128c2ecf20Sopenharmony_ci	struct inode *root;
2138c2ecf20Sopenharmony_ci	int ret = -EINVAL;
2148c2ecf20Sopenharmony_ci	u32 j;
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_ci	sbp->s_flags |= SB_RDONLY;
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci	infp = kzalloc(sizeof(*infp), GFP_KERNEL);
2198c2ecf20Sopenharmony_ci	if (!infp) {
2208c2ecf20Sopenharmony_ci		printk(KERN_WARNING "vxfs: unable to allocate incore superblock\n");
2218c2ecf20Sopenharmony_ci		return -ENOMEM;
2228c2ecf20Sopenharmony_ci	}
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci	bsize = sb_min_blocksize(sbp, BLOCK_SIZE);
2258c2ecf20Sopenharmony_ci	if (!bsize) {
2268c2ecf20Sopenharmony_ci		printk(KERN_WARNING "vxfs: unable to set blocksize\n");
2278c2ecf20Sopenharmony_ci		goto out;
2288c2ecf20Sopenharmony_ci	}
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci	sbp->s_op = &vxfs_super_ops;
2318c2ecf20Sopenharmony_ci	sbp->s_fs_info = infp;
2328c2ecf20Sopenharmony_ci	sbp->s_time_min = 0;
2338c2ecf20Sopenharmony_ci	sbp->s_time_max = U32_MAX;
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ci	if (!vxfs_try_sb_magic(sbp, silent, 1,
2368c2ecf20Sopenharmony_ci			(__force __fs32)cpu_to_le32(VXFS_SUPER_MAGIC))) {
2378c2ecf20Sopenharmony_ci		/* Unixware, x86 */
2388c2ecf20Sopenharmony_ci		infp->byte_order = VXFS_BO_LE;
2398c2ecf20Sopenharmony_ci	} else if (!vxfs_try_sb_magic(sbp, silent, 8,
2408c2ecf20Sopenharmony_ci			(__force __fs32)cpu_to_be32(VXFS_SUPER_MAGIC))) {
2418c2ecf20Sopenharmony_ci		/* HP-UX, parisc */
2428c2ecf20Sopenharmony_ci		infp->byte_order = VXFS_BO_BE;
2438c2ecf20Sopenharmony_ci	} else {
2448c2ecf20Sopenharmony_ci		if (!silent)
2458c2ecf20Sopenharmony_ci			printk(KERN_NOTICE "vxfs: can't find superblock.\n");
2468c2ecf20Sopenharmony_ci		goto out;
2478c2ecf20Sopenharmony_ci	}
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci	rsbp = infp->vsi_raw;
2508c2ecf20Sopenharmony_ci	j = fs32_to_cpu(infp, rsbp->vs_version);
2518c2ecf20Sopenharmony_ci	if ((j < 2 || j > 4) && !silent) {
2528c2ecf20Sopenharmony_ci		printk(KERN_NOTICE "vxfs: unsupported VxFS version (%d)\n", j);
2538c2ecf20Sopenharmony_ci		goto out;
2548c2ecf20Sopenharmony_ci	}
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci#ifdef DIAGNOSTIC
2578c2ecf20Sopenharmony_ci	printk(KERN_DEBUG "vxfs: supported VxFS version (%d)\n", j);
2588c2ecf20Sopenharmony_ci	printk(KERN_DEBUG "vxfs: blocksize: %d\n",
2598c2ecf20Sopenharmony_ci		fs32_to_cpu(infp, rsbp->vs_bsize));
2608c2ecf20Sopenharmony_ci#endif
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci	sbp->s_magic = fs32_to_cpu(infp, rsbp->vs_magic);
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci	infp->vsi_oltext = fs32_to_cpu(infp, rsbp->vs_oltext[0]);
2658c2ecf20Sopenharmony_ci	infp->vsi_oltsize = fs32_to_cpu(infp, rsbp->vs_oltsize);
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ci	j = fs32_to_cpu(infp, rsbp->vs_bsize);
2688c2ecf20Sopenharmony_ci	if (!sb_set_blocksize(sbp, j)) {
2698c2ecf20Sopenharmony_ci		printk(KERN_WARNING "vxfs: unable to set final block size\n");
2708c2ecf20Sopenharmony_ci		goto out;
2718c2ecf20Sopenharmony_ci	}
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci	if (vxfs_read_olt(sbp, bsize)) {
2748c2ecf20Sopenharmony_ci		printk(KERN_WARNING "vxfs: unable to read olt\n");
2758c2ecf20Sopenharmony_ci		goto out;
2768c2ecf20Sopenharmony_ci	}
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_ci	if (vxfs_read_fshead(sbp)) {
2798c2ecf20Sopenharmony_ci		printk(KERN_WARNING "vxfs: unable to read fshead\n");
2808c2ecf20Sopenharmony_ci		goto out;
2818c2ecf20Sopenharmony_ci	}
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci	root = vxfs_iget(sbp, VXFS_ROOT_INO);
2848c2ecf20Sopenharmony_ci	if (IS_ERR(root)) {
2858c2ecf20Sopenharmony_ci		ret = PTR_ERR(root);
2868c2ecf20Sopenharmony_ci		goto out;
2878c2ecf20Sopenharmony_ci	}
2888c2ecf20Sopenharmony_ci	sbp->s_root = d_make_root(root);
2898c2ecf20Sopenharmony_ci	if (!sbp->s_root) {
2908c2ecf20Sopenharmony_ci		printk(KERN_WARNING "vxfs: unable to get root dentry.\n");
2918c2ecf20Sopenharmony_ci		goto out_free_ilist;
2928c2ecf20Sopenharmony_ci	}
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci	return 0;
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ciout_free_ilist:
2978c2ecf20Sopenharmony_ci	iput(infp->vsi_fship);
2988c2ecf20Sopenharmony_ci	iput(infp->vsi_ilist);
2998c2ecf20Sopenharmony_ci	iput(infp->vsi_stilist);
3008c2ecf20Sopenharmony_ciout:
3018c2ecf20Sopenharmony_ci	brelse(infp->vsi_bp);
3028c2ecf20Sopenharmony_ci	kfree(infp);
3038c2ecf20Sopenharmony_ci	return ret;
3048c2ecf20Sopenharmony_ci}
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci/*
3078c2ecf20Sopenharmony_ci * The usual module blurb.
3088c2ecf20Sopenharmony_ci */
3098c2ecf20Sopenharmony_cistatic struct dentry *vxfs_mount(struct file_system_type *fs_type,
3108c2ecf20Sopenharmony_ci	int flags, const char *dev_name, void *data)
3118c2ecf20Sopenharmony_ci{
3128c2ecf20Sopenharmony_ci	return mount_bdev(fs_type, flags, dev_name, data, vxfs_fill_super);
3138c2ecf20Sopenharmony_ci}
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_cistatic struct file_system_type vxfs_fs_type = {
3168c2ecf20Sopenharmony_ci	.owner		= THIS_MODULE,
3178c2ecf20Sopenharmony_ci	.name		= "vxfs",
3188c2ecf20Sopenharmony_ci	.mount		= vxfs_mount,
3198c2ecf20Sopenharmony_ci	.kill_sb	= kill_block_super,
3208c2ecf20Sopenharmony_ci	.fs_flags	= FS_REQUIRES_DEV,
3218c2ecf20Sopenharmony_ci};
3228c2ecf20Sopenharmony_ciMODULE_ALIAS_FS("vxfs"); /* makes mount -t vxfs autoload the module */
3238c2ecf20Sopenharmony_ciMODULE_ALIAS("vxfs");
3248c2ecf20Sopenharmony_ci
3258c2ecf20Sopenharmony_cistatic int __init
3268c2ecf20Sopenharmony_civxfs_init(void)
3278c2ecf20Sopenharmony_ci{
3288c2ecf20Sopenharmony_ci	int rv;
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci	vxfs_inode_cachep = kmem_cache_create_usercopy("vxfs_inode",
3318c2ecf20Sopenharmony_ci			sizeof(struct vxfs_inode_info), 0,
3328c2ecf20Sopenharmony_ci			SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD,
3338c2ecf20Sopenharmony_ci			offsetof(struct vxfs_inode_info, vii_immed.vi_immed),
3348c2ecf20Sopenharmony_ci			sizeof_field(struct vxfs_inode_info,
3358c2ecf20Sopenharmony_ci				vii_immed.vi_immed),
3368c2ecf20Sopenharmony_ci			NULL);
3378c2ecf20Sopenharmony_ci	if (!vxfs_inode_cachep)
3388c2ecf20Sopenharmony_ci		return -ENOMEM;
3398c2ecf20Sopenharmony_ci	rv = register_filesystem(&vxfs_fs_type);
3408c2ecf20Sopenharmony_ci	if (rv < 0)
3418c2ecf20Sopenharmony_ci		kmem_cache_destroy(vxfs_inode_cachep);
3428c2ecf20Sopenharmony_ci	return rv;
3438c2ecf20Sopenharmony_ci}
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_cistatic void __exit
3468c2ecf20Sopenharmony_civxfs_cleanup(void)
3478c2ecf20Sopenharmony_ci{
3488c2ecf20Sopenharmony_ci	unregister_filesystem(&vxfs_fs_type);
3498c2ecf20Sopenharmony_ci	/*
3508c2ecf20Sopenharmony_ci	 * Make sure all delayed rcu free inodes are flushed before we
3518c2ecf20Sopenharmony_ci	 * destroy cache.
3528c2ecf20Sopenharmony_ci	 */
3538c2ecf20Sopenharmony_ci	rcu_barrier();
3548c2ecf20Sopenharmony_ci	kmem_cache_destroy(vxfs_inode_cachep);
3558c2ecf20Sopenharmony_ci}
3568c2ecf20Sopenharmony_ci
3578c2ecf20Sopenharmony_cimodule_init(vxfs_init);
3588c2ecf20Sopenharmony_cimodule_exit(vxfs_cleanup);
359